From cd17687f01420952712a500107e0f93e7ab8d5f8 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Fri, 15 Aug 2008 23:45:34 -0500 Subject: Second Life viewer sources 1.19.1.0 --- linden/doc/contributions.txt | 13 + linden/etc/message.xml | 21 +- linden/indra/SConstruct | 38 +- linden/indra/indra_complete/indra_complete.sln | 2 + linden/indra/indra_complete/indra_complete_vc8.sln | 3 - linden/indra/lib/python/indra/base/config.py | 25 + linden/indra/lib/python/indra/base/lllog.py | 72 + linden/indra/lib/python/indra/base/lluuid.py | 21 +- linden/indra/lib/python/indra/base/metrics.py | 23 +- linden/indra/lib/python/indra/ipc/mysql_pool.py | 5 +- linden/indra/lib/python/indra/ipc/russ.py | 10 +- linden/indra/lib/python/indra/util/llsubprocess.py | 106 + linden/indra/lib/python/indra/util/named_query.py | 48 +- linden/indra/lib/python/indra/util/shutil2.py | 84 + linden/indra/llaudio/llaudio_vc8.vcproj | 646 +- linden/indra/llaudio/llaudio_vc9.vcproj | 648 +- linden/indra/llcharacter/llcharacter.cpp | 26 +- linden/indra/llcharacter/llcharacter.h | 5 +- linden/indra/llcharacter/llcharacter_vc8.vcproj | 838 +- linden/indra/llcharacter/llcharacter_vc9.vcproj | 840 +- linden/indra/llcharacter/llkeyframemotion.cpp | 295 +- linden/indra/llcharacter/llkeyframemotion.h | 11 +- linden/indra/llcharacter/llkeyframemotionparam.cpp | 149 +- linden/indra/llcharacter/llkeyframemotionparam.h | 16 +- linden/indra/llcharacter/llmotioncontroller.cpp | 9 +- linden/indra/llcharacter/llmotioncontroller.h | 2 + linden/indra/llcharacter/llpose.cpp | 23 +- linden/indra/llcharacter/llpose.h | 2 - linden/indra/llcharacter/llstatemachine.h | 1 - linden/indra/llcommon/indra_constants.h | 4 + linden/indra/llcommon/linden_common.h | 7 + linden/indra/llcommon/llapp.cpp | 11 +- linden/indra/llcommon/llapr.cpp | 8 +- linden/indra/llcommon/llclickaction.h | 2 + linden/indra/llcommon/llcommon_vc8.vcproj | 1618 ++-- linden/indra/llcommon/llcommon_vc9.vcproj | 1616 ++-- linden/indra/llcommon/llfasttimer.h | 7 +- linden/indra/llcommon/llfile.cpp | 28 + linden/indra/llcommon/llfile.h | 9 + linden/indra/llcommon/llkeythrottle.h | 5 +- linden/indra/llcommon/lllog.cpp | 3 +- linden/indra/llcommon/llmemory.h | 50 +- linden/indra/llcommon/llpreprocessor.h | 27 - linden/indra/llcommon/llsdserialize.cpp | 763 +- linden/indra/llcommon/llsdserialize.h | 232 +- linden/indra/llcommon/llsdserialize_xml.cpp | 23 +- linden/indra/llcommon/llstreamtools.cpp | 27 +- linden/indra/llcommon/llstreamtools.h | 7 +- linden/indra/llcommon/llsys.cpp | 3 +- linden/indra/llcommon/llthread.cpp | 7 + linden/indra/llcommon/llthread.h | 10 +- linden/indra/llcommon/llversionserver.h | 6 +- linden/indra/llcommon/llversionviewer.h | 4 +- linden/indra/llcrashlogger/llcrashlogger.cpp | 10 +- linden/indra/llimage/llimage.vcproj | 6 +- linden/indra/llimage/llimage_vc8.vcproj | 650 +- linden/indra/llimage/llimage_vc9.vcproj | 652 +- linden/indra/llinventory/llinventory.cpp | 70 +- linden/indra/llinventory/llinventory.h | 4 +- linden/indra/llinventory/llinventory_vc8.vcproj | 694 +- linden/indra/llinventory/llinventory_vc9.vcproj | 696 +- linden/indra/llinventory/llparcel.cpp | 1409 +-- linden/indra/llinventory/llparcel.h | 22 + linden/indra/llinventory/llpermissions.cpp | 33 + linden/indra/llinventory/llpermissions.h | 3 + linden/indra/llinventory/llsaleinfo.cpp | 21 + linden/indra/llinventory/llsaleinfo.h | 3 + linden/indra/llmath/llcamera.cpp | 127 +- linden/indra/llmath/llcamera.h | 22 +- linden/indra/llmath/llcoordframe.cpp | 6 +- linden/indra/llmath/llmath.h | 16 + linden/indra/llmath/llmath_vc8.vcproj | 944 +-- linden/indra/llmath/llmath_vc9.vcproj | 946 +-- linden/indra/llmath/lloctree.h | 382 +- linden/indra/llmath/llrect.h | 32 +- linden/indra/llmath/lltreenode.h | 89 +- linden/indra/llmath/llvolume.cpp | 546 +- linden/indra/llmath/llvolume.h | 18 +- linden/indra/llmath/llvolumemgr.cpp | 23 + linden/indra/llmath/llvolumemgr.h | 1 + linden/indra/llmath/v3color.cpp | 8 + linden/indra/llmath/v3color.h | 10 +- linden/indra/llmath/v4color.cpp | 10 +- linden/indra/llmath/v4color.h | 4 +- linden/indra/llmath/v4math.h | 3 +- linden/indra/llmedia/files.lst | 10 +- linden/indra/llmedia/llmedia.vcproj | 73 +- linden/indra/llmedia/llmedia_vc8.vcproj | 60 +- linden/indra/llmedia/llmedia_vc9.vcproj | 626 +- linden/indra/llmedia/llmediabase.cpp | 210 - linden/indra/llmedia/llmediabase.h | 313 +- linden/indra/llmedia/llmediaemitter.h | 80 +- linden/indra/llmedia/llmediaemitterevents.h | 61 - linden/indra/llmedia/llmediaengine.cpp | 635 -- linden/indra/llmedia/llmediaengine.h | 150 - linden/indra/llmedia/llmediaimplcommon.cpp | 540 ++ linden/indra/llmedia/llmediaimplcommon.h | 161 + linden/indra/llmedia/llmediaimplexample1.cpp | 228 + linden/indra/llmedia/llmediaimplexample1.h | 72 + linden/indra/llmedia/llmediaimplexample2.cpp | 195 + linden/indra/llmedia/llmediaimplexample2.h | 75 + linden/indra/llmedia/llmediaimplfactory.cpp | 104 + linden/indra/llmedia/llmediaimplfactory.h | 99 + linden/indra/llmedia/llmediaimplgstreamer.cpp | 652 +- linden/indra/llmedia/llmediaimplgstreamer.h | 105 +- linden/indra/llmedia/llmediaimplgstreamer_syms.cpp | 20 +- .../indra/llmedia/llmediaimplgstreamervidplug.cpp | 4 +- linden/indra/llmedia/llmediaimplgstreamervidplug.h | 4 +- linden/indra/llmedia/llmediaimplllmozlib.cpp | 590 ++ linden/indra/llmedia/llmediaimplllmozlib.h | 120 + linden/indra/llmedia/llmediaimplquicktime.cpp | 1191 +-- linden/indra/llmedia/llmediaimplquicktime.h | 166 +- linden/indra/llmedia/llmediaimplregister.h | 59 + linden/indra/llmedia/llmediamanager.cpp | 255 + linden/indra/llmedia/llmediamanager.h | 120 + linden/indra/llmedia/llmediamoviebase.cpp | 234 - linden/indra/llmedia/llmediamoviebase.h | 84 - linden/indra/llmedia/llmediaobserver.h | 103 + linden/indra/llmedia/llmediaobservers.h | 54 - linden/indra/llmessage/llassetstorage.cpp | 59 + linden/indra/llmessage/llassetstorage.h | 26 + linden/indra/llmessage/llbuffer.h | 12 + linden/indra/llmessage/llcachename.cpp | 194 +- linden/indra/llmessage/llcachename.h | 11 +- linden/indra/llmessage/llcallbacklisth.h | 103 - linden/indra/llmessage/llcircuit.h | 1 - linden/indra/llmessage/llcurl.cpp | 962 ++- linden/indra/llmessage/llcurl.h | 205 +- linden/indra/llmessage/llfiltersd2xmlrpc.cpp | 4 +- linden/indra/llmessage/llhost.cpp | 12 +- linden/indra/llmessage/llhost.h | 4 +- linden/indra/llmessage/llhttpassetstorage.cpp | 76 +- linden/indra/llmessage/llhttpclient.cpp | 157 +- linden/indra/llmessage/llhttpclient.h | 71 +- linden/indra/llmessage/llhttpnode.h | 2 +- linden/indra/llmessage/lliohttpserver.cpp | 6 +- linden/indra/llmessage/llmessage.vcproj | 3 - linden/indra/llmessage/llmessage_vc8.vcproj | 1846 ++-- linden/indra/llmessage/llmessage_vc9.vcproj | 1848 ++-- linden/indra/llmessage/llnamevalue.h | 1 - linden/indra/llmessage/llpacketring.h | 1 - linden/indra/llmessage/llsdrpcclient.cpp | 2 +- linden/indra/llmessage/llsdrpcserver.cpp | 5 +- linden/indra/llmessage/llservicebuilder.cpp | 58 +- linden/indra/llmessage/llurlrequest.cpp | 209 +- linden/indra/llmessage/llurlrequest.h | 26 +- linden/indra/llmessage/llxfermanager.cpp | 46 +- linden/indra/llmessage/llxfermanager.h | 4 +- linden/indra/llmessage/message.h | 2 - linden/indra/llprimitive/llmaterialtable.cpp | 104 +- linden/indra/llprimitive/llmaterialtable.h | 4 +- linden/indra/llprimitive/llprimitive_vc8.vcproj | 638 +- linden/indra/llprimitive/llprimitive_vc9.vcproj | 640 +- linden/indra/llprimitive/lltextureentry.cpp | 1 - linden/indra/llrender/files.lst | 2 + linden/indra/llrender/llfontgl.cpp | 73 +- linden/indra/llrender/llglimmediate.cpp | 354 + linden/indra/llrender/llglimmediate.h | 104 + linden/indra/llrender/llimagegl.cpp | 18 +- linden/indra/llrender/llimagegl.h | 3 +- linden/indra/llrender/llrender.vcproj | 12 + linden/indra/llrender/llrender_vc8.vcproj | 642 +- linden/indra/llrender/llrender_vc9.vcproj | 644 +- linden/indra/llrender/llrendertarget.cpp | 185 + linden/indra/llrender/llrendertarget.h | 116 + linden/indra/llrender/llvertexbuffer.cpp | 538 +- linden/indra/llrender/llvertexbuffer.h | 67 +- linden/indra/llui/files.lst | 4 + linden/indra/llui/llalertdialog.cpp | 16 +- linden/indra/llui/llalertdialog.h | 59 +- linden/indra/llui/llbutton.cpp | 65 +- linden/indra/llui/llbutton.h | 39 +- linden/indra/llui/llcheckboxctrl.cpp | 13 +- linden/indra/llui/llclipboard.cpp | 4 +- linden/indra/llui/llclipboard.h | 18 +- linden/indra/llui/llcombobox.cpp | 71 +- linden/indra/llui/llcombobox.h | 16 +- linden/indra/llui/llctrlselectioninterface.h | 12 +- linden/indra/llui/lldraghandle.cpp | 91 +- linden/indra/llui/lldraghandle.h | 7 + linden/indra/llui/lleditmenuhandler.cpp | 96 +- linden/indra/llui/lleditmenuhandler.h | 46 +- linden/indra/llui/llfloater.cpp | 488 +- linden/indra/llui/llfloater.h | 172 +- linden/indra/llui/llfocusmgr.cpp | 34 +- linden/indra/llui/llfocusmgr.h | 33 +- linden/indra/llui/lliconctrl.cpp | 4 +- linden/indra/llui/lliconctrl.h | 2 +- linden/indra/llui/llkeywords.cpp | 2 +- linden/indra/llui/llkeywords.h | 34 +- linden/indra/llui/lllineeditor.cpp | 214 +- linden/indra/llui/lllineeditor.h | 143 +- linden/indra/llui/llmemberlistener.h | 53 +- linden/indra/llui/llmenugl.cpp | 566 +- linden/indra/llui/llmenugl.h | 268 +- linden/indra/llui/llmodaldialog.cpp | 23 +- linden/indra/llui/llmodaldialog.h | 8 +- linden/indra/llui/llmultislider.cpp | 677 ++ linden/indra/llui/llmultislider.h | 129 + linden/indra/llui/llmultisliderctrl.cpp | 634 ++ linden/indra/llui/llmultisliderctrl.h | 160 + linden/indra/llui/llpanel.cpp | 231 +- linden/indra/llui/llpanel.h | 176 +- linden/indra/llui/llradiogroup.cpp | 28 +- linden/indra/llui/llradiogroup.h | 41 +- linden/indra/llui/llresizebar.cpp | 42 +- linden/indra/llui/llresizebar.h | 11 +- linden/indra/llui/llresizehandle.cpp | 27 +- linden/indra/llui/llresizehandle.h | 9 +- linden/indra/llui/llresmgr.h | 5 +- linden/indra/llui/llrootview.cpp | 12 +- linden/indra/llui/llrootview.h | 4 +- linden/indra/llui/llscrollbar.cpp | 48 +- linden/indra/llui/llscrollbar.h | 26 +- linden/indra/llui/llscrollcontainer.cpp | 68 +- linden/indra/llui/llscrollcontainer.h | 39 +- linden/indra/llui/llscrollingpanellist.cpp | 20 - linden/indra/llui/llscrollingpanellist.h | 28 +- linden/indra/llui/llscrolllistctrl.cpp | 123 +- linden/indra/llui/llscrolllistctrl.h | 127 +- linden/indra/llui/llslider.cpp | 30 +- linden/indra/llui/llslider.h | 19 +- linden/indra/llui/llsliderctrl.cpp | 31 +- linden/indra/llui/llsliderctrl.h | 43 +- linden/indra/llui/llspinctrl.cpp | 25 +- linden/indra/llui/llspinctrl.h | 37 +- linden/indra/llui/llstyle.cpp | 94 +- linden/indra/llui/llstyle.h | 51 +- linden/indra/llui/lltabcontainer.cpp | 2519 +++--- linden/indra/llui/lltabcontainer.h | 263 +- linden/indra/llui/lltabcontainervertical.cpp | 582 +- linden/indra/llui/lltabcontainervertical.h | 67 +- linden/indra/llui/lltextbox.cpp | 124 +- linden/indra/llui/lltextbox.h | 30 +- linden/indra/llui/lltexteditor.cpp | 828 +- linden/indra/llui/lltexteditor.h | 314 +- linden/indra/llui/llui.cpp | 1048 +-- linden/indra/llui/llui.h | 330 +- linden/indra/llui/llui.vcproj | 18 + linden/indra/llui/llui_vc8.vcproj | 1206 +-- linden/indra/llui/llui_vc9.vcproj | 1208 +-- linden/indra/llui/lluictrl.cpp | 203 +- linden/indra/llui/lluictrl.h | 132 +- linden/indra/llui/lluictrlfactory.cpp | 224 +- linden/indra/llui/lluictrlfactory.h | 127 +- linden/indra/llui/lluifwd.h | 63 + linden/indra/llui/lluistring.cpp | 12 +- linden/indra/llui/lluistring.h | 10 +- linden/indra/llui/lluixmltags.h | 179 +- linden/indra/llui/llundo.cpp | 7 +- linden/indra/llui/llundo.h | 48 +- linden/indra/llui/llview.cpp | 1042 +-- linden/indra/llui/llview.h | 486 +- linden/indra/llui/llviewborder.cpp | 96 +- linden/indra/llui/llviewborder.h | 38 +- linden/indra/llui/llviewquery.cpp | 17 +- linden/indra/llui/llviewquery.h | 27 +- linden/indra/llvfs/llvfs_vc8.vcproj | 590 +- linden/indra/llvfs/llvfs_vc9.vcproj | 592 +- linden/indra/llwindow/lldxhardware.cpp | 2 + linden/indra/llwindow/llgl.cpp | 269 +- linden/indra/llwindow/llgl.h | 95 + linden/indra/llwindow/llglheaders.h | 36 + linden/indra/llwindow/llglstates.h | 125 +- linden/indra/llwindow/llglstubs.h | 236 - linden/indra/llwindow/llmousehandler.h | 2 +- linden/indra/llwindow/llwindow.cpp | 14 +- linden/indra/llwindow/llwindow.h | 5 +- linden/indra/llwindow/llwindow.vcproj | 8 +- linden/indra/llwindow/llwindow_vc8.vcproj | 792 +- linden/indra/llwindow/llwindow_vc9.vcproj | 796 +- linden/indra/llwindow/llwindowmacosx.cpp | 38 +- linden/indra/llwindow/llwindowsdl.cpp | 45 +- linden/indra/llwindow/llwindowwin32.cpp | 17 +- linden/indra/llwindow/llwindowwin32.h | 1 + linden/indra/llxml/llcontrol.cpp | 35 +- linden/indra/llxml/llxml_vc8.vcproj | 558 +- linden/indra/llxml/llxml_vc9.vcproj | 560 +- linden/indra/llxml/llxmlnode.cpp | 107 +- linden/indra/lscript/lscript_byteconvert.h | 37 +- linden/indra/lscript/lscript_compile/indra.l | 14 + .../lscript_compile/lscript_compile_fb_vc8.vcproj | 264 +- .../lscript_compile/lscript_compile_fb_vc9.vcproj | 264 +- .../lscript_compile/lscript_compile_ly_vc8.vcproj | 262 +- .../lscript_compile/lscript_compile_vc8.vcproj | 662 +- .../lscript_compile/lscript_compile_vc9.vcproj | 664 +- .../lscript/lscript_execute/lscript_execute.cpp | 28 +- .../lscript_execute/lscript_execute_vc8.vcproj | 558 +- .../lscript_execute/lscript_execute_vc9.vcproj | 560 +- .../lscript/lscript_execute/lscript_readlso.cpp | 184 +- linden/indra/lscript/lscript_library.h | 8 +- .../lscript/lscript_library/lscript_alloc.cpp | 24 +- .../lscript/lscript_library/lscript_library.cpp | 12 +- .../lscript_library/lscript_library_vc8.vcproj | 542 +- .../lscript_library/lscript_library_vc9.vcproj | 544 +- .../indra/newview/English.lproj/InfoPlist.strings | 4 +- linden/indra/newview/Info-SecondLife.plist | 2 +- linden/indra/newview/app_settings/colors_base.xml | 13 +- .../indra/newview/app_settings/high_graphics.xml | 39 + linden/indra/newview/app_settings/keywords.ini | 12 + linden/indra/newview/app_settings/low_graphics.xml | 39 + linden/indra/newview/app_settings/mid_graphics.xml | 39 + .../shaders/class1/avatar/avatarF.glsl | 7 + .../shaders/class1/avatar/avatarSkinV.glsl | 7 +- .../shaders/class1/avatar/avatarV.glsl | 22 +- .../shaders/class1/avatar/eyeballF.glsl | 7 + .../shaders/class1/avatar/eyeballV.glsl | 19 +- .../shaders/class1/avatar/pickAvatarF.glsl | 7 + .../shaders/class1/avatar/pickAvatarV.glsl | 10 +- .../shaders/class1/effects/glowExtractF.glsl | 28 + .../shaders/class1/effects/glowExtractV.glsl | 14 + .../app_settings/shaders/class1/effects/glowF.glsl | 31 + .../app_settings/shaders/class1/effects/glowV.glsl | 22 + .../shaders/class1/environment/glowF.glsl | 14 - .../shaders/class1/environment/glowV.glsl | 10 - .../shaders/class1/environment/groundF.glsl | 5 - .../shaders/class1/environment/groundV.glsl | 6 - .../shaders/class1/environment/scatterF.glsl | 17 - .../shaders/class1/environment/scatterV.glsl | 15 - .../shaders/class1/environment/terrainF.glsl | 16 +- .../shaders/class1/environment/terrainV.glsl | 13 +- .../shaders/class1/environment/terrainWaterF.glsl | 23 + .../shaders/class1/environment/underWaterF.glsl | 45 + .../shaders/class1/environment/waterF.glsl | 96 +- .../shaders/class1/environment/waterFogF.glsl | 20 + .../shaders/class1/environment/waterV.glsl | 90 +- .../shaders/class1/interface/highlightF.glsl | 7 + .../shaders/class1/interface/highlightV.glsl | 15 +- .../shaders/class1/lighting/lightF.glsl | 30 +- .../shaders/class1/lighting/lightFullbrightF.glsl | 15 + .../class1/lighting/lightFullbrightShinyF.glsl | 15 + .../class1/lighting/lightFullbrightWaterF.glsl | 15 + .../class1/lighting/lightFuncSpecularV.glsl | 46 + .../shaders/class1/lighting/lightFuncV.glsl | 34 + .../shaders/class1/lighting/lightShinyF.glsl | 17 + .../shaders/class1/lighting/lightShinyWaterF.glsl | 17 + .../shaders/class1/lighting/lightSpecularV.glsl | 26 + .../shaders/class1/lighting/lightV.glsl | 89 +- .../shaders/class1/lighting/lightWaterF.glsl | 15 + .../class1/lighting/sumLightsSpecularV.glsl | 35 + .../shaders/class1/lighting/sumLightsV.glsl | 29 + .../shaders/class1/objects/alphaF.glsl | 6 - .../shaders/class1/objects/alphaV.glsl | 21 - .../shaders/class1/objects/bumpshinyF.glsl | 18 - .../shaders/class1/objects/bumpshinyV.glsl | 25 - .../shaders/class1/objects/fullbrightF.glsl | 13 + .../shaders/class1/objects/fullbrightShinyF.glsl | 13 + .../shaders/class1/objects/fullbrightShinyV.glsl | 29 + .../shaders/class1/objects/fullbrightV.glsl | 23 + .../shaders/class1/objects/fullbrightWaterF.glsl | 13 + .../shaders/class1/objects/shinyF.glsl | 16 +- .../shaders/class1/objects/shinyV.glsl | 25 +- .../shaders/class1/objects/shinyWaterF.glsl | 13 + .../shaders/class1/objects/simpleF.glsl | 7 + .../shaders/class1/objects/simpleV.glsl | 22 +- .../shaders/class1/objects/simpleWaterF.glsl | 13 + .../shaders/class1/windlight/atmosphericsF.glsl | 13 + .../class1/windlight/atmosphericsHelpersV.glsl | 34 + .../shaders/class1/windlight/atmosphericsV.glsl | 15 + .../class1/windlight/atmosphericsVarsF.glsl | 13 + .../class1/windlight/atmosphericsVarsV.glsl | 19 + .../shaders/class1/windlight/gammaF.glsl | 19 + .../shaders/class1/windlight/transportF.glsl | 26 + .../shaders/class2/avatar/avatarV.glsl | 48 - .../shaders/class2/avatar/eyeballV.glsl | 21 +- .../app_settings/shaders/class2/effects/blurF.glsl | 31 + .../app_settings/shaders/class2/effects/blurV.glsl | 35 + .../shaders/class2/effects/colorFilterF.glsl | 31 + .../shaders/class2/effects/drawQuadV.glsl | 14 + .../shaders/class2/effects/extractF.glsl | 22 + .../shaders/class2/effects/nightVisionF.glsl | 42 + .../shaders/class2/effects/simpleF.glsl | 14 + .../shaders/class2/environment/terrainF.glsl | 38 + .../shaders/class2/environment/terrainV.glsl | 52 + .../shaders/class2/environment/terrainWaterF.glsl | 39 + .../shaders/class2/environment/underWaterF.glsl | 88 + .../shaders/class2/environment/waterF.glsl | 223 +- .../shaders/class2/environment/waterFogF.glsl | 54 + .../shaders/class2/environment/waterV.glsl | 53 - .../shaders/class2/lighting/lightF.glsl | 41 +- .../shaders/class2/lighting/lightFullbrightF.glsl | 23 + .../class2/lighting/lightFullbrightShinyF.glsl | 30 + .../class2/lighting/lightFullbrightWaterF.glsl | 21 + .../shaders/class2/lighting/lightShinyF.glsl | 29 + .../shaders/class2/lighting/lightShinyWaterF.glsl | 27 + .../shaders/class2/lighting/lightSpecularV.glsl | 16 + .../shaders/class2/lighting/lightV.glsl | 128 +- .../shaders/class2/lighting/lightWaterF.glsl | 21 + .../class2/lighting/sumLightsSpecularV.glsl | 41 + .../shaders/class2/lighting/sumLightsV.glsl | 34 + .../shaders/class2/objects/alphaF.glsl | 18 - .../shaders/class2/objects/alphaV.glsl | 24 - .../shaders/class2/objects/bumpshinyF.glsl | 29 - .../shaders/class2/objects/bumpshinyV.glsl | 31 - .../shaders/class2/objects/shinyV.glsl | 31 + .../shaders/class2/windlight/atmosphericsF.glsl | 24 + .../class2/windlight/atmosphericsHelpersV.glsl | 41 + .../shaders/class2/windlight/atmosphericsV.glsl | 137 + .../class2/windlight/atmosphericsVarsF.glsl | 34 + .../class2/windlight/atmosphericsVarsV.glsl | 60 + .../shaders/class2/windlight/cloudsF.glsl | 76 + .../shaders/class2/windlight/cloudsV.glsl | 163 + .../shaders/class2/windlight/gammaF.glsl | 24 + .../shaders/class2/windlight/skyF.glsl | 41 + .../shaders/class2/windlight/skyV.glsl | 138 + .../shaders/class2/windlight/transportF.glsl | 35 + .../shaders/class3/avatar/avatarV.glsl | 112 +- .../shaders/class3/environment/waterF.glsl | 145 - .../class3/lighting/sumLightsSpecularV.glsl | 44 + .../shaders/class3/lighting/sumLightsV.glsl | 41 + .../shaders/class3/objects/bumpshinyF.glsl | 25 - .../app_settings/shaders/shader_heirarchy.txt | 176 + .../indra/newview/app_settings/ultra_graphics.xml | 39 + .../newview/app_settings/windlight/clouds2.tga | Bin 0 -> 262935 bytes .../app_settings/windlight/days/Default.xml | 36 + .../app_settings/windlight/postprocesseffects.xml | 2 + .../app_settings/windlight/skies/A%2D12AM.xml | 141 + .../app_settings/windlight/skies/A%2D12PM.xml | 141 + .../app_settings/windlight/skies/A%2D3AM.xml | 141 + .../app_settings/windlight/skies/A%2D3PM.xml | 141 + .../app_settings/windlight/skies/A%2D6AM.xml | 141 + .../app_settings/windlight/skies/A%2D6PM.xml | 141 + .../app_settings/windlight/skies/A%2D9AM.xml | 141 + .../app_settings/windlight/skies/A%2D9PM.xml | 141 + .../app_settings/windlight/skies/Barcelona.xml | 141 + .../app_settings/windlight/skies/Blizzard.xml | 141 + .../app_settings/windlight/skies/Blue%20Midday.xml | 141 + .../windlight/skies/Coastal%20Afternoon.xml | 141 + .../windlight/skies/Coastal%20Sunset.xml | 141 + .../app_settings/windlight/skies/Default.xml | 141 + .../windlight/skies/Desert%20Sunset.xml | 141 + .../app_settings/windlight/skies/Fine%20Day.xml | 141 + .../windlight/skies/Fluffy%20Big%20Clouds.xml | 141 + .../newview/app_settings/windlight/skies/Foggy.xml | 141 + .../windlight/skies/Funky%20Funky%20Funky.xml | 141 + .../app_settings/windlight/skies/Funky%20Funky.xml | 141 + .../app_settings/windlight/skies/Gelatto.xml | 141 + .../newview/app_settings/windlight/skies/Ghost.xml | 141 + .../windlight/skies/Incongruent%20Truths.xml | 141 + .../app_settings/windlight/skies/Midday%201.xml | 141 + .../app_settings/windlight/skies/Midday%202.xml | 141 + .../app_settings/windlight/skies/Midday%203.xml | 141 + .../app_settings/windlight/skies/Midday%204.xml | 141 + .../newview/app_settings/windlight/skies/Night.xml | 141 + .../app_settings/windlight/skies/Pirate.xml | 141 + .../app_settings/windlight/skies/Purple.xml | 141 + .../windlight/skies/Sailor%27s%20Delight.xml | 141 + .../windlight/skies/Sheer%20Surreality.xml | 141 + .../app_settings/windlight/water/Default.xml | 43 + .../app_settings/windlight/water/Glassy.xml | 43 + .../newview/app_settings/windlight/water/Murky.xml | 43 + .../newview/app_settings/windlight/water/Pond.xml | 43 + .../windlight/water/SNAKE%21%21%21.xml | 43 + .../windlight/water/Second%20Plague.xml | 43 + .../app_settings/windlight/water/Valdez.xml | 43 + linden/indra/newview/featuretable.txt | 496 +- linden/indra/newview/featuretable_linux.txt | 442 +- linden/indra/newview/featuretable_mac.txt | 477 +- linden/indra/newview/featuretable_solaris.txt | 2 +- linden/indra/newview/files.lst | 56 +- linden/indra/newview/gpu_table.txt | 312 +- .../installers/windows/installer_template.nsi | 1894 +++-- linden/indra/newview/licenses-linux.txt | 43 + linden/indra/newview/licenses-mac.txt | 43 + linden/indra/newview/licenses-solaris.txt | 43 + linden/indra/newview/licenses-win32.txt | 45 + linden/indra/newview/linux_tools/launch_url.sh | 14 +- linden/indra/newview/linux_tools/wrapper.sh | 10 +- linden/indra/newview/llagent.cpp | 158 +- linden/indra/newview/llagent.h | 3 +- linden/indra/newview/llanimalcontrols.cpp | 458 - linden/indra/newview/llanimalcontrols.h | 196 - linden/indra/newview/llappearance.h | 12 +- linden/indra/newview/llappviewer.cpp | 299 +- linden/indra/newview/llappviewerwin32.cpp | 30 +- linden/indra/newview/llbox.cpp | 28 +- linden/indra/newview/llcallingcard.cpp | 23 +- linden/indra/newview/llcallingcard.h | 12 +- linden/indra/newview/llcameraview.cpp | 12 +- linden/indra/newview/llcameraview.h | 4 +- linden/indra/newview/llcape.cpp | 642 -- linden/indra/newview/llcape.h | 231 - linden/indra/newview/llchatbar.cpp | 6 + .../indra/newview/llclassifiedstatsresponder.cpp | 4 +- linden/indra/newview/llclassifiedstatsresponder.h | 4 +- linden/indra/newview/llcloud.cpp | 35 - linden/indra/newview/llcloud.h | 1 - linden/indra/newview/llcolorswatch.cpp | 47 +- linden/indra/newview/llcolorswatch.h | 2 +- linden/indra/newview/llcompass.cpp | 1 - linden/indra/newview/llcompilequeue.cpp | 1 - linden/indra/newview/llconsole.cpp | 6 +- linden/indra/newview/llcontainerview.cpp | 21 +- linden/indra/newview/llcontroldef.cpp | 318 +- linden/indra/newview/llcubemap.cpp | 40 +- linden/indra/newview/llcubemap.h | 9 +- linden/indra/newview/lldebugmessagebox.cpp | 1 - linden/indra/newview/lldrawable.cpp | 359 +- linden/indra/newview/lldrawable.h | 28 +- linden/indra/newview/lldrawpool.cpp | 240 +- linden/indra/newview/lldrawpool.h | 33 +- linden/indra/newview/lldrawpoolalpha.cpp | 288 +- linden/indra/newview/lldrawpoolalpha.h | 18 +- linden/indra/newview/lldrawpoolavatar.cpp | 309 +- linden/indra/newview/lldrawpoolavatar.h | 6 +- linden/indra/newview/lldrawpoolbump.cpp | 530 +- linden/indra/newview/lldrawpoolbump.h | 40 +- linden/indra/newview/lldrawpoolclouds.h | 1 - linden/indra/newview/lldrawpoolground.cpp | 14 +- linden/indra/newview/lldrawpoolground.h | 1 - linden/indra/newview/lldrawpoolsimple.cpp | 165 +- linden/indra/newview/lldrawpoolsimple.h | 3 + linden/indra/newview/lldrawpoolsky.cpp | 58 +- linden/indra/newview/lldrawpoolsky.h | 4 +- linden/indra/newview/lldrawpoolstars.cpp | 121 - linden/indra/newview/lldrawpoolstars.h | 57 - linden/indra/newview/lldrawpoolterrain.cpp | 274 +- linden/indra/newview/lldrawpoolterrain.h | 6 +- linden/indra/newview/lldrawpooltree.cpp | 112 +- linden/indra/newview/lldrawpooltree.h | 3 +- linden/indra/newview/lldrawpoolwater.cpp | 393 +- linden/indra/newview/lldrawpoolwater.h | 14 +- linden/indra/newview/lldrawpoolwlsky.cpp | 343 + linden/indra/newview/lldrawpoolwlsky.h | 84 + linden/indra/newview/lldynamictexture.cpp | 27 +- linden/indra/newview/lldynamictexture.h | 4 +- linden/indra/newview/llface.cpp | 587 +- linden/indra/newview/llface.h | 92 +- linden/indra/newview/llface.inl | 81 - linden/indra/newview/llfasttimerview.cpp | 200 +- linden/indra/newview/llfasttimerview.h | 1 + linden/indra/newview/llfeaturemanager.cpp | 348 +- linden/indra/newview/llfeaturemanager.h | 57 +- linden/indra/newview/llfilepicker.cpp | 2 + linden/indra/newview/llfirstuse.cpp | 11 + linden/indra/newview/llfirstuse.h | 3 +- linden/indra/newview/llflexibleobject.cpp | 78 +- linden/indra/newview/llflexibleobject.h | 3 +- linden/indra/newview/llfloaterabout.cpp | 28 +- linden/indra/newview/llfloateractivespeakers.cpp | 36 +- linden/indra/newview/llfloateractivespeakers.h | 14 +- linden/indra/newview/llfloateranimpreview.cpp | 89 +- linden/indra/newview/llfloaterauction.cpp | 4 +- linden/indra/newview/llfloaterauction.h | 2 +- linden/indra/newview/llfloateravatarinfo.cpp | 6 +- linden/indra/newview/llfloateravatarpicker.cpp | 5 +- linden/indra/newview/llfloateravatartextures.cpp | 52 +- linden/indra/newview/llfloaterbump.cpp | 15 +- linden/indra/newview/llfloaterbuy.cpp | 10 +- linden/indra/newview/llfloaterbuy.h | 2 +- linden/indra/newview/llfloaterbuycontents.cpp | 10 +- linden/indra/newview/llfloaterbuycontents.h | 2 +- linden/indra/newview/llfloaterbuycurrency.cpp | 2 +- linden/indra/newview/llfloaterbuyland.cpp | 164 +- linden/indra/newview/llfloaterbuyland.h | 2 +- linden/indra/newview/llfloaterchat.cpp | 53 +- linden/indra/newview/llfloaterchat.h | 9 +- linden/indra/newview/llfloaterchatterbox.cpp | 80 +- linden/indra/newview/llfloaterchatterbox.h | 123 +- linden/indra/newview/llfloaterclassified.cpp | 2 +- linden/indra/newview/llfloatercolorpicker.cpp | 214 +- linden/indra/newview/llfloatercolorpicker.h | 2 +- linden/indra/newview/llfloatercustomize.cpp | 57 +- linden/indra/newview/llfloatercustomize.h | 1 - linden/indra/newview/llfloaterdaycycle.cpp | 612 ++ linden/indra/newview/llfloaterdaycycle.h | 146 + linden/indra/newview/llfloaterdirectory.cpp | 4 +- linden/indra/newview/llfloaterenvsettings.cpp | 384 + linden/indra/newview/llfloaterenvsettings.h | 106 + linden/indra/newview/llfloaterfriends.cpp | 84 +- linden/indra/newview/llfloaterfriends.h | 9 +- linden/indra/newview/llfloatergesture.cpp | 2 +- linden/indra/newview/llfloatergroupinvite.cpp | 2 +- linden/indra/newview/llfloatergroups.h | 10 +- linden/indra/newview/llfloaterhardwaresettings.cpp | 207 + linden/indra/newview/llfloaterhardwaresettings.h | 102 + linden/indra/newview/llfloaterhtml.cpp | 81 +- linden/indra/newview/llfloaterhtml.h | 18 +- linden/indra/newview/llfloaterhtmlhelp.cpp | 528 ++ linden/indra/newview/llfloaterhtmlhelp.h | 87 + linden/indra/newview/llfloaterimagepreview.cpp | 130 +- linden/indra/newview/llfloaterimport.cpp | 669 -- linden/indra/newview/llfloaterimport.h | 114 - linden/indra/newview/llfloaterinspect.cpp | 15 +- linden/indra/newview/llfloaterinspect.h | 2 +- linden/indra/newview/llfloaterlagmeter.cpp | 116 +- linden/indra/newview/llfloaterlagmeter.h | 2 + linden/indra/newview/llfloaterland.cpp | 474 +- linden/indra/newview/llfloaterland.h | 66 +- linden/indra/newview/llfloaterlandmark.h | 3 +- linden/indra/newview/llfloatermap.cpp | 13 +- linden/indra/newview/llfloatermute.h | 2 +- linden/indra/newview/llfloaternamedesc.cpp | 19 +- linden/indra/newview/llfloaternamedesc.h | 1 - linden/indra/newview/llfloaternewim.cpp | 13 +- linden/indra/newview/llfloateropenobject.h | 2 +- linden/indra/newview/llfloaterpermissionsmgr.cpp | 12 +- linden/indra/newview/llfloaterpostcard.cpp | 57 +- linden/indra/newview/llfloaterpostcard.h | 6 +- linden/indra/newview/llfloaterpostprocess.cpp | 273 + linden/indra/newview/llfloaterpostprocess.h | 90 + linden/indra/newview/llfloaterpreference.cpp | 58 +- linden/indra/newview/llfloaterpreference.h | 16 +- linden/indra/newview/llfloaterproperties.cpp | 28 +- linden/indra/newview/llfloaterregioninfo.cpp | 192 +- linden/indra/newview/llfloaterregioninfo.h | 21 +- linden/indra/newview/llfloaterreleasemsg.cpp | 12 +- linden/indra/newview/llfloaterreleasemsg.h | 2 - linden/indra/newview/llfloaterreporter.cpp | 4 +- linden/indra/newview/llfloatersaveavatar.cpp | 117 - linden/indra/newview/llfloatersaveavatar.h | 58 - linden/indra/newview/llfloaterscriptdebug.cpp | 8 +- linden/indra/newview/llfloatersellland.cpp | 8 +- linden/indra/newview/llfloatersellland.h | 2 +- linden/indra/newview/llfloatersnapshot.cpp | 550 +- linden/indra/newview/llfloatertelehub.h | 2 +- linden/indra/newview/llfloatertest.cpp | 12 +- linden/indra/newview/llfloatertools.cpp | 44 +- linden/indra/newview/llfloatertools.h | 6 +- linden/indra/newview/llfloatertopobjects.cpp | 14 +- linden/indra/newview/llfloatertos.cpp | 27 +- linden/indra/newview/llfloaterurldisplay.h | 2 +- linden/indra/newview/llfloaterurlentry.cpp | 293 + linden/indra/newview/llfloaterurlentry.h | 69 + linden/indra/newview/llfloatervoicewizard.cpp | 14 +- linden/indra/newview/llfloatervoicewizard.h | 8 +- linden/indra/newview/llfloaterwater.cpp | 735 ++ linden/indra/newview/llfloaterwater.h | 133 + linden/indra/newview/llfloaterwindlight.cpp | 998 +++ linden/indra/newview/llfloaterwindlight.h | 142 + linden/indra/newview/llfloaterworldmap.cpp | 32 +- linden/indra/newview/llfloaterworldmap.h | 2 +- linden/indra/newview/llfolderview.cpp | 172 +- linden/indra/newview/llfolderview.h | 21 +- linden/indra/newview/llframestats.cpp | 4 - linden/indra/newview/llframestats.h | 1 - linden/indra/newview/llframestatview.cpp | 14 +- linden/indra/newview/llgenepool.cpp | 17 +- linden/indra/newview/llgivemoney.cpp | 3 +- linden/indra/newview/llgivemoney.h | 2 +- linden/indra/newview/llglsandbox.cpp | 443 +- linden/indra/newview/llglslshader.cpp | 2016 +++-- linden/indra/newview/llglslshader.h | 299 +- linden/indra/newview/llgroupnotify.cpp | 12 +- linden/indra/newview/llhoverview.cpp | 241 +- linden/indra/newview/llhoverview.h | 7 +- linden/indra/newview/llhudconnector.cpp | 221 - linden/indra/newview/llhudconnector.h | 81 - linden/indra/newview/llhudeffectbeam.cpp | 45 - linden/indra/newview/llhudeffectlookat.cpp | 20 +- linden/indra/newview/llhudeffectlookat.h | 1 - linden/indra/newview/llhudeffectpointat.cpp | 19 +- linden/indra/newview/llhudeffecttrail.cpp | 12 +- linden/indra/newview/llhudicon.cpp | 32 +- linden/indra/newview/llhudmanager.cpp | 3 +- linden/indra/newview/llhudmanager.h | 3 - linden/indra/newview/llhudobject.cpp | 9 - linden/indra/newview/llhudobject.h | 1 - linden/indra/newview/llhudrender.cpp | 10 +- linden/indra/newview/llhudtext.cpp | 36 +- linden/indra/newview/llimpanel.cpp | 16 +- linden/indra/newview/llimpanel.h | 2 +- linden/indra/newview/llimview.cpp | 43 +- linden/indra/newview/llimview.h | 4 +- linden/indra/newview/llinventoryactions.cpp | 7 +- linden/indra/newview/llinventorybridge.cpp | 52 +- linden/indra/newview/llinventorybridge.h | 2 +- linden/indra/newview/llinventorymodel.cpp | 301 +- linden/indra/newview/llinventorymodel.h | 30 +- linden/indra/newview/llinventoryview.cpp | 15 +- linden/indra/newview/llinventoryview.h | 5 +- linden/indra/newview/lljoystickbutton.cpp | 73 +- linden/indra/newview/lljoystickbutton.h | 2 +- linden/indra/newview/lllcd.cpp | 100 +- linden/indra/newview/lllocalanimationobject.cpp | 298 - linden/indra/newview/lllocalanimationobject.h | 131 - linden/indra/newview/llmanip.cpp | 45 +- linden/indra/newview/llmanip.h | 4 +- linden/indra/newview/llmaniprotate.cpp | 51 +- linden/indra/newview/llmanipscale.cpp | 167 +- linden/indra/newview/llmanipscale.h | 17 +- linden/indra/newview/llmaniptranslate.cpp | 416 +- linden/indra/newview/llmaniptranslate.h | 15 +- linden/indra/newview/llmediaremotectrl.cpp | 170 +- linden/indra/newview/llmediaremotectrl.h | 3 + linden/indra/newview/llmemoryview.cpp | 11 +- linden/indra/newview/llmenucommands.cpp | 1 - linden/indra/newview/llmimetypes.cpp | 264 + linden/indra/newview/llmimetypes.h | 118 + linden/indra/newview/llmoveview.cpp | 1 - linden/indra/newview/llnamebox.cpp | 15 +- linden/indra/newview/llnamebox.h | 1 - linden/indra/newview/llnameeditor.cpp | 14 +- linden/indra/newview/llnameeditor.h | 1 - linden/indra/newview/llnamelistctrl.cpp | 43 +- linden/indra/newview/llnetmap.cpp | 193 +- linden/indra/newview/llnetmap.h | 2 +- linden/indra/newview/llnotify.cpp | 60 +- linden/indra/newview/llnotify.h | 11 + linden/indra/newview/lloverlaybar.cpp | 82 +- linden/indra/newview/lloverlaybar.h | 9 +- linden/indra/newview/llpanelaudioprefs.cpp | 1 - linden/indra/newview/llpanelaudiovolume.cpp | 1 + linden/indra/newview/llpanelaudiovolume.h | 1 - linden/indra/newview/llpanelavatar.cpp | 105 +- linden/indra/newview/llpanelavatar.h | 10 +- linden/indra/newview/llpanelclassified.cpp | 75 +- linden/indra/newview/llpanelclassified.h | 8 +- linden/indra/newview/llpaneldirbrowser.cpp | 47 +- linden/indra/newview/llpaneldirbrowser.h | 2 + linden/indra/newview/llpaneldirfind.cpp | 31 +- linden/indra/newview/llpaneldirgroups.cpp | 26 +- linden/indra/newview/llpaneldirland.cpp | 4 +- linden/indra/newview/llpaneldirpeople.cpp | 26 +- linden/indra/newview/llpaneldirplaces.cpp | 26 +- linden/indra/newview/llpaneldisplay.cpp | 850 +- linden/indra/newview/llpaneldisplay.h | 176 +- linden/indra/newview/llpanelevent.cpp | 21 +- linden/indra/newview/llpanelface.cpp | 129 +- linden/indra/newview/llpanelface.h | 3 + linden/indra/newview/llpanelgeneral.cpp | 12 +- linden/indra/newview/llpanelgeneral.h | 3 + linden/indra/newview/llpanelgroup.cpp | 43 +- linden/indra/newview/llpanelgroup.h | 6 +- linden/indra/newview/llpanelgroupgeneral.cpp | 52 +- linden/indra/newview/llpanelgroupinvite.cpp | 16 +- linden/indra/newview/llpanelgrouplandmoney.cpp | 73 +- linden/indra/newview/llpanelgroupnotices.cpp | 43 +- linden/indra/newview/llpanelgrouproles.cpp | 103 +- linden/indra/newview/llpanelgrouproles.h | 4 +- linden/indra/newview/llpanelgroupvoting.cpp | 86 +- linden/indra/newview/llpanelinput.cpp | 5 + linden/indra/newview/llpanelinput.h | 1 + linden/indra/newview/llpanelinventory.cpp | 23 +- linden/indra/newview/llpanelinventory.h | 1 - linden/indra/newview/llpanelland.cpp | 2 +- linden/indra/newview/llpanellandmedia.cpp | 401 + linden/indra/newview/llpanellandmedia.h | 80 + linden/indra/newview/llpanellogin.cpp | 56 +- linden/indra/newview/llpanellogin.h | 12 +- linden/indra/newview/llpanelobject.cpp | 30 +- linden/indra/newview/llpanelpermissions.cpp | 14 +- linden/indra/newview/llpanelpick.cpp | 4 +- linden/indra/newview/llpanelplace.cpp | 21 +- linden/indra/newview/llpanelvolume.cpp | 27 +- linden/indra/newview/llpanelweb.cpp | 163 +- linden/indra/newview/llpanelweb.h | 2 + linden/indra/newview/llparcelselection.cpp | 105 + linden/indra/newview/llparcelselection.h | 86 + linden/indra/newview/llpolymesh.cpp | 82 +- linden/indra/newview/llpolymesh.h | 17 +- linden/indra/newview/llpolymorph.cpp | 5 - linden/indra/newview/llpolymorph.h | 2 - linden/indra/newview/llpostprocess.cpp | 641 ++ linden/indra/newview/llpostprocess.h | 275 + linden/indra/newview/llprefsim.cpp | 4 +- linden/indra/newview/llprefsvoice.cpp | 1 + linden/indra/newview/llpreview.cpp | 24 +- linden/indra/newview/llpreview.h | 8 +- linden/indra/newview/llpreviewanim.cpp | 35 +- linden/indra/newview/llpreviewanim.h | 1 - linden/indra/newview/llpreviewgesture.cpp | 16 +- linden/indra/newview/llpreviewlandmark.cpp | 1 - linden/indra/newview/llpreviewlandmark.h | 1 - linden/indra/newview/llpreviewnotecard.cpp | 6 +- linden/indra/newview/llpreviewscript.cpp | 98 +- linden/indra/newview/llpreviewscript.h | 4 +- linden/indra/newview/llpreviewtexture.cpp | 21 +- linden/indra/newview/llprogressview.cpp | 21 +- linden/indra/newview/llremoteparcelrequest.cpp | 6 +- linden/indra/newview/llremoteparcelrequest.h | 6 +- linden/indra/newview/llroam.cpp | 307 - linden/indra/newview/llroam.h | 308 - linden/indra/newview/llselectmgr.cpp | 178 +- linden/indra/newview/llselectmgr.h | 16 +- linden/indra/newview/llsky.cpp | 100 +- linden/indra/newview/llsky.h | 13 +- linden/indra/newview/llspatialpartition.cpp | 2213 +++-- linden/indra/newview/llspatialpartition.h | 213 +- linden/indra/newview/llsprite.cpp | 10 +- linden/indra/newview/llstartup.cpp | 240 +- linden/indra/newview/llstartup.h | 4 +- linden/indra/newview/llstatbar.cpp | 8 +- linden/indra/newview/llstatgraph.cpp | 15 +- linden/indra/newview/llstatusbar.cpp | 148 +- linden/indra/newview/llstatusbar.h | 37 +- linden/indra/newview/llstatview.cpp | 4 +- linden/indra/newview/llsurface.cpp | 77 - linden/indra/newview/llsurface.h | 2 - linden/indra/newview/llsurfacepatch.cpp | 19 +- linden/indra/newview/lltexlayer.cpp | 60 +- linden/indra/newview/lltexturectrl.cpp | 108 +- linden/indra/newview/lltexturectrl.h | 3 +- linden/indra/newview/lltextureview.cpp | 36 +- linden/indra/newview/lltextureview.h | 1 - linden/indra/newview/lltool.cpp | 1 - linden/indra/newview/lltool.h | 2 +- linden/indra/newview/lltoolbar.cpp | 8 +- linden/indra/newview/lltoolbrush.cpp | 77 +- linden/indra/newview/lltoolbrush.h | 15 +- linden/indra/newview/lltoolcomp.cpp | 8 +- linden/indra/newview/lltooldraganddrop.cpp | 6 +- linden/indra/newview/lltoolfocus.cpp | 1 - linden/indra/newview/lltoolgun.cpp | 1 + linden/indra/newview/lltoolmgr.cpp | 50 +- linden/indra/newview/lltoolmgr.h | 4 +- linden/indra/newview/lltoolmorph.cpp | 40 +- linden/indra/newview/lltoolmorph.h | 6 +- linden/indra/newview/lltoolpie.cpp | 178 +- linden/indra/newview/lltoolpie.h | 2 +- linden/indra/newview/lltoolselect.cpp | 3 +- linden/indra/newview/lltoolselect.h | 2 +- linden/indra/newview/lltoolselectland.h | 2 +- linden/indra/newview/lltoolselectrect.cpp | 9 +- linden/indra/newview/lltoolview.cpp | 19 +- linden/indra/newview/lltoolview.h | 5 +- linden/indra/newview/lltracker.cpp | 45 +- linden/indra/newview/lluploaddialog.cpp | 29 +- linden/indra/newview/lluploaddialog.h | 2 - linden/indra/newview/llurldispatcher.cpp | 3 +- linden/indra/newview/llurlhistory.cpp | 137 + linden/indra/newview/llurlhistory.h | 60 + linden/indra/newview/llvelocitybar.cpp | 31 +- linden/indra/newview/llviewerassetstorage.cpp | 59 +- linden/indra/newview/llvieweraudio.cpp | 13 +- linden/indra/newview/llviewercamera.cpp | 195 +- linden/indra/newview/llviewercamera.h | 7 +- linden/indra/newview/llviewercontrol.cpp | 10 +- linden/indra/newview/llviewercontrol.h | 3 + linden/indra/newview/llviewerdisplay.cpp | 594 +- linden/indra/newview/llviewerdisplay.h | 5 +- linden/indra/newview/llviewerimage.cpp | 8 +- linden/indra/newview/llviewerimage.h | 4 + linden/indra/newview/llviewerimagelist.cpp | 270 +- linden/indra/newview/llviewerimagelist.h | 16 +- linden/indra/newview/llviewerinventory.cpp | 48 +- linden/indra/newview/llviewerinventory.h | 1 + linden/indra/newview/llviewerjoint.cpp | 205 +- linden/indra/newview/llviewerjoint.h | 1 - linden/indra/newview/llviewerjointattachment.cpp | 67 +- linden/indra/newview/llviewerjointattachment.h | 3 - linden/indra/newview/llviewerjointmesh.cpp | 290 +- linden/indra/newview/llviewerjointmesh.h | 5 +- linden/indra/newview/llviewerjointmesh_sse.cpp | 2 + linden/indra/newview/llviewerjointmesh_sse2.cpp | 2 + linden/indra/newview/llviewerjointmesh_vec.cpp | 2 + linden/indra/newview/llviewerjointshape.cpp | 233 - linden/indra/newview/llviewerjointshape.h | 96 - linden/indra/newview/llviewerkeyboard.cpp | 7 +- linden/indra/newview/llviewermedia.cpp | 634 ++ linden/indra/newview/llviewermedia.h | 72 + linden/indra/newview/llviewermenu.cpp | 412 +- linden/indra/newview/llviewermenu.h | 8 +- linden/indra/newview/llviewermenufile.cpp | 15 +- linden/indra/newview/llviewermessage.cpp | 92 +- linden/indra/newview/llviewermessage.h | 3 + linden/indra/newview/llviewerobject.cpp | 115 +- linden/indra/newview/llviewerobject.h | 30 +- linden/indra/newview/llviewerobjectlist.cpp | 53 +- linden/indra/newview/llviewerobjectlist.h | 3 - linden/indra/newview/llviewerparcelmedia.cpp | 363 + linden/indra/newview/llviewerparcelmedia.h | 75 + .../indra/newview/llviewerparcelmediaautoplay.cpp | 151 + linden/indra/newview/llviewerparcelmediaautoplay.h | 55 + linden/indra/newview/llviewerparcelmgr.cpp | 312 +- linden/indra/newview/llviewerparcelmgr.h | 56 +- linden/indra/newview/llviewerparceloverlay.cpp | 38 +- linden/indra/newview/llviewerpartsim.cpp | 200 +- linden/indra/newview/llviewerpartsim.h | 35 +- linden/indra/newview/llviewerpartsource.cpp | 65 +- linden/indra/newview/llviewerpartsource.h | 2 + linden/indra/newview/llviewerprecompiledheaders.h | 10 - linden/indra/newview/llviewerregion.cpp | 51 +- linden/indra/newview/llviewerregion.h | 31 +- linden/indra/newview/llviewerstats.cpp | 6 +- linden/indra/newview/llviewertexteditor.cpp | 246 +- linden/indra/newview/llviewertexteditor.h | 41 +- linden/indra/newview/llvieweruictrlfactory.cpp | 20 +- linden/indra/newview/llviewerwindow.cpp | 431 +- linden/indra/newview/llviewerwindow.h | 7 +- linden/indra/newview/llvoavatar.cpp | 1249 ++- linden/indra/newview/llvoavatar.h | 59 +- linden/indra/newview/llvoclouds.cpp | 159 +- linden/indra/newview/llvoclouds.h | 3 +- linden/indra/newview/llvograss.cpp | 8 +- linden/indra/newview/llvograss.h | 2 +- linden/indra/newview/llvoground.cpp | 3 +- linden/indra/newview/llvoiceclient.cpp | 26 +- linden/indra/newview/llvoiceremotectrl.cpp | 5 +- linden/indra/newview/llvoicevisualizer.cpp | 51 +- linden/indra/newview/llvopartgroup.cpp | 207 +- linden/indra/newview/llvopartgroup.h | 5 +- linden/indra/newview/llvosky.cpp | 1505 ++-- linden/indra/newview/llvosky.h | 407 +- linden/indra/newview/llvostars.cpp | 211 - linden/indra/newview/llvostars.h | 67 - linden/indra/newview/llvosurfacepatch.cpp | 94 +- linden/indra/newview/llvosurfacepatch.h | 12 +- linden/indra/newview/llvotextbubble.cpp | 5 +- linden/indra/newview/llvotextbubble.h | 2 +- linden/indra/newview/llvotree.cpp | 195 +- linden/indra/newview/llvotree.h | 4 +- linden/indra/newview/llvovolume.cpp | 731 +- linden/indra/newview/llvovolume.h | 31 +- linden/indra/newview/llvowater.cpp | 84 +- linden/indra/newview/llvowater.h | 4 + linden/indra/newview/llvowlsky.cpp | 821 ++ linden/indra/newview/llvowlsky.h | 110 + linden/indra/newview/llwaterparammanager.cpp | 433 + linden/indra/newview/llwaterparammanager.h | 401 + linden/indra/newview/llwaterparamset.cpp | 233 + linden/indra/newview/llwaterparamset.h | 156 + linden/indra/newview/llwearable.cpp | 125 +- linden/indra/newview/llwearable.h | 7 +- linden/indra/newview/llwearablelist.cpp | 5 +- linden/indra/newview/llwearablelist.h | 7 +- linden/indra/newview/llweb.cpp | 13 +- linden/indra/newview/llwebbrowserctrl.cpp | 385 +- linden/indra/newview/llwebbrowserctrl.h | 29 +- linden/indra/newview/llwindebug.cpp | 194 +- linden/indra/newview/llwlanimator.cpp | 168 + linden/indra/newview/llwlanimator.h | 76 + linden/indra/newview/llwldaycycle.cpp | 233 + linden/indra/newview/llwldaycycle.h | 105 + linden/indra/newview/llwlparammanager.cpp | 572 ++ linden/indra/newview/llwlparammanager.h | 292 + linden/indra/newview/llwlparamset.cpp | 403 + linden/indra/newview/llwlparamset.h | 252 + linden/indra/newview/llworld.cpp | 87 +- linden/indra/newview/llworld.h | 3 + linden/indra/newview/llworldmapview.cpp | 253 +- linden/indra/newview/llxmlrpctransaction.cpp | 152 +- linden/indra/newview/lsl_guide.html | 1979 +++-- .../newview/macview.xcodeproj/project.pbxproj | 397 +- linden/indra/newview/newview.vcproj | 233 +- linden/indra/newview/newview_vc8.vcproj | 8959 ++++++++++---------- linden/indra/newview/newview_vc9.vcproj | 8940 +++++++++---------- linden/indra/newview/pipeline.cpp | 2903 +++++-- linden/indra/newview/pipeline.h | 202 +- linden/indra/newview/postbuild.bat | 2 +- linden/indra/newview/releasenotes.txt | 90 + linden/indra/newview/res/newViewRes.rc | 43 +- linden/indra/newview/res/resource.h | 2 + .../indra/newview/secondlife setup build aruna.bat | 4 + .../secondlife setup build firstlookwindlight.bat | 4 + .../indra/newview/secondlife setup build mitra.bat | 4 + .../newview/secondlife setup build mohini.bat | 4 + .../indra/newview/secondlife setup build nandi.bat | 4 + .../indra/newview/secondlife setup build radha.bat | 4 + .../indra/newview/secondlife setup build ravi.bat | 4 + linden/indra/newview/skins/textures/textures.xml | 17 +- linden/indra/newview/skins/xui/de/floater_html.xml | 14 +- linden/indra/newview/skins/xui/en-us/LCD_text.xml | 102 +- linden/indra/newview/skins/xui/en-us/alerts.xml | 677 +- .../newview/skins/xui/en-us/floater_about.xml | 11 +- .../newview/skins/xui/en-us/floater_about_land.xml | 916 +- .../skins/xui/en-us/floater_active_speakers.xml | 93 +- .../skins/xui/en-us/floater_animation_preview.xml | 53 +- .../newview/skins/xui/en-us/floater_auction.xml | 4 +- .../skins/xui/en-us/floater_audio_volume.xml | 15 +- .../skins/xui/en-us/floater_avatar_picker.xml | 49 +- .../skins/xui/en-us/floater_avatar_textures.xml | 6 +- .../newview/skins/xui/en-us/floater_bumps.xml | 32 +- .../skins/xui/en-us/floater_buy_contents.xml | 12 +- .../skins/xui/en-us/floater_buy_currency.xml | 14 +- .../newview/skins/xui/en-us/floater_buy_land.xml | 177 +- .../newview/skins/xui/en-us/floater_buy_object.xml | 19 +- .../skins/xui/en-us/floater_chat_history.xml | 114 +- .../newview/skins/xui/en-us/floater_chatterbox.xml | 3 +- .../skins/xui/en-us/floater_color_picker.xml | 2 +- .../newview/skins/xui/en-us/floater_critical.xml | 2 +- .../newview/skins/xui/en-us/floater_customize.xml | 921 +- .../skins/xui/en-us/floater_day_cycle_options.xml | 250 + .../skins/xui/en-us/floater_device_settings.xml | 7 +- .../newview/skins/xui/en-us/floater_directory.xml | 339 +- .../skins/xui/en-us/floater_env_settings.xml | 66 + .../newview/skins/xui/en-us/floater_friends.xml | 20 +- .../newview/skins/xui/en-us/floater_god_tools.xml | 261 +- .../newview/skins/xui/en-us/floater_groups.xml | 44 +- .../skins/xui/en-us/floater_hardware_settings.xml | 53 + .../indra/newview/skins/xui/en-us/floater_html.xml | 40 +- .../indra/newview/skins/xui/en-us/floater_im.xml | 33 +- .../skins/xui/en-us/floater_image_preview.xml | 10 +- .../newview/skins/xui/en-us/floater_inspect.xml | 57 +- .../skins/xui/en-us/floater_instant_message.xml | 24 +- .../xui/en-us/floater_instant_message_ad_hoc.xml | 109 +- .../xui/en-us/floater_instant_message_group.xml | 38 +- .../newview/skins/xui/en-us/floater_inventory.xml | 165 +- .../en-us/floater_inventory_item_properties.xml | 20 +- .../xui/en-us/floater_inventory_view_finder.xml | 123 +- .../newview/skins/xui/en-us/floater_joystick.xml | 145 +- .../newview/skins/xui/en-us/floater_lagmeter.xml | 621 +- .../skins/xui/en-us/floater_land_holdings.xml | 4 +- .../skins/xui/en-us/floater_landmark_ctrl.xml | 62 +- .../skins/xui/en-us/floater_live_lsleditor.xml | 22 +- .../newview/skins/xui/en-us/floater_lsl_guide.xml | 20 +- .../skins/xui/en-us/floater_media_browser.xml | 37 + .../newview/skins/xui/en-us/floater_moveview.xml | 27 +- .../indra/newview/skins/xui/en-us/floater_mute.xml | 20 +- .../skins/xui/en-us/floater_mute_object.xml | 10 +- .../newview/skins/xui/en-us/floater_my_friends.xml | 4 +- .../newview/skins/xui/en-us/floater_new_im.xml | 30 +- .../skins/xui/en-us/floater_new_outfit_dialog.xml | 263 +- .../newview/skins/xui/en-us/floater_openobject.xml | 22 +- .../indra/newview/skins/xui/en-us/floater_pay.xml | 58 +- .../newview/skins/xui/en-us/floater_pay_object.xml | 63 +- .../skins/xui/en-us/floater_post_process.xml | 184 + .../newview/skins/xui/en-us/floater_postcard.xml | 45 +- .../skins/xui/en-us/floater_preferences.xml | 40 +- .../skins/xui/en-us/floater_preview_animation.xml | 23 +- .../skins/xui/en-us/floater_preview_classified.xml | 11 +- .../xui/en-us/floater_preview_embedded_texture.xml | 14 +- .../skins/xui/en-us/floater_preview_event.xml | 10 +- .../en-us/floater_preview_existing_landmark.xml | 10 +- .../skins/xui/en-us/floater_preview_gesture.xml | 18 +- .../xui/en-us/floater_preview_new_landmark.xml | 33 +- .../skins/xui/en-us/floater_preview_notecard.xml | 39 +- .../floater_preview_notecard_keep_discard.xml | 36 +- .../skins/xui/en-us/floater_preview_sound.xml | 38 +- .../skins/xui/en-us/floater_preview_texture.xml | 18 +- .../en-us/floater_preview_texture_keep_discard.xml | 30 +- .../skins/xui/en-us/floater_preview_url.xml | 10 +- .../skins/xui/en-us/floater_price_for_listing.xml | 10 +- .../indra/newview/skins/xui/en-us/floater_rate.xml | 73 +- .../skins/xui/en-us/floater_region_info.xml | 6 +- .../skins/xui/en-us/floater_report_abuse.xml | 48 +- .../newview/skins/xui/en-us/floater_report_bug.xml | 43 +- .../skins/xui/en-us/floater_script_debug.xml | 10 +- .../skins/xui/en-us/floater_script_ed_panel.xml | 119 +- .../skins/xui/en-us/floater_script_preview.xml | 24 +- .../skins/xui/en-us/floater_script_queue.xml | 15 +- .../skins/xui/en-us/floater_script_search.xml | 37 +- .../newview/skins/xui/en-us/floater_select_key.xml | 30 +- .../newview/skins/xui/en-us/floater_sell_land.xml | 28 +- .../skins/xui/en-us/floater_settings_debug.xml | 1 + .../xui/en-us/floater_sim_release_message.xml | 20 +- .../newview/skins/xui/en-us/floater_snapshot.xml | 56 +- .../skins/xui/en-us/floater_sound_preview.xml | 8 +- .../indra/newview/skins/xui/en-us/floater_test.xml | 8 +- .../skins/xui/en-us/floater_texture_ctrl.xml | 71 +- .../newview/skins/xui/en-us/floater_tools.xml | 1078 ++- .../skins/xui/en-us/floater_top_objects.xml | 63 +- .../indra/newview/skins/xui/en-us/floater_tos.xml | 6 +- .../newview/skins/xui/en-us/floater_url_entry.xml | 23 + .../skins/xui/en-us/floater_voice_wizard.xml | 34 +- .../newview/skins/xui/en-us/floater_water.xml | 260 + .../skins/xui/en-us/floater_wearable_save_as.xml | 22 +- .../skins/xui/en-us/floater_windlight_options.xml | 593 ++ .../newview/skins/xui/en-us/floater_world_map.xml | 24 +- .../newview/skins/xui/en-us/menu_inventory.xml | 237 +- .../indra/newview/skins/xui/en-us/menu_login.xml | 42 +- .../skins/xui/en-us/menu_pie_attachment.xml | 6 +- .../newview/skins/xui/en-us/menu_pie_avatar.xml | 36 +- .../newview/skins/xui/en-us/menu_pie_land.xml | 20 +- .../newview/skins/xui/en-us/menu_pie_object.xml | 38 +- .../newview/skins/xui/en-us/menu_pie_self.xml | 30 +- .../indra/newview/skins/xui/en-us/menu_slurl.xml | 16 +- .../indra/newview/skins/xui/en-us/menu_viewer.xml | 953 +-- .../indra/newview/skins/xui/en-us/mime_types.xml | 448 + linden/indra/newview/skins/xui/en-us/notify.xml | 102 +- .../indra/newview/skins/xui/en-us/panel_audio.xml | 18 +- .../newview/skins/xui/en-us/panel_audio_device.xml | 137 +- .../indra/newview/skins/xui/en-us/panel_avatar.xml | 124 +- .../skins/xui/en-us/panel_avatar_classified.xml | 12 +- .../indra/newview/skins/xui/en-us/panel_bars.xml | 30 +- .../indra/newview/skins/xui/en-us/panel_bg_tab.xml | 20 +- .../newview/skins/xui/en-us/panel_chat_bar.xml | 22 +- .../newview/skins/xui/en-us/panel_classified.xml | 11 +- .../indra/newview/skins/xui/en-us/panel_event.xml | 12 +- .../newview/skins/xui/en-us/panel_friends.xml | 53 +- .../indra/newview/skins/xui/en-us/panel_group.xml | 14 +- .../skins/xui/en-us/panel_group_general.xml | 79 +- .../newview/skins/xui/en-us/panel_group_invite.xml | 10 +- .../skins/xui/en-us/panel_group_land_money.xml | 19 +- .../skins/xui/en-us/panel_group_notices.xml | 14 +- .../newview/skins/xui/en-us/panel_group_roles.xml | 63 +- .../newview/skins/xui/en-us/panel_group_voting.xml | 82 +- .../indra/newview/skins/xui/en-us/panel_groups.xml | 46 +- .../skins/xui/en-us/panel_land_covenant.xml | 18 +- .../indra/newview/skins/xui/en-us/panel_login.xml | 35 +- .../skins/xui/en-us/panel_master_volume.xml | 4 +- .../skins/xui/en-us/panel_media_controls.xml | 67 +- .../newview/skins/xui/en-us/panel_media_remote.xml | 33 +- .../xui/en-us/panel_media_remote_expanded.xml | 11 +- .../newview/skins/xui/en-us/panel_music_remote.xml | 21 +- .../newview/skins/xui/en-us/panel_overlaybar.xml | 86 +- .../indra/newview/skins/xui/en-us/panel_place.xml | 74 +- .../newview/skins/xui/en-us/panel_place_small.xml | 74 +- .../skins/xui/en-us/panel_preferences_LCD.xml | 91 +- .../skins/xui/en-us/panel_preferences_audio.xml | 93 +- .../skins/xui/en-us/panel_preferences_chat.xml | 135 +- .../skins/xui/en-us/panel_preferences_general.xml | 157 +- .../xui/en-us/panel_preferences_graphics1.xml | 413 +- .../xui/en-us/panel_preferences_graphics2.xml | 132 - .../xui/en-us/panel_preferences_graphics3.xml | 119 - .../skins/xui/en-us/panel_preferences_im.xml | 94 +- .../skins/xui/en-us/panel_preferences_input.xml | 73 +- .../skins/xui/en-us/panel_preferences_network.xml | 100 +- .../skins/xui/en-us/panel_preferences_popups.xml | 36 +- .../skins/xui/en-us/panel_preferences_voice.xml | 182 +- .../skins/xui/en-us/panel_preferences_web.xml | 89 +- .../skins/xui/en-us/panel_region_covenant.xml | 32 +- .../newview/skins/xui/en-us/panel_region_debug.xml | 8 +- .../skins/xui/en-us/panel_region_estate.xml | 212 +- .../skins/xui/en-us/panel_region_general.xml | 13 +- .../skins/xui/en-us/panel_region_terrain.xml | 1 + .../skins/xui/en-us/panel_region_texture.xml | 1 + .../skins/xui/en-us/panel_scrolling_param.xml | 38 +- .../skins/xui/en-us/panel_speaker_controls.xml | 105 +- .../newview/skins/xui/en-us/panel_status_bar.xml | 147 +- .../newview/skins/xui/en-us/panel_toolbar.xml | 21 +- .../skins/xui/en-us/panel_voice_controls.xml | 3 +- .../newview/skins/xui/en-us/panel_voice_enable.xml | 135 +- .../skins/xui/en-us/panel_voice_options.xml | 7 +- .../newview/skins/xui/en-us/panel_voice_remote.xml | 10 +- .../xui/en-us/panel_voice_remote_expanded.xml | 22 +- .../newview/skins/xui/en-us/teleport_strings.xml | 48 +- linden/indra/newview/skins/xui/es/floater_html.xml | 6 +- linden/indra/newview/skins/xui/fr/floater_html.xml | 6 +- linden/indra/newview/skins/xui/ja/floater_html.xml | 14 +- linden/indra/newview/skins/xui/ko/floater_html.xml | 14 +- linden/indra/newview/skins/xui/pt/floater_html.xml | 22 +- linden/indra/newview/skins/xui/zh/floater_html.xml | 6 +- linden/indra/newview/viewer_manifest.py | 10 +- linden/indra/test/common.cpp | 41 +- linden/indra/test/io.cpp | 30 +- linden/indra/test/llhttpclient_tut.cpp | 42 +- linden/indra/test/llsdserialize_tut.cpp | 927 +- linden/indra/test/test_vc8.vcproj | 910 +- linden/indra/test/test_vc9.vcproj | 906 +- .../win_crash_logger/win_crash_logger_vc8.vcproj | 672 +- .../win_crash_logger/win_crash_logger_vc9.vcproj | 671 +- linden/indra/win_updater/win_updater_vc8.vcproj | 590 +- linden/indra/win_updater/win_updater_vc9.vcproj | 586 +- linden/libraries/include/glh/glh_linear.h | 1621 ++++ linden/libraries/include/llmozlib.h | 310 - linden/libraries/include/llmozlib2.h | 368 + linden/scripts/messages/message_template.msg | 8 + linden/scripts/setup-path.py | 2 +- linden/scripts/template_verifier.py | 25 +- 1140 files changed, 98826 insertions(+), 69529 deletions(-) create mode 100644 linden/indra/lib/python/indra/base/lllog.py create mode 100644 linden/indra/lib/python/indra/util/llsubprocess.py create mode 100644 linden/indra/lib/python/indra/util/shutil2.py delete mode 100644 linden/indra/llmedia/llmediabase.cpp delete mode 100644 linden/indra/llmedia/llmediaemitterevents.h delete mode 100644 linden/indra/llmedia/llmediaengine.cpp delete mode 100644 linden/indra/llmedia/llmediaengine.h create mode 100644 linden/indra/llmedia/llmediaimplcommon.cpp create mode 100644 linden/indra/llmedia/llmediaimplcommon.h create mode 100644 linden/indra/llmedia/llmediaimplexample1.cpp create mode 100644 linden/indra/llmedia/llmediaimplexample1.h create mode 100644 linden/indra/llmedia/llmediaimplexample2.cpp create mode 100644 linden/indra/llmedia/llmediaimplexample2.h create mode 100644 linden/indra/llmedia/llmediaimplfactory.cpp create mode 100644 linden/indra/llmedia/llmediaimplfactory.h create mode 100644 linden/indra/llmedia/llmediaimplllmozlib.cpp create mode 100644 linden/indra/llmedia/llmediaimplllmozlib.h create mode 100644 linden/indra/llmedia/llmediaimplregister.h create mode 100644 linden/indra/llmedia/llmediamanager.cpp create mode 100644 linden/indra/llmedia/llmediamanager.h delete mode 100644 linden/indra/llmedia/llmediamoviebase.cpp delete mode 100644 linden/indra/llmedia/llmediamoviebase.h create mode 100644 linden/indra/llmedia/llmediaobserver.h delete mode 100644 linden/indra/llmedia/llmediaobservers.h delete mode 100644 linden/indra/llmessage/llcallbacklisth.h create mode 100644 linden/indra/llrender/llglimmediate.cpp create mode 100644 linden/indra/llrender/llglimmediate.h create mode 100644 linden/indra/llrender/llrendertarget.cpp create mode 100644 linden/indra/llrender/llrendertarget.h create mode 100644 linden/indra/llui/llmultislider.cpp create mode 100644 linden/indra/llui/llmultislider.h create mode 100644 linden/indra/llui/llmultisliderctrl.cpp create mode 100644 linden/indra/llui/llmultisliderctrl.h create mode 100644 linden/indra/llui/lluifwd.h delete mode 100644 linden/indra/llwindow/llglstubs.h create mode 100644 linden/indra/newview/app_settings/high_graphics.xml create mode 100644 linden/indra/newview/app_settings/low_graphics.xml create mode 100644 linden/indra/newview/app_settings/mid_graphics.xml create mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/glowF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/glowV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/environment/glowF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/environment/glowV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/environment/groundF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/environment/groundV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/environment/scatterF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/environment/scatterV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/objects/alphaF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/objects/alphaV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/objects/bumpshinyF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class1/objects/bumpshinyV.glsl create mode 100755 linden/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl create mode 100755 linden/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl create mode 100755 linden/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl create mode 100755 linden/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl create mode 100755 linden/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl create mode 100755 linden/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/avatar/avatarV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/effects/blurF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/effects/blurV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/effects/extractF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl create mode 100755 linden/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/environment/waterV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/objects/alphaF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/objects/alphaV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/objects/bumpshinyF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class2/objects/bumpshinyV.glsl create mode 100755 linden/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/environment/waterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl delete mode 100644 linden/indra/newview/app_settings/shaders/class3/objects/bumpshinyF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/shader_heirarchy.txt create mode 100644 linden/indra/newview/app_settings/ultra_graphics.xml create mode 100644 linden/indra/newview/app_settings/windlight/clouds2.tga create mode 100644 linden/indra/newview/app_settings/windlight/days/Default.xml create mode 100644 linden/indra/newview/app_settings/windlight/postprocesseffects.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/A%2D12AM.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/A%2D12PM.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/A%2D3AM.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/A%2D3PM.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/A%2D6AM.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/A%2D6PM.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/A%2D9AM.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/A%2D9PM.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Barcelona.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Blizzard.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Blue%20Midday.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Default.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Fine%20Day.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Foggy.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Funky%20Funky.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Gelatto.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Ghost.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Midday%201.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Midday%202.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Midday%203.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Midday%204.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Night.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Pirate.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Purple.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml create mode 100644 linden/indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml create mode 100644 linden/indra/newview/app_settings/windlight/water/Default.xml create mode 100644 linden/indra/newview/app_settings/windlight/water/Glassy.xml create mode 100644 linden/indra/newview/app_settings/windlight/water/Murky.xml create mode 100644 linden/indra/newview/app_settings/windlight/water/Pond.xml create mode 100644 linden/indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml create mode 100644 linden/indra/newview/app_settings/windlight/water/Second%20Plague.xml create mode 100644 linden/indra/newview/app_settings/windlight/water/Valdez.xml delete mode 100644 linden/indra/newview/llanimalcontrols.cpp delete mode 100644 linden/indra/newview/llanimalcontrols.h delete mode 100644 linden/indra/newview/llcape.cpp delete mode 100644 linden/indra/newview/llcape.h delete mode 100644 linden/indra/newview/lldrawpoolstars.cpp delete mode 100644 linden/indra/newview/lldrawpoolstars.h create mode 100644 linden/indra/newview/lldrawpoolwlsky.cpp create mode 100644 linden/indra/newview/lldrawpoolwlsky.h create mode 100644 linden/indra/newview/llfloaterdaycycle.cpp create mode 100644 linden/indra/newview/llfloaterdaycycle.h create mode 100644 linden/indra/newview/llfloaterenvsettings.cpp create mode 100644 linden/indra/newview/llfloaterenvsettings.h create mode 100644 linden/indra/newview/llfloaterhardwaresettings.cpp create mode 100644 linden/indra/newview/llfloaterhardwaresettings.h create mode 100644 linden/indra/newview/llfloaterhtmlhelp.cpp create mode 100644 linden/indra/newview/llfloaterhtmlhelp.h delete mode 100644 linden/indra/newview/llfloaterimport.cpp delete mode 100644 linden/indra/newview/llfloaterimport.h create mode 100644 linden/indra/newview/llfloaterpostprocess.cpp create mode 100644 linden/indra/newview/llfloaterpostprocess.h delete mode 100644 linden/indra/newview/llfloatersaveavatar.cpp delete mode 100644 linden/indra/newview/llfloatersaveavatar.h create mode 100644 linden/indra/newview/llfloaterurlentry.cpp create mode 100644 linden/indra/newview/llfloaterurlentry.h create mode 100644 linden/indra/newview/llfloaterwater.cpp create mode 100644 linden/indra/newview/llfloaterwater.h create mode 100644 linden/indra/newview/llfloaterwindlight.cpp create mode 100644 linden/indra/newview/llfloaterwindlight.h delete mode 100644 linden/indra/newview/llhudconnector.cpp delete mode 100644 linden/indra/newview/llhudconnector.h delete mode 100644 linden/indra/newview/lllocalanimationobject.cpp delete mode 100644 linden/indra/newview/lllocalanimationobject.h create mode 100644 linden/indra/newview/llmimetypes.cpp create mode 100644 linden/indra/newview/llmimetypes.h create mode 100644 linden/indra/newview/llpanellandmedia.cpp create mode 100644 linden/indra/newview/llpanellandmedia.h create mode 100644 linden/indra/newview/llparcelselection.cpp create mode 100644 linden/indra/newview/llparcelselection.h create mode 100644 linden/indra/newview/llpostprocess.cpp create mode 100644 linden/indra/newview/llpostprocess.h delete mode 100644 linden/indra/newview/llroam.cpp delete mode 100644 linden/indra/newview/llroam.h create mode 100644 linden/indra/newview/llurlhistory.cpp create mode 100644 linden/indra/newview/llurlhistory.h delete mode 100644 linden/indra/newview/llviewerjointshape.cpp delete mode 100644 linden/indra/newview/llviewerjointshape.h create mode 100644 linden/indra/newview/llviewermedia.cpp create mode 100644 linden/indra/newview/llviewermedia.h create mode 100644 linden/indra/newview/llviewerparcelmedia.cpp create mode 100644 linden/indra/newview/llviewerparcelmedia.h create mode 100644 linden/indra/newview/llviewerparcelmediaautoplay.cpp create mode 100644 linden/indra/newview/llviewerparcelmediaautoplay.h delete mode 100644 linden/indra/newview/llvostars.cpp delete mode 100644 linden/indra/newview/llvostars.h create mode 100644 linden/indra/newview/llvowlsky.cpp create mode 100644 linden/indra/newview/llvowlsky.h create mode 100644 linden/indra/newview/llwaterparammanager.cpp create mode 100644 linden/indra/newview/llwaterparammanager.h create mode 100644 linden/indra/newview/llwaterparamset.cpp create mode 100644 linden/indra/newview/llwaterparamset.h create mode 100644 linden/indra/newview/llwlanimator.cpp create mode 100644 linden/indra/newview/llwlanimator.h create mode 100644 linden/indra/newview/llwldaycycle.cpp create mode 100644 linden/indra/newview/llwldaycycle.h create mode 100644 linden/indra/newview/llwlparammanager.cpp create mode 100644 linden/indra/newview/llwlparammanager.h create mode 100644 linden/indra/newview/llwlparamset.cpp create mode 100644 linden/indra/newview/llwlparamset.h create mode 100644 linden/indra/newview/secondlife setup build aruna.bat create mode 100644 linden/indra/newview/secondlife setup build firstlookwindlight.bat create mode 100644 linden/indra/newview/secondlife setup build mitra.bat create mode 100644 linden/indra/newview/secondlife setup build mohini.bat create mode 100644 linden/indra/newview/secondlife setup build nandi.bat create mode 100644 linden/indra/newview/secondlife setup build radha.bat create mode 100644 linden/indra/newview/secondlife setup build ravi.bat create mode 100644 linden/indra/newview/skins/xui/en-us/floater_day_cycle_options.xml create mode 100644 linden/indra/newview/skins/xui/en-us/floater_env_settings.xml create mode 100644 linden/indra/newview/skins/xui/en-us/floater_hardware_settings.xml create mode 100644 linden/indra/newview/skins/xui/en-us/floater_media_browser.xml create mode 100644 linden/indra/newview/skins/xui/en-us/floater_post_process.xml create mode 100644 linden/indra/newview/skins/xui/en-us/floater_url_entry.xml create mode 100644 linden/indra/newview/skins/xui/en-us/floater_water.xml create mode 100644 linden/indra/newview/skins/xui/en-us/floater_windlight_options.xml create mode 100644 linden/indra/newview/skins/xui/en-us/mime_types.xml delete mode 100644 linden/indra/newview/skins/xui/en-us/panel_preferences_graphics2.xml delete mode 100644 linden/indra/newview/skins/xui/en-us/panel_preferences_graphics3.xml create mode 100755 linden/libraries/include/glh/glh_linear.h delete mode 100644 linden/libraries/include/llmozlib.h create mode 100644 linden/libraries/include/llmozlib2.h diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index d35e2aa..8606ad8 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt @@ -8,6 +8,9 @@ Able Whitman VWR-650 VWR-1460 VWR-1691 +Aimee Trescothick + VWR-3903 + VWR-4803 Alejandro Rosenthal VWR-1184 Alissa Sabre @@ -33,6 +36,7 @@ Alissa Sabre VWR-1410 VWR-2116 VWR-2826 + VWR-3290 VWR-4010 VWR-3410 Angus Boyd @@ -44,9 +48,12 @@ Balp Allen Benja Kepler VWR-746 Blakar Ogre + VWR-418 VWR-881 + VWR-983 VWR-1612 VWR-1613 + VWR-2164 blino Nakamura VWR-17 Boroondas Gupte @@ -55,6 +62,8 @@ Boroondas Gupte bushing Spatula VWR-119 VWR-424 +Carjay McGinnis + VWR-3737 Catherine Pfeffer VWR-1282 Dale Glass @@ -170,6 +179,9 @@ McCabe Maxsted Michelle2 Zenovka VWR-2652 VWR-2834 + VWR-3749 +Mm Alder + VWR-3777 Mr Greggan VWR-445 Nicholaz Beresford @@ -179,6 +191,7 @@ Nicholaz Beresford VWR-349 VWR-353 VWR-364 + VWR-374 VWR-546 VWR-691 VWR-727 diff --git a/linden/etc/message.xml b/linden/etc/message.xml index ddbfa58..bfbf1b1 100644 --- a/linden/etc/message.xml +++ b/linden/etc/message.xml @@ -357,6 +357,14 @@ trusted-sender true + + ParcelProperties + + flavor + llsd + trusted-sender + true + avatarnotesrequest @@ -431,6 +439,14 @@ trusted-sender false + + FetchInventoryDescendents + + flavor + llsd + trusted-sender + false + GroupProposalBallot @@ -514,7 +530,10 @@ SearchStatTracking false - + + ParcelPropertiesUpdate + false + messageBans diff --git a/linden/indra/SConstruct b/linden/indra/SConstruct index d06b5b6..1dfb980 100644 --- a/linden/indra/SConstruct +++ b/linden/indra/SConstruct @@ -14,7 +14,7 @@ # # Then build as follows: # -# scons BTARGET=client STANDALONE=yes MOZLIB=no ELFIO=no DISTCC=no +# scons BTARGET=client STANDALONE=yes MOZLIB2=no ELFIO=no DISTCC=no # # For help on options: # @@ -86,12 +86,12 @@ opts.AddOptions( EnumOption('BTARGET', 'Set build target', 'server', allowed_values=('client', 'server', 'all')), BoolOption('DISTCC', 'Enabled distcc', True), - BoolOption('MOZLIB', 'Enabled llmozlib/mozilla support', True), + BoolOption('MOZLIB2', 'Enabled llmozlib2/mozilla support', True), BoolOption('FMOD', 'Enabled FMOD audio support', True), BoolOption('GSTREAMER', 'Enabled GStreamer support', True), BoolOption('COLORGCC', 'Enabled colorgcc', True), EnumOption('GRID', 'Client package\'s default grid', 'default', - allowed_values=('default', 'aditi', 'agni', 'durga', 'ganga', 'shakti', 'siva', 'soma', 'uma', 'vaak', 'yami')), + allowed_values=('default', 'aditi', 'agni', 'durga', 'ganga', 'shakti', 'siva', 'soma', 'uma', 'vaak', 'yami', 'mohini', 'aruna', 'mitra', 'nandi', 'radha', 'ravi')), EnumOption('CHANNEL', 'Client package\'s default channel', 'Release', allowed_values=('Release', 'Release Candidate', 'WindLight')), BoolOption('ELFIO', 'Enabled enhanced backtraces with libELFIO symbol extraction support', True), @@ -106,7 +106,7 @@ build_param = optenv['BUILD'] arch = optenv['ARCH'] target_param = optenv['BTARGET'] enable_distcc = optenv['DISTCC'] -enable_mozlib = optenv['MOZLIB'] +enable_mozlib = optenv['MOZLIB2'] enable_gstreamer = optenv['GSTREAMER'] enable_colorgcc = optenv['COLORGCC'] grid = optenv['GRID'] @@ -286,8 +286,9 @@ for build_target in targets: if standalone: include_dirs += [d[2:] for d in pkgconfig('--cflags-only-I').split()] + client_external_libs += [ 'boost_regex' ] else: - client_external_libs += [ 'gtk-x11-2.0', 'atk-1.0', 'gmodule-2.0', 'gdk-x11-2.0', 'gdk_pixbuf-2.0', 'pango-1.0', 'pangoft2-1.0', 'pangox-1.0', 'pangoxft-1.0', 'Xinerama' ] + client_external_libs += [ 'gtk-x11-2.0', 'atk-1.0', 'gmodule-2.0', 'gdk-x11-2.0', 'gdk_pixbuf-2.0', 'pango-1.0', 'pangoft2-1.0', 'pangox-1.0', 'pangoxft-1.0', 'Xinerama' , 'boost_regex'] incdirs = [ 'ELFIO', 'atk-1.0', 'glib-2.0', 'gtk-2.0', 'llfreetype2', 'pango-1.0' ] include_dirs += ['../libraries/' + system_str + '/include/' + d @@ -298,13 +299,13 @@ for build_target in targets: else: cppflags += '-DLL_ELFBIN=0 ' - # llmozlib stuff + # llmozlib2 stuff if enable_mozlib: - cppflags += '-DLL_LIBXUL_ENABLED=1 ' - client_external_libs += [ 'llmozlib' ] - client_external_libs += [ 'mozjs', 'nspr4', 'plc4', 'plds4', 'profdirserviceprovider_s', 'xpcom', 'xul' ] + cppflags += '-DLL_LLMOZLIB_ENABLED=1 ' + client_external_libs += [ 'llmozlib2' ] + client_external_libs += [ 'mozjs', 'nspr4', 'plc4', 'plds4', 'profdirserviceprovider_s', 'xul' ] else: - cppflags += '-DLL_LIBXUL_ENABLED=0 ' + cppflags += '-DLL_LLMOZLIB_ENABLED=0 ' # GStreamer stuff if enable_gstreamer: @@ -437,13 +438,16 @@ for build_target in targets: ### Distributed build hosts ### if enable_distcc: - hosts = [ 'localhost/2', ] - if arch == 'i686': - dead = [] - stations = [s for s in xrange(36) if s not in dead] - random.shuffle(stations) - hosts += ['station%d.lindenlab.com/2,lzo' % s for s in stations] - hosts = ' '.join(hosts) + if 'DISTCC_HOSTS' in os.environ: + hosts = os.environ['DISTCC_HOSTS'] + else: + hosts = [ 'localhost/2', ] + if arch == 'i686': + dead = [] + stations = [s for s in xrange(36) if s not in dead] + random.shuffle(stations) + hosts += ['station%d.lindenlab.com/2,lzo' % s for s in stations] + hosts = ' '.join(hosts) print "Distributing to hosts: " + hosts env['ENV']['DISTCC_HOSTS'] = hosts env['ENV']['USER'] = os.environ['USER'] diff --git a/linden/indra/indra_complete/indra_complete.sln b/linden/indra/indra_complete/indra_complete.sln index 83dbdc5..b9efa5a 100644 --- a/linden/indra/indra_complete/indra_complete.sln +++ b/linden/indra/indra_complete/indra_complete.sln @@ -243,6 +243,8 @@ Global ReleaseForDownload = ReleaseForDownload ReleaseNoOpt = ReleaseNoOpt EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {7BCB4B2C-8378-4186-88EA-5742B5ABE17F}.Debug.ActiveCfg = Debug|Win32 {7BCB4B2C-8378-4186-88EA-5742B5ABE17F}.Debug.Build.0 = Debug|Win32 diff --git a/linden/indra/indra_complete/indra_complete_vc8.sln b/linden/indra/indra_complete/indra_complete_vc8.sln index 372ea06..f00d16b 100644 --- a/linden/indra/indra_complete/indra_complete_vc8.sln +++ b/linden/indra/indra_complete/indra_complete_vc8.sln @@ -391,7 +391,6 @@ Global {D0FDC1C3-A589-40F2-ABCA-A84FF3835624}.ReleaseForDownload|Win32.ActiveCfg = Release|Win32 {D0FDC1C3-A589-40F2-ABCA-A84FF3835624}.ReleaseForDownload|Win32.Build.0 = Release|Win32 {D0FDC1C3-A589-40F2-ABCA-A84FF3835624}.ReleaseNoOpt|Win32.ActiveCfg = ReleaseNoOpt|Win32 - {D0FDC1C3-A589-40F2-ABCA-A84FF3835624}.ReleaseNoOpt|Win32.Build.0 = ReleaseNoOpt|Win32 {C6CA76F5-DCB4-4789-BBA7-43D11EE7C8E2}.Debug|Win32.ActiveCfg = Debug|Win32 {C6CA76F5-DCB4-4789-BBA7-43D11EE7C8E2}.Debug|Win32.Build.0 = Debug|Win32 {C6CA76F5-DCB4-4789-BBA7-43D11EE7C8E2}.DebugMesaHeadless|Win32.ActiveCfg = Debug|Win32 @@ -401,7 +400,6 @@ Global {C6CA76F5-DCB4-4789-BBA7-43D11EE7C8E2}.ReleaseForDownload|Win32.ActiveCfg = Release|Win32 {C6CA76F5-DCB4-4789-BBA7-43D11EE7C8E2}.ReleaseForDownload|Win32.Build.0 = Release|Win32 {C6CA76F5-DCB4-4789-BBA7-43D11EE7C8E2}.ReleaseNoOpt|Win32.ActiveCfg = ReleaseNoOpt|Win32 - {C6CA76F5-DCB4-4789-BBA7-43D11EE7C8E2}.ReleaseNoOpt|Win32.Build.0 = ReleaseNoOpt|Win32 {A5504A1E-8BA4-45D2-8144-1B6937E37E98}.Debug|Win32.ActiveCfg = Debug|Win32 {A5504A1E-8BA4-45D2-8144-1B6937E37E98}.Debug|Win32.Build.0 = Debug|Win32 {A5504A1E-8BA4-45D2-8144-1B6937E37E98}.DebugMesaHeadless|Win32.ActiveCfg = Debug|Win32 @@ -411,7 +409,6 @@ Global {A5504A1E-8BA4-45D2-8144-1B6937E37E98}.ReleaseForDownload|Win32.ActiveCfg = Release|Win32 {A5504A1E-8BA4-45D2-8144-1B6937E37E98}.ReleaseForDownload|Win32.Build.0 = Release|Win32 {A5504A1E-8BA4-45D2-8144-1B6937E37E98}.ReleaseNoOpt|Win32.ActiveCfg = ReleaseNoOpt|Win32 - {A5504A1E-8BA4-45D2-8144-1B6937E37E98}.ReleaseNoOpt|Win32.Build.0 = ReleaseNoOpt|Win32 {777F38BE-2DFE-4051-9AAD-2832ABC474CC}.Debug|Win32.ActiveCfg = Debug|Win32 {777F38BE-2DFE-4051-9AAD-2832ABC474CC}.Debug|Win32.Build.0 = Debug|Win32 {777F38BE-2DFE-4051-9AAD-2832ABC474CC}.DebugMesaHeadless|Win32.ActiveCfg = Debug|Win32 diff --git a/linden/indra/lib/python/indra/base/config.py b/linden/indra/lib/python/indra/base/config.py index eea733a..3865f5e 100644 --- a/linden/indra/lib/python/indra/base/config.py +++ b/linden/indra/lib/python/indra/base/config.py @@ -47,6 +47,25 @@ def load(indra_xml_file=None): config_file.close() #print "loaded config from",indra_xml_file,"into",_g_config_dict +def dump(indra_xml_file, indra_cfg={}, update_in_mem=False): + ''' + Dump config contents into a file + Kindof reverse of load. + Optionally takes a new config to dump. + Does NOT update global config unless requested. + ''' + global _g_config_dict + if not indra_cfg: + indra_cfg = _g_config_dict + if not indra_cfg: + return + config_file = open(indra_xml_file, 'w') + _config_xml = llsd.format_xml(indra_cfg) + config_file.write(_config_xml) + config_file.close() + if update_in_mem: + update(indra_cfg) + def update(new_conf): """Load an XML file and apply its map as overrides or additions to the existing config. The dataserver does this with indra.xml @@ -69,6 +88,12 @@ def get(key, default = None): load() return _g_config_dict.get(key, default) +def set(key, newval): + global _g_config_dict + if _g_config_dict == None: + load() + _g_config_dict[key] = newval + def as_dict(): global _g_config_dict return _g_config_dict diff --git a/linden/indra/lib/python/indra/base/lllog.py b/linden/indra/lib/python/indra/base/lllog.py new file mode 100644 index 0000000..99c50ef --- /dev/null +++ b/linden/indra/lib/python/indra/base/lllog.py @@ -0,0 +1,72 @@ +"""\ +@file lllog.py +@brief Logging for event processing + +$LicenseInfo:firstyear=2008&license=mit$ + +Copyright (c) 2008, 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$ +""" + +from indra.base.llsd import format_notation + +try: + import syslog +except ImportError: + # Windows + import sys + + class syslog(object): + _logfp = sys.stderr + + def syslog(msg): + _logfp.write(msg) + if not msg.endswith('\n'): + _logfp.write('\n') + + syslog = staticmethod(syslog) + +class Logger(object): + def __init__(self, name='indra'): + self._sequence = 0 + try: + syslog.openlog(name, syslog.LOG_CONS | syslog.LOG_PID, + syslog.LOG_LOCAL0) + except AttributeError: + # No syslog module on Windows + pass + + def next(self): + self._sequence += 1 + return self._sequence + + def log(self, msg, llsd): + payload = 'LLLOGMESSAGE (%d) %s %s' % (self.next(), msg, + format_notation(llsd)) + syslog.syslog(payload) + +_logger = None + +def log(msg, llsd): + global _logger + if _logger is None: + _logger = Logger() + _logger.log(msg, llsd) diff --git a/linden/indra/lib/python/indra/base/lluuid.py b/linden/indra/lib/python/indra/base/lluuid.py index f173310..dd336f0 100644 --- a/linden/indra/lib/python/indra/base/lluuid.py +++ b/linden/indra/lib/python/indra/base/lluuid.py @@ -227,16 +227,31 @@ def printTranslatedMemory(four_hex_uints): uuid.setFromMemoryDump(four_hex_uints) print uuid.toString() -def isPossiblyID(id_str): +def isUUID(id_str): """ - This function returns 1 if the string passed has some uuid-like - characteristics. Otherwise returns 0. + This function returns: + - 1 if the string passed is a UUID + - 0 is the string passed is not a UUID + - None if it neither of the if's below is satisfied """ if not id_str or len(id_str) < 5 or len(id_str) > 36: return 0 if isinstance(id_str, UUID) or UUID.uuid_regex.match(id_str): return 1 + + return None + +def isPossiblyID(id_str): + """ + This function returns 1 if the string passed has some uuid-like + characteristics. Otherwise returns 0. + """ + + is_uuid = isUUID(id_str) + if is_uuid is not None: + return is_uuid + # build a string which matches every character. hex_wildcard = r"[0-9a-fA-F]" chars = len(id_str) diff --git a/linden/indra/lib/python/indra/base/metrics.py b/linden/indra/lib/python/indra/base/metrics.py index e640c45..04e6286 100644 --- a/linden/indra/lib/python/indra/base/metrics.py +++ b/linden/indra/lib/python/indra/base/metrics.py @@ -31,12 +31,23 @@ $/LicenseInfo$ import sys from indra.base import llsd -def log(location, stats, file=None): - "Write a standard llmetrics log" - metrics = {'location':location, 'stats':stats} - if file is None: +_sequence_id = 0 + +def record_metrics(table, stats, dest=None): + "Write a standard metrics log" + _log("LLMETRICS", table, stats, dest) + +def record_event(table, data, dest=None): + "Write a standard logmessage log" + _log("LLLOGMESSAGE", table, data, dest) + +def _log(header, table, data, dest): + if dest is None: # do this check here in case sys.stdout changes at some # point. as a default parameter, it will never be # re-evaluated. - file = sys.stdout - print >>file, "LLMETRICS:", llsd.format_notation(metrics) + dest = sys.stdout + global _sequence_id + print >>dest, header, "(" + str(_sequence_id) + ")", + print >>dest, table, llsd.format_notation(data) + _sequence_id += 1 diff --git a/linden/indra/lib/python/indra/ipc/mysql_pool.py b/linden/indra/lib/python/indra/ipc/mysql_pool.py index 0a06cdd..01e31bb 100644 --- a/linden/indra/lib/python/indra/ipc/mysql_pool.py +++ b/linden/indra/lib/python/indra/ipc/mysql_pool.py @@ -64,12 +64,13 @@ connection pools keyed on host,databasename""" else: return self._credentials.get('default', None) - def get(self, host, dbname): - key = (host, dbname) + def get(self, host, dbname, port=3306): + key = (host, dbname, port) if key not in self._databases: new_kwargs = self._kwargs.copy() new_kwargs['db'] = dbname new_kwargs['host'] = host + new_kwargs['port'] = port new_kwargs.update(self.credentials_for(host)) dbpool = ConnectionPool(self._min_size, self._max_size, *self._args, **new_kwargs) self._databases[key] = dbpool diff --git a/linden/indra/lib/python/indra/ipc/russ.py b/linden/indra/lib/python/indra/ipc/russ.py index a198acf..fbb1777 100644 --- a/linden/indra/lib/python/indra/ipc/russ.py +++ b/linden/indra/lib/python/indra/ipc/russ.py @@ -136,7 +136,15 @@ def _build_query_string(query_dict): @returns Returns an urlencoded query string including leading '?'. """ if query_dict: - return '?' + urllib.urlencode(query_dict) + keys = query_dict.keys() + keys.sort() + def stringize(value): + if type(value) in (str,unicode): + return value + else: + return str(value) + query_list = [urllib.quote(str(key)) + '=' + urllib.quote(stringize(query_dict[key])) for key in keys] + return '?' + '&'.join(query_list) else: return '' diff --git a/linden/indra/lib/python/indra/util/llsubprocess.py b/linden/indra/lib/python/indra/util/llsubprocess.py new file mode 100644 index 0000000..1c107d9 --- /dev/null +++ b/linden/indra/lib/python/indra/util/llsubprocess.py @@ -0,0 +1,106 @@ +"""\ +@file llsubprocess.py +@author Phoenix +@date 2008-01-18 +@brief The simplest possible wrapper for a common sub-process paradigm. + +$LicenseInfo:firstyear=2007&license=mit$ + +Copyright (c) 2007-2008, 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 os +import popen2 +import time +import select + +class Timeout(RuntimeError): + "Exception raised when a subprocess times out." + pass + +def run(command, args=None, data=None, timeout=None): + """\ +@brief Run command with arguments + +This is it. This is the function I want to run all the time when doing +subprocces, but end up copying the code everywhere. none of the +standard commands are secure and provide a way to specify input, get +all the output, and get the result. +@param command A string specifying a process to launch. +@param args Arguments to be passed to command. Must be list, tuple or None. +@param data input to feed to the command. +@param timeout Maximum number of many seconds to run. +@return Returns (result, stdout, stderr) from process. +""" + cmd = [command] + if args: + cmd.extend([str(arg) for arg in args]) + #print "cmd: ","' '".join(cmd) + child = popen2.Popen3(cmd, True) + #print child.pid + out = [] + err = [] + result = -1 + time_left = timeout + tochild = [child.tochild.fileno()] + while True: + time_start = time.time() + #print "time:",time_left + p_in, p_out, p_err = select.select( + [child.fromchild.fileno(), child.childerr.fileno()], + tochild, + [], + time_left) + if p_in: + new_line = os.read(child.fromchild.fileno(), 32 * 1024) + if new_line: + #print "line:",new_line + out.append(new_line) + new_line = os.read(child.childerr.fileno(), 32 * 1024) + if new_line: + #print "error:", new_line + err.append(new_line) + if p_out: + if data: + #print "p_out" + bytes = os.write(child.tochild.fileno(), data) + data = data[bytes:] + if len(data) == 0: + data = None + tochild = [] + child.tochild.close() + result = child.poll() + if result != -1: + child.tochild.close() + child.fromchild.close() + child.childerr.close() + break + if time_left is not None: + time_left -= (time.time() - time_start) + if time_left < 0: + raise Timeout + #print "result:",result + out = ''.join(out) + #print "stdout:", out + err = ''.join(err) + #print "stderr:", err + return result, out, err diff --git a/linden/indra/lib/python/indra/util/named_query.py b/linden/indra/lib/python/indra/util/named_query.py index c462d9f..c52bfde 100644 --- a/linden/indra/lib/python/indra/util/named_query.py +++ b/linden/indra/lib/python/indra/util/named_query.py @@ -495,9 +495,51 @@ class _RewriteQueryForArray(object): if type(value) in (list,tuple): rv = [] for idx in range(len(value)): - new_key = "_" + key + "_" + str(idx) - self.new_params[new_key] = value[idx] - rv.append("%(" + new_key + ")s") + # if the value@idx is array-like, we are + # probably dealing with a VALUES + new_key = "_%s_%s"%(key, str(idx)) + val_item = value[idx] + if type(val_item) in (list, tuple, dict): + if type(val_item) is dict: + # this is because in Python, the order of + # key, value retrieval from the dict is not + # guaranteed to match what the input intended + # and for VALUES, order is important. + # TODO: Implemented ordered dict in LLSD parser? + raise ExpectationFailed('Only lists/tuples allowed,\ + received dict') + values_keys = [] + for value_idx, item in enumerate(val_item): + # we want a key of the format : + # key_#replacement_#value_row_#value_col + # ugh... so if we are replacing 10 rows in user_note, + # the first values clause would read (for @:user_notes) :- + # ( :_user_notes_0_1_1, :_user_notes_0_1_2, :_user_notes_0_1_3 ) + # the input LLSD for VALUES will look like: + # ... + # + # user_notes + # + # + # ... + # ... + # ... + # + # ... + # + # + # ... + values_key = "%s_%s"%(new_key, value_idx) + self.new_params[values_key] = item + values_keys.append("%%(%s)s"%values_key) + # now collapse all these new place holders enclosed in () + # from [':_key_0_1_1', ':_key_0_1_2', ':_key_0_1_3,...] + # rv will have [ '(:_key_0_1_1, :_key_0_1_2, :_key_0_1_3)', ] + # which is flattened a few lines below join(rv) + rv.append('(%s)' % ','.join(values_keys)) + else: + self.new_params[new_key] = val_item + rv.append("%%(%s)s"%new_key) return ','.join(rv) else: # not something that can be expanded, so just drop the diff --git a/linden/indra/lib/python/indra/util/shutil2.py b/linden/indra/lib/python/indra/util/shutil2.py new file mode 100644 index 0000000..2c504c2 --- /dev/null +++ b/linden/indra/lib/python/indra/util/shutil2.py @@ -0,0 +1,84 @@ +''' +@file shutil2.py +@brief a better shutil.copytree replacement + +$LicenseInfo:firstyear=2007&license=mit$ + +Copyright (c) 2007-2008, 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$ +''' + +# +# shutil2.py +# Taken from http://www.scons.org/wiki/AccumulateBuilder +# the stock copytree sucks because it insists that the +# target dir not exist +# + +import os.path +import shutil + +def copytree(src, dest, symlinks=False): + """My own copyTree which does not fail if the directory exists. + + Recursively copy a directory tree using copy2(). + + If the optional symlinks flag is true, symbolic links in the + source tree result in symbolic links in the destination tree; if + it is false, the contents of the files pointed to by symbolic + links are copied. + + Behavior is meant to be identical to GNU 'cp -R'. + """ + def copyItems(src, dest, symlinks=False): + """Function that does all the work. + + It is necessary to handle the two 'cp' cases: + - destination does exist + - destination does not exist + + See 'cp -R' documentation for more details + """ + for item in os.listdir(src): + srcPath = os.path.join(src, item) + if os.path.isdir(srcPath): + srcBasename = os.path.basename(srcPath) + destDirPath = os.path.join(dest, srcBasename) + if not os.path.exists(destDirPath): + os.makedirs(destDirPath) + copyItems(srcPath, destDirPath) + elif os.path.islink(item) and symlinks: + linkto = os.readlink(item) + os.symlink(linkto, dest) + else: + shutil.copy2(srcPath, dest) + + # case 'cp -R src/ dest/' where dest/ already exists + if os.path.exists(dest): + destPath = os.path.join(dest, os.path.basename(src)) + if not os.path.exists(destPath): + os.makedirs(destPath) + # case 'cp -R src/ dest/' where dest/ does not exist + else: + os.makedirs(dest) + destPath = dest + # actually copy the files + copyItems(src, destPath) diff --git a/linden/indra/llaudio/llaudio_vc8.vcproj b/linden/indra/llaudio/llaudio_vc8.vcproj index 6ca3e67..6cfe76c 100644 --- a/linden/indra/llaudio/llaudio_vc8.vcproj +++ b/linden/indra/llaudio/llaudio_vc8.vcproj @@ -1,323 +1,323 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llaudio/llaudio_vc9.vcproj b/linden/indra/llaudio/llaudio_vc9.vcproj index a1a8d91..e51623c 100644 --- a/linden/indra/llaudio/llaudio_vc9.vcproj +++ b/linden/indra/llaudio/llaudio_vc9.vcproj @@ -1,324 +1,324 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llcharacter/llcharacter.cpp b/linden/indra/llcharacter/llcharacter.cpp index af4c5aa..0339cf0 100644 --- a/linden/indra/llcharacter/llcharacter.cpp +++ b/linden/indra/llcharacter/llcharacter.cpp @@ -241,33 +241,15 @@ void LLCharacter::dumpCharacter( LLJoint* joint ) //----------------------------------------------------------------------------- void LLCharacter::setAnimationData(std::string name, void *data) { - if(mAnimationData.getValue(name)) - { - *mAnimationData[name] = data; - } - else - { - mAnimationData.addToHead(name, data); - } + mAnimationData[name] = data; } //----------------------------------------------------------------------------- // getAnimationData() //----------------------------------------------------------------------------- -void * LLCharacter::getAnimationData(std::string name) +void* LLCharacter::getAnimationData(std::string name) { - void **result = mAnimationData.getValue(name); - void *return_value; // Necessary to suppress VC6 warning. JC - if (!result) - { - return_value = NULL; - } - else - { - return_value = *result; - } - - return return_value; + return get_if_there(mAnimationData, name, (void*)NULL); } //----------------------------------------------------------------------------- @@ -275,7 +257,7 @@ void * LLCharacter::getAnimationData(std::string name) //----------------------------------------------------------------------------- void LLCharacter::removeAnimationData(std::string name) { - mAnimationData.remove(name); + mAnimationData.erase(name); } //----------------------------------------------------------------------------- diff --git a/linden/indra/llcharacter/llcharacter.h b/linden/indra/llcharacter/llcharacter.h index 6699796..46faab1 100644 --- a/linden/indra/llcharacter/llcharacter.h +++ b/linden/indra/llcharacter/llcharacter.h @@ -39,9 +39,7 @@ #include "lljoint.h" #include "llmotioncontroller.h" -#include "llassoclist.h" #include "llvisualparam.h" -#include "linked_lists.h" #include "string_table.h" #include "llmemory.h" #include "llthread.h" @@ -255,7 +253,8 @@ public: protected: LLMotionController mMotionController; - LLAssocList mAnimationData; + typedef std::map animation_data_map_t; + animation_data_map_t mAnimationData; F32 mPreferredPelvisHeight; ESex mSex; diff --git a/linden/indra/llcharacter/llcharacter_vc8.vcproj b/linden/indra/llcharacter/llcharacter_vc8.vcproj index 00ceb88..fdad9c2 100644 --- a/linden/indra/llcharacter/llcharacter_vc8.vcproj +++ b/linden/indra/llcharacter/llcharacter_vc8.vcproj @@ -1,419 +1,419 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llcharacter/llcharacter_vc9.vcproj b/linden/indra/llcharacter/llcharacter_vc9.vcproj index 13e3b14..837ec04 100644 --- a/linden/indra/llcharacter/llcharacter_vc9.vcproj +++ b/linden/indra/llcharacter/llcharacter_vc9.vcproj @@ -1,420 +1,420 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llcharacter/llkeyframemotion.cpp b/linden/indra/llcharacter/llkeyframemotion.cpp index 4288b8d..0138860 100644 --- a/linden/indra/llcharacter/llkeyframemotion.cpp +++ b/linden/indra/llcharacter/llkeyframemotion.cpp @@ -122,6 +122,7 @@ U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo() //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- // ScaleCurve::ScaleCurve() //----------------------------------------------------------------------------- @@ -136,7 +137,7 @@ LLKeyframeMotion::ScaleCurve::ScaleCurve() //----------------------------------------------------------------------------- LLKeyframeMotion::ScaleCurve::~ScaleCurve() { - mKeys.deleteAllData(); + mKeys.clear(); mNumKeys = 0; } @@ -146,43 +147,42 @@ LLKeyframeMotion::ScaleCurve::~ScaleCurve() LLVector3 LLKeyframeMotion::ScaleCurve::getValue(F32 time, F32 duration) { LLVector3 value; - F32 index_before, index_after; - ScaleKey* scale_before; - ScaleKey* scale_after; - mKeys.getInterval(time, index_before, index_after, scale_before, scale_after); - if (scale_before) + if (mKeys.empty()) { - if (!scale_after) - { - scale_after = &mLoopInKey; - index_after = duration; - } - - if (index_after == index_before) - { - value = scale_after->mScale; - } - else - { - F32 u = (time - index_before) / (index_after - index_before); - value = interp(u, *scale_before, *scale_after); - } + value.clearVec(); + return value; + } + + key_map_t::iterator right = mKeys.lower_bound(time); + if (right == mKeys.end()) + { + // Past last key + --right; + value = right->second.mScale; + } + else if (right == mKeys.begin() || right->first == time) + { + // Before first key or exactly on a key + value = right->second.mScale; } else { - // before first key - if (scale_after) - { - value = scale_after->mScale; - } - // no keys? - else + // Between two keys + key_map_t::iterator left = right; --left; + F32 index_before = left->first; + F32 index_after = right->first; + ScaleKey& scale_before = left->second; + ScaleKey& scale_after = right->second; + if (right == mKeys.end()) { - value.clearVec(); + scale_after = mLoopInKey; + index_after = duration; } - } + F32 u = (time - index_before) / (index_after - index_before); + value = interp(u, scale_before, scale_after); + } return value; } @@ -217,7 +217,7 @@ LLKeyframeMotion::RotationCurve::RotationCurve() //----------------------------------------------------------------------------- LLKeyframeMotion::RotationCurve::~RotationCurve() { - mKeys.deleteAllData(); + mKeys.clear(); mNumKeys = 0; } @@ -227,44 +227,42 @@ LLKeyframeMotion::RotationCurve::~RotationCurve() LLQuaternion LLKeyframeMotion::RotationCurve::getValue(F32 time, F32 duration) { LLQuaternion value; - F32 index_before, index_after; - RotationKey* rot_before; - RotationKey* rot_after; - mKeys.getInterval(time, index_before, index_after, rot_before, rot_after); - - if (rot_before) + if (mKeys.empty()) { - if (!rot_after) - { - rot_after = &mLoopInKey; - index_after = duration; - } - - if (index_after == index_before) - { - value = rot_after->mRotation; - } - else - { - F32 u = (time - index_before) / (index_after - index_before); - value = interp(u, *rot_before, *rot_after); - } + value = LLQuaternion::DEFAULT; + return value; + } + + key_map_t::iterator right = mKeys.lower_bound(time); + if (right == mKeys.end()) + { + // Past last key + --right; + value = right->second.mRotation; + } + else if (right == mKeys.begin() || right->first == time) + { + // Before first key or exactly on a key + value = right->second.mRotation; } else { - // before first key - if (rot_after) + // Between two keys + key_map_t::iterator left = right; --left; + F32 index_before = left->first; + F32 index_after = right->first; + RotationKey& rot_before = left->second; + RotationKey& rot_after = right->second; + if (right == mKeys.end()) { - value = rot_after->mRotation; - } - // no keys? - else - { - value = LLQuaternion::DEFAULT; + rot_after = mLoopInKey; + index_after = duration; } - } + F32 u = (time - index_before) / (index_after - index_before); + value = interp(u, rot_before, rot_after); + } return value; } @@ -300,7 +298,7 @@ LLKeyframeMotion::PositionCurve::PositionCurve() //----------------------------------------------------------------------------- LLKeyframeMotion::PositionCurve::~PositionCurve() { - mKeys.deleteAllData(); + mKeys.clear(); mNumKeys = 0; } @@ -310,46 +308,45 @@ LLKeyframeMotion::PositionCurve::~PositionCurve() LLVector3 LLKeyframeMotion::PositionCurve::getValue(F32 time, F32 duration) { LLVector3 value; - F32 index_before, index_after; - PositionKey* pos_before; - PositionKey* pos_after; - - mKeys.getInterval(time, index_before, index_after, pos_before, pos_after); - if (pos_before) + if (mKeys.empty()) { - if (!pos_after) - { - pos_after = &mLoopInKey; - index_after = duration; - } - - if (index_after == index_before) - { - value = pos_after->mPosition; - } - else - { - F32 u = (time - index_before) / (index_after - index_before); - value = interp(u, *pos_before, *pos_after); - } + value.clearVec(); + return value; + } + + key_map_t::iterator right = mKeys.lower_bound(time); + if (right == mKeys.end()) + { + // Past last key + --right; + value = right->second.mPosition; + } + else if (right == mKeys.begin() || right->first == time) + { + // Before first key or exactly on a key + value = right->second.mPosition; } else { - // before first key - if (pos_after) + // Between two keys + key_map_t::iterator left = right; --left; + F32 index_before = left->first; + F32 index_after = right->first; + PositionKey& pos_before = left->second; + PositionKey& pos_after = right->second; + if (right == mKeys.end()) { - value = pos_after->mPosition; - } - // no keys? - else - { - value.clearVec(); + pos_after = mLoopInKey; + index_after = duration; } + + F32 u = (time - index_before) / (index_after - index_before); + value = interp(u, pos_before, pos_after); } llassert(value.isFinite()); - + return value; } @@ -1404,8 +1401,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) time = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); } - RotationKey *rot_key = new RotationKey; - rot_key->mTime = time; + RotationKey rot_key; + rot_key.mTime = time; LLVector3 rot_angles; U16 x, y, z; @@ -1416,7 +1413,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) success = dp.unpackVector3(rot_angles, "rot_angles"); LLQuaternion::Order ro = StringToOrder("ZYX"); - rot_key->mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro); + rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro); } else { @@ -1428,13 +1425,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f); rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f); rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f); - rot_key->mRotation.unpackFromVector3(rot_vec); + rot_key.mRotation.unpackFromVector3(rot_vec); } if (!success) { llwarns << "can't read rotation key (" << k << ")" << llendl; - delete rot_key; return FALSE; } @@ -1464,14 +1460,13 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) for (S32 k = 0; k < joint_motion->mPositionCurve.mNumKeys; k++) { U16 time_short; - PositionKey* pos_key = new PositionKey; + PositionKey pos_key; if (old_version) { - if (!dp.unpackF32(pos_key->mTime, "time")) + if (!dp.unpackF32(pos_key.mTime, "time")) { llwarns << "can't read position key (" << k << ")" << llendl; - delete pos_key; return FALSE; } } @@ -1480,18 +1475,17 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) if (!dp.unpackU16(time_short, "time")) { llwarns << "can't read position key (" << k << ")" << llendl; - delete pos_key; return FALSE; } - pos_key->mTime = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); + pos_key.mTime = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); } BOOL success = TRUE; if (old_version) { - success = dp.unpackVector3(pos_key->mPosition, "pos"); + success = dp.unpackVector3(pos_key.mPosition, "pos"); } else { @@ -1501,23 +1495,22 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp) success &= dp.unpackU16(y, "pos_y"); success &= dp.unpackU16(z, "pos_z"); - pos_key->mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - pos_key->mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - pos_key->mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + pos_key.mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + pos_key.mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + pos_key.mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); } if (!success) { llwarns << "can't read position key (" << k << ")" << llendl; - delete pos_key; return FALSE; } - pCurve->mKeys[pos_key->mTime] = pos_key; + pCurve->mKeys[pos_key.mTime] = pos_key; if (is_pelvis) { - mJointMotionList->mPelvisBBox.addPoint(pos_key->mPosition); + mJointMotionList->mPelvisBBox.addPoint(pos_key.mPosition); } } @@ -1724,14 +1717,14 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const success &= dp.packS32(joint_motionp->mPriority, "joint_priority"); success &= dp.packS32(joint_motionp->mRotationCurve.mNumKeys, "num_rot_keys"); - for (RotationKey* rot_keyp = joint_motionp->mRotationCurve.mKeys.getFirstData(); - rot_keyp; - rot_keyp = joint_motionp->mRotationCurve.mKeys.getNextData()) + for (RotationCurve::key_map_t::iterator iter = joint_motionp->mRotationCurve.mKeys.begin(); + iter != joint_motionp->mRotationCurve.mKeys.end(); ++iter) { - U16 time_short = F32_to_U16(rot_keyp->mTime, 0.f, mJointMotionList->mDuration); + RotationKey& rot_key = iter->second; + U16 time_short = F32_to_U16(rot_key.mTime, 0.f, mJointMotionList->mDuration); success &= dp.packU16(time_short, "time"); - LLVector3 rot_angles = rot_keyp->mRotation.packToVector3(); + LLVector3 rot_angles = rot_key.mRotation.packToVector3(); U16 x, y, z; rot_angles.quantize16(-1.f, 1.f, -1.f, 1.f); @@ -1744,18 +1737,18 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const } success &= dp.packS32(joint_motionp->mPositionCurve.mNumKeys, "num_pos_keys"); - for (PositionKey* pos_keyp = joint_motionp->mPositionCurve.mKeys.getFirstData(); - pos_keyp; - pos_keyp = joint_motionp->mPositionCurve.mKeys.getNextData()) + for (PositionCurve::key_map_t::iterator iter = joint_motionp->mPositionCurve.mKeys.begin(); + iter != joint_motionp->mPositionCurve.mKeys.end(); ++iter) { - U16 time_short = F32_to_U16(pos_keyp->mTime, 0.f, mJointMotionList->mDuration); + PositionKey& pos_key = iter->second; + U16 time_short = F32_to_U16(pos_key.mTime, 0.f, mJointMotionList->mDuration); success &= dp.packU16(time_short, "time"); U16 x, y, z; - pos_keyp->mPosition.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - x = F32_to_U16(pos_keyp->mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - y = F32_to_U16(pos_keyp->mPosition.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); - z = F32_to_U16(pos_keyp->mPosition.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + pos_key.mPosition.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + x = F32_to_U16(pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + y = F32_to_U16(pos_key.mPosition.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); + z = F32_to_U16(pos_key.mPosition.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); success &= dp.packU16(x, "pos_x"); success &= dp.packU16(y, "pos_y"); success &= dp.packU16(z, "pos_z"); @@ -2030,64 +2023,6 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, } } - -//----------------------------------------------------------------------------- -// writeCAL3D() -//----------------------------------------------------------------------------- -void LLKeyframeMotion::writeCAL3D(apr_file_t* fp) -{ -// -// -// -// 0 0 48.8332 -// 0.0512905 0.05657 0.66973 0.738668 -// -// -// - - apr_file_printf(fp, "\n", getDuration(), mJointMotionList->getNumJointMotions()); - for (U32 joint_index = 0; joint_index < mJointMotionList->getNumJointMotions(); joint_index++) - { - JointMotion* joint_motionp = mJointMotionList->getJointMotion(joint_index); - LLJoint* animated_joint = mCharacter->getJoint(joint_motionp->mJointName); - S32 joint_num = animated_joint->mJointNum + 1; - - apr_file_printf(fp, " \n", joint_num, joint_motionp->mRotationCurve.mNumKeys ); - PositionKey* pos_keyp = joint_motionp->mPositionCurve.mKeys.getFirstData(); - for (RotationKey* rot_keyp = joint_motionp->mRotationCurve.mKeys.getFirstData(); - rot_keyp; - rot_keyp = joint_motionp->mRotationCurve.mKeys.getNextData()) - { - apr_file_printf(fp, " \n", rot_keyp->mTime); - LLVector3 nominal_pos = animated_joint->getPosition(); - if (animated_joint->getParent()) - { - nominal_pos.scaleVec(animated_joint->getParent()->getScale()); - } - nominal_pos = nominal_pos * 100.f; - - if (joint_motionp->mUsage & LLJointState::POS && pos_keyp) - { - LLVector3 pos_val = pos_keyp->mPosition; - pos_val = pos_val * 100.f; - pos_val += nominal_pos; - apr_file_printf(fp, " %0.4f %0.4f %0.4f\n", pos_val.mV[VX], pos_val.mV[VY], pos_val.mV[VZ]); - pos_keyp = joint_motionp->mPositionCurve.mKeys.getNextData(); - } - else - { - apr_file_printf(fp, " %0.4f %0.4f %0.4f\n", nominal_pos.mV[VX], nominal_pos.mV[VY], nominal_pos.mV[VZ]); - } - - LLQuaternion rot_val = ~rot_keyp->mRotation; - apr_file_printf(fp, " %0.4f %0.4f %0.4f %0.4f\n", rot_val.mQ[VX], rot_val.mQ[VY], rot_val.mQ[VZ], rot_val.mQ[VW]); - apr_file_printf(fp, " \n"); - } - apr_file_printf(fp, " \n"); - } - apr_file_printf(fp, "\n"); -} - //-------------------------------------------------------------------- // LLKeyframeDataCache::dumpDiagInfo() //-------------------------------------------------------------------- diff --git a/linden/indra/llcharacter/llkeyframemotion.h b/linden/indra/llcharacter/llkeyframemotion.h index 0ad0181..5f897cf 100644 --- a/linden/indra/llcharacter/llkeyframemotion.h +++ b/linden/indra/llcharacter/llkeyframemotion.h @@ -43,7 +43,6 @@ #include "llhandmotion.h" #include "lljointstate.h" #include "llmotion.h" -#include "llptrskipmap.h" #include "llquaternion.h" #include "v3dmath.h" #include "v3math.h" @@ -158,7 +157,6 @@ public: U32 getFileSize(); BOOL serialize(LLDataPacker& dp) const; BOOL deserialize(LLDataPacker& dp); - void writeCAL3D(apr_file_t* fp); BOOL isLoaded() { return mJointMotionList != NULL; } @@ -339,7 +337,8 @@ public: InterpolationType mInterpolationType; S32 mNumKeys; - LLPtrSkipMap mKeys; + typedef std::map key_map_t; + key_map_t mKeys; ScaleKey mLoopInKey; ScaleKey mLoopOutKey; }; @@ -357,7 +356,8 @@ public: InterpolationType mInterpolationType; S32 mNumKeys; - LLPtrSkipMap mKeys; + typedef std::map key_map_t; + key_map_t mKeys; RotationKey mLoopInKey; RotationKey mLoopOutKey; }; @@ -375,7 +375,8 @@ public: InterpolationType mInterpolationType; S32 mNumKeys; - LLPtrSkipMap mKeys; + typedef std::map key_map_t; + key_map_t mKeys; PositionKey mLoopInKey; PositionKey mLoopOutKey; }; diff --git a/linden/indra/llcharacter/llkeyframemotionparam.cpp b/linden/indra/llcharacter/llkeyframemotionparam.cpp index 2dd935c..106c02c 100644 --- a/linden/indra/llcharacter/llkeyframemotionparam.cpp +++ b/linden/indra/llcharacter/llkeyframemotionparam.cpp @@ -48,14 +48,6 @@ //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -// sortFunc() -//----------------------------------------------------------------------------- -BOOL LLKeyframeMotionParam::sortFunc(ParameterizedMotion *new_motion, ParameterizedMotion *tested_motion) -{ - return (new_motion->second < tested_motion->second); -} - -//----------------------------------------------------------------------------- // LLKeyframeMotionParam() // Class Constructor //----------------------------------------------------------------------------- @@ -77,17 +69,18 @@ LLKeyframeMotionParam::LLKeyframeMotionParam( const LLUUID &id) : LLMotion(id) //----------------------------------------------------------------------------- LLKeyframeMotionParam::~LLKeyframeMotionParam() { - for (U32 i = 0; i < mParameterizedMotions.length(); i++) + for (motion_map_t::iterator iter = mParameterizedMotions.begin(); + iter != mParameterizedMotions.end(); ++iter) { - LLLinkedList< ParameterizedMotion > *motionList = *mParameterizedMotions.getValueAt(i); - for (ParameterizedMotion* paramMotion = motionList->getFirstData(); paramMotion; paramMotion = motionList->getNextData()) + motion_list_t& motionList = iter->second; + for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { - delete paramMotion->first; + const ParameterizedMotion& paramMotion = *iter2; + delete paramMotion.first; // note - deletes the structure; ParameterizedMotion pair remains intact } - delete motionList; + motionList.clear(); } - - mParameterizedMotions.removeAll(); + mParameterizedMotions.clear(); } //----------------------------------------------------------------------------- @@ -102,36 +95,39 @@ LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *ch return STATUS_FAILURE; } - for (U32 i = 0; i < mParameterizedMotions.length(); i++) + for (motion_map_t::iterator iter = mParameterizedMotions.begin(); + iter != mParameterizedMotions.end(); ++iter) { - LLLinkedList< ParameterizedMotion > *motionList = *mParameterizedMotions.getValueAt(i); - for (ParameterizedMotion* paramMotion = motionList->getFirstData(); paramMotion; paramMotion = motionList->getNextData()) + motion_list_t& motionList = iter->second; + for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { - paramMotion->first->onInitialize(character); + const ParameterizedMotion& paramMotion = *iter2; - if (paramMotion->first->getDuration() > mEaseInDuration) + paramMotion.first->onInitialize(character); + + if (paramMotion.first->getDuration() > mEaseInDuration) { - mEaseInDuration = paramMotion->first->getEaseInDuration(); + mEaseInDuration = paramMotion.first->getEaseInDuration(); } - if (paramMotion->first->getEaseOutDuration() > mEaseOutDuration) + if (paramMotion.first->getEaseOutDuration() > mEaseOutDuration) { - mEaseOutDuration = paramMotion->first->getEaseOutDuration(); + mEaseOutDuration = paramMotion.first->getEaseOutDuration(); } - if (paramMotion->first->getDuration() > mDuration) + if (paramMotion.first->getDuration() > mDuration) { - mDuration = paramMotion->first->getDuration(); + mDuration = paramMotion.first->getDuration(); } - if (paramMotion->first->getPriority() > mPriority) + if (paramMotion.first->getPriority() > mPriority) { - mPriority = paramMotion->first->getPriority(); + mPriority = paramMotion.first->getPriority(); } - LLPose *pose = paramMotion->first->getPose(); + LLPose *pose = paramMotion.first->getPose(); - mPoseBlender.addMotion(paramMotion->first); + mPoseBlender.addMotion(paramMotion.first); for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState()) { LLPose *blendedPose = mPoseBlender.getBlendedPose(); @@ -148,12 +144,14 @@ LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *ch //----------------------------------------------------------------------------- BOOL LLKeyframeMotionParam::onActivate() { - for (U32 i = 0; i < mParameterizedMotions.length(); i++) + for (motion_map_t::iterator iter = mParameterizedMotions.begin(); + iter != mParameterizedMotions.end(); ++iter) { - LLLinkedList< ParameterizedMotion > *motionList = *mParameterizedMotions.getValueAt(i); - for (ParameterizedMotion* paramMotion = motionList->getFirstData(); paramMotion; paramMotion = motionList->getNextData()) + motion_list_t& motionList = iter->second; + for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { - paramMotion->first->activate(); + const ParameterizedMotion& paramMotion = *iter2; + paramMotion.first->activate(); } } return TRUE; @@ -165,46 +163,48 @@ BOOL LLKeyframeMotionParam::onActivate() //----------------------------------------------------------------------------- BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) { - F32 weightFactor = 1.f / (F32)mParameterizedMotions.length(); - U32 i; + F32 weightFactor = 1.f / (F32)mParameterizedMotions.size(); // zero out all pose weights - for (i = 0; i < mParameterizedMotions.length(); i++) + for (motion_map_t::iterator iter = mParameterizedMotions.begin(); + iter != mParameterizedMotions.end(); ++iter) { - LLLinkedList< ParameterizedMotion > *motionList = *mParameterizedMotions.getValueAt(i); - - for (ParameterizedMotion* paramMotion = motionList->getFirstData(); paramMotion; paramMotion = motionList->getNextData()) + motion_list_t& motionList = iter->second; + for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { -// llinfos << "Weight for pose " << paramMotion->first->getName() << " is " << paramMotion->first->getPose()->getWeight() << llendl; - paramMotion->first->getPose()->setWeight(0.f); + const ParameterizedMotion& paramMotion = *iter2; +// llinfos << "Weight for pose " << paramMotion.first->getName() << " is " << paramMotion.first->getPose()->getWeight() << llendl; + paramMotion.first->getPose()->setWeight(0.f); } } - for (i = 0; i < mParameterizedMotions.length(); i++) + for (motion_map_t::iterator iter = mParameterizedMotions.begin(); + iter != mParameterizedMotions.end(); ++iter) { - LLLinkedList< ParameterizedMotion > *motionList = *mParameterizedMotions.getValueAt(i); - std::string *paramName = mParameterizedMotions.getIndexAt(i); - F32* paramValue = (F32 *)mCharacter->getAnimationData(*paramName); - ParameterizedMotion* firstMotion = NULL; - ParameterizedMotion* secondMotion = NULL; - + const std::string& paramName = iter->first; + F32* paramValue = (F32 *)mCharacter->getAnimationData(paramName); if (NULL == paramValue) // unexpected, but... { llwarns << "paramValue == NULL" << llendl; continue; } - for (ParameterizedMotion* paramMotion = motionList->getFirstData(); paramMotion; paramMotion = motionList->getNextData()) + const ParameterizedMotion* firstMotion = NULL; + const ParameterizedMotion* secondMotion = NULL; + + motion_list_t& motionList = iter->second; + for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { - paramMotion->first->onUpdate(time, joint_mask); + const ParameterizedMotion& paramMotion = *iter2; + paramMotion.first->onUpdate(time, joint_mask); - F32 distToParam = paramMotion->second - *paramValue; + F32 distToParam = paramMotion.second - *paramValue; if ( distToParam <= 0.f) { // keep track of the motion closest to the parameter value - firstMotion = paramMotion; + firstMotion = ¶mMotion; } else { @@ -212,13 +212,13 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) // so store the first motion we find as the second one we want to blend... if (firstMotion && !secondMotion ) { - secondMotion = paramMotion; + secondMotion = ¶mMotion; } //...or, if we've seen no other motion so far, make sure we blend to this only else if (!firstMotion) { - firstMotion = paramMotion; - secondMotion = paramMotion; + firstMotion = ¶mMotion; + secondMotion = ¶mMotion; } } } @@ -283,12 +283,14 @@ BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask) //----------------------------------------------------------------------------- void LLKeyframeMotionParam::onDeactivate() { - for (U32 i = 0; i < mParameterizedMotions.length(); i++) + for (motion_map_t::iterator iter = mParameterizedMotions.begin(); + iter != mParameterizedMotions.end(); ++iter) { - LLLinkedList< ParameterizedMotion > *motionList = *mParameterizedMotions.getValueAt(i); - for (ParameterizedMotion* paramMotion = motionList->getFirstData(); paramMotion; paramMotion = motionList->getNextData()) + motion_list_t& motionList = iter->second; + for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { - paramMotion->first->onDeactivate(); + const ParameterizedMotion& paramMotion = *iter2; + paramMotion.first->onDeactivate(); } } } @@ -307,23 +309,8 @@ BOOL LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char newMotion->setName(name); - // make sure a list of motions exists for this parameter - LLLinkedList< ParameterizedMotion > *motionList; - if (mParameterizedMotions.getValue(param)) - { - motionList = *mParameterizedMotions.getValue(param); - } - else - { - motionList = new LLLinkedList< ParameterizedMotion >; - motionList->setInsertBefore(sortFunc); - mParameterizedMotions.addToHead(param, motionList); - } - // now add motion to this list - ParameterizedMotion *parameterizedMotion = new ParameterizedMotion(newMotion, value); - - motionList->addDataSorted(parameterizedMotion); + mParameterizedMotions[param].insert(ParameterizedMotion(newMotion, value)); return TRUE; } @@ -334,14 +321,16 @@ BOOL LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char //----------------------------------------------------------------------------- void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name) { - for (U32 i = 0; i < mParameterizedMotions.length(); i++) + for (motion_map_t::iterator iter = mParameterizedMotions.begin(); + iter != mParameterizedMotions.end(); ++iter) { - LLLinkedList< ParameterizedMotion > *motionList = *mParameterizedMotions.getValueAt(i); - for (ParameterizedMotion* paramMotion = motionList->getFirstData(); paramMotion; paramMotion = motionList->getNextData()) + motion_list_t& motionList = iter->second; + for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2) { - if (paramMotion->first->getName() == name) + const ParameterizedMotion& paramMotion = *iter2; + if (paramMotion.first->getName() == name) { - mDefaultKeyframeMotion = paramMotion->first; + mDefaultKeyframeMotion = paramMotion.first; } } } diff --git a/linden/indra/llcharacter/llkeyframemotionparam.h b/linden/indra/llcharacter/llkeyframemotionparam.h index a5bc2cb..f509e6a 100644 --- a/linden/indra/llcharacter/llkeyframemotionparam.h +++ b/linden/indra/llcharacter/llkeyframemotionparam.h @@ -143,8 +143,20 @@ protected: // Member Data //------------------------------------------------------------------------- - typedef LLLinkedList < ParameterizedMotion > motion_list_t; - LLAssocList mParameterizedMotions; + struct compare_motions + { + bool operator() (const ParameterizedMotion& a, const ParameterizedMotion& b) const + { + if (a.second != b.second) + return (a.second < b.second); + else + return a.first < b.first; + } + }; + + typedef std::set < ParameterizedMotion, compare_motions > motion_list_t; + typedef std::map motion_map_t; + motion_map_t mParameterizedMotions; LLMotion* mDefaultKeyframeMotion; LLCharacter* mCharacter; LLPoseBlender mPoseBlender; diff --git a/linden/indra/llcharacter/llmotioncontroller.cpp b/linden/indra/llcharacter/llmotioncontroller.cpp index d1a2a53..028cf22 100644 --- a/linden/indra/llcharacter/llmotioncontroller.cpp +++ b/linden/indra/llcharacter/llmotioncontroller.cpp @@ -746,7 +746,7 @@ void LLMotionController::updateMotion() // is calculating a new keyframe pose, make sure the last one gets applied mPoseBlender.interpolate(1.f); - mPoseBlender.clearBlenders(); + clearBlenders(); mTimeStepCount = quantum_count; mLastTime = mTime; @@ -824,6 +824,13 @@ void LLMotionController::updateMotion() //----------------------------------------------------------------------------- BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time) { + // It's not clear why the getWeight() line seems to be crashing this, but + // hopefully this fixes it. + if (motion == NULL || motion->getPose() == NULL) + { + return FALSE; + } + if (mLoadingMotions.find(motion) != mLoadingMotions.end()) { // we want to start this motion, but we can't yet, so flag it as started diff --git a/linden/indra/llcharacter/llmotioncontroller.h b/linden/indra/llcharacter/llmotioncontroller.h index e66edcb..48e184d 100644 --- a/linden/indra/llcharacter/llmotioncontroller.h +++ b/linden/indra/llcharacter/llmotioncontroller.h @@ -157,6 +157,8 @@ public: // deactivates terminated motions` void updateMotion(); + void clearBlenders() { mPoseBlender.clearBlenders(); } + // flush motions // releases all motion instances void flushAllMotions(); diff --git a/linden/indra/llcharacter/llpose.cpp b/linden/indra/llcharacter/llpose.cpp index 3a6a221..f496b7b 100644 --- a/linden/indra/llcharacter/llpose.cpp +++ b/linden/indra/llcharacter/llpose.cpp @@ -379,15 +379,20 @@ void LLJointStateBlender::blendJointStates(BOOL apply_now) } } - // apply blended transforms - target_joint->setPosition(blended_pos); - target_joint->setScale(blended_scale); - target_joint->setRotation(blended_rot); - - // apply additive transforms - target_joint->setPosition(target_joint->getPosition() + added_pos); - target_joint->setScale(target_joint->getScale() + added_scale); - target_joint->setRotation(added_rot * target_joint->getRotation()); + if (!added_scale.isFinite()) + { + added_scale.clearVec(); + } + + if (!blended_scale.isFinite()) + { + blended_scale.setVec(1,1,1); + } + + // apply transforms + target_joint->setPosition(blended_pos + added_pos); + target_joint->setScale(blended_scale + added_scale); + target_joint->setRotation(added_rot * blended_rot); if (apply_now) { diff --git a/linden/indra/llcharacter/llpose.h b/linden/indra/llcharacter/llpose.h index f67a26b..075a456 100644 --- a/linden/indra/llcharacter/llpose.h +++ b/linden/indra/llcharacter/llpose.h @@ -37,10 +37,8 @@ //----------------------------------------------------------------------------- #include -#include "linked_lists.h" #include "llmap.h" #include "lljointstate.h" -#include "llassoclist.h" #include "lljoint.h" #include diff --git a/linden/indra/llcharacter/llstatemachine.h b/linden/indra/llcharacter/llstatemachine.h index f46e4bf..12a71b7 100644 --- a/linden/indra/llcharacter/llstatemachine.h +++ b/linden/indra/llcharacter/llstatemachine.h @@ -34,7 +34,6 @@ #include -#include "llassoclist.h" #include "llerror.h" #include diff --git a/linden/indra/llcommon/indra_constants.h b/linden/indra/llcommon/indra_constants.h index 16e471d..eceb576 100644 --- a/linden/indra/llcommon/indra_constants.h +++ b/linden/indra/llcommon/indra_constants.h @@ -323,6 +323,10 @@ const U32 PARCEL_MEDIA_COMMAND_TIME = 6; const U32 PARCEL_MEDIA_COMMAND_AGENT = 7; const U32 PARCEL_MEDIA_COMMAND_UNLOAD = 8; const U32 PARCEL_MEDIA_COMMAND_AUTO_ALIGN = 9; +const U32 PARCEL_MEDIA_COMMAND_TYPE = 10; +const U32 PARCEL_MEDIA_COMMAND_SIZE = 11; +const U32 PARCEL_MEDIA_COMMAND_DESC = 12; +const U32 PARCEL_MEDIA_COMMAND_LOOP_SET = 13; // map item types const U32 MAP_ITEM_TELEHUB = 0x01; diff --git a/linden/indra/llcommon/linden_common.h b/linden/indra/llcommon/linden_common.h index 01540c1..547cceb 100644 --- a/linden/indra/llcommon/linden_common.h +++ b/linden/indra/llcommon/linden_common.h @@ -58,6 +58,13 @@ #ifdef LL_WINDOWS #pragma warning (3 : 4702) // we like level 3, not 4 +// level 4 warnings that we need to disable: +#pragma warning (disable : 4100) // unreferenced formal parameter +#pragma warning (disable : 4127) // conditional expression is constant (e.g. while(1) ) +#pragma warning (disable : 4244) // possible loss of data on conversions +#pragma warning (disable : 4396) // the inline specifier cannot be used when a friend declaration refers to a specialization of a function template +#pragma warning (disable : 4512) // assignment operator could not be generated +#pragma warning (disable : 4706) // assignment within conditional (even if((x = y)) ) #endif // LL_WINDOWS // Linden only libs in alpha-order other than stdtypes.h diff --git a/linden/indra/llcommon/llapp.cpp b/linden/indra/llcommon/llapp.cpp index 5ae0727..a10436a 100644 --- a/linden/indra/llcommon/llapp.cpp +++ b/linden/indra/llcommon/llapp.cpp @@ -166,7 +166,16 @@ bool LLApp::parseCommandOptions(int argc, char** argv) // we found another option after this one or we have // reached the end. simply record that this option was // found and continue. - commands[name] = true; + int flag = name.compare("logfile"); + if (0 == flag) + { + commands[name] = "log"; + } + else + { + commands[name] = true; + } + continue; } ++ii; diff --git a/linden/indra/llcommon/llapr.cpp b/linden/indra/llcommon/llapr.cpp index 2a81e5e..770cd3f 100644 --- a/linden/indra/llcommon/llapr.cpp +++ b/linden/indra/llcommon/llapr.cpp @@ -292,7 +292,7 @@ bool ll_apr_file_remove(const LLString& filename, apr_pool_t* pool) s = apr_file_remove(filename.c_str(), pool); if (s != APR_SUCCESS) { - llwarns << "ll_apr_file_remove failed on file: " << filename << llendl; + lldebugs << "ll_apr_file_remove failed on file: " << filename << llendl; ll_apr_warn_status(s); return false; } @@ -306,7 +306,7 @@ bool ll_apr_file_rename(const LLString& filename, const LLString& newname, apr_p s = apr_file_rename(filename.c_str(), newname.c_str(), pool); if (s != APR_SUCCESS) { - llwarns << "ll_apr_file_rename failed on file: " << filename << llendl; + lldebugs << "ll_apr_file_rename failed on file: " << filename << llendl; ll_apr_warn_status(s); return false; } @@ -363,7 +363,7 @@ bool ll_apr_dir_make(const LLString& dirname, apr_pool_t* pool) s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool); if (s != APR_SUCCESS) { - llwarns << "ll_apr_file_remove failed on file: " << dirname << llendl; + lldebugs << "ll_apr_dir_make failed on file: " << dirname << llendl; ll_apr_warn_status(s); return false; } @@ -377,7 +377,7 @@ bool ll_apr_dir_remove(const LLString& dirname, apr_pool_t* pool) s = apr_file_remove(dirname.c_str(), pool); if (s != APR_SUCCESS) { - llwarns << "ll_apr_file_remove failed on file: " << dirname << llendl; + lldebugs << "ll_apr_dir_remove failed on file: " << dirname << llendl; ll_apr_warn_status(s); return false; } diff --git a/linden/indra/llcommon/llclickaction.h b/linden/indra/llcommon/llclickaction.h index 20bfbfd..b69ca15 100644 --- a/linden/indra/llcommon/llclickaction.h +++ b/linden/indra/llcommon/llclickaction.h @@ -39,5 +39,7 @@ const U8 CLICK_ACTION_SIT = 1; const U8 CLICK_ACTION_BUY = 2; const U8 CLICK_ACTION_PAY = 3; const U8 CLICK_ACTION_OPEN = 4; +const U8 CLICK_ACTION_PLAY = 5; +const U8 CLICK_ACTION_OPEN_MEDIA = 6; #endif diff --git a/linden/indra/llcommon/llcommon_vc8.vcproj b/linden/indra/llcommon/llcommon_vc8.vcproj index fc3060a..5578075 100644 --- a/linden/indra/llcommon/llcommon_vc8.vcproj +++ b/linden/indra/llcommon/llcommon_vc8.vcproj @@ -1,807 +1,811 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llcommon/llcommon_vc9.vcproj b/linden/indra/llcommon/llcommon_vc9.vcproj index 752d13f..0bb2d11 100644 --- a/linden/indra/llcommon/llcommon_vc9.vcproj +++ b/linden/indra/llcommon/llcommon_vc9.vcproj @@ -1,808 +1,808 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llcommon/llfasttimer.h b/linden/indra/llcommon/llfasttimer.h index 3ecf176..8ad2667 100644 --- a/linden/indra/llcommon/llfasttimer.h +++ b/linden/indra/llcommon/llfasttimer.h @@ -62,6 +62,7 @@ public: FTM_SIMULATE_PARTICLES, FTM_UPDATE_SKY, FTM_UPDATE_TEXTURES, + FTM_UPDATE_WLPARAM, FTM_UPDATE_WATER, FTM_UPDATE_CLOUDS, FTM_UPDATE_GRASS, @@ -86,8 +87,12 @@ public: FTM_RENDER_HUD, FTM_RENDER_PARTICLES, FTM_RENDER_WATER, + FTM_RENDER_WL_SKY, + FTM_RENDER_FAKE_VBO_UPDATE, FTM_RENDER_TIMER, FTM_RENDER_UI, + FTM_RENDER_BLOOM, + FTM_RENDER_BLOOM_FBO, FTM_RENDER_FONTS, // newview specific @@ -124,6 +129,7 @@ public: FTM_GEO_RESERVE, FTM_GEO_LIGHT, FTM_GEO_SHADOW, + FTM_GEO_SKY, FTM_GEN_VOLUME, FTM_GEN_TRIANGLES, FTM_GEN_FLEX, @@ -150,7 +156,6 @@ public: FTM_PIPELINE, FTM_VFILE_WAIT, FTM_FLEXIBLE_UPDATE, - FTM_OCCLUSION, FTM_OCCLUSION_READBACK, FTM_HUD_EFFECTS, FTM_HUD_UPDATE, diff --git a/linden/indra/llcommon/llfile.cpp b/linden/indra/llcommon/llfile.cpp index 38157df..6ccf6ac 100644 --- a/linden/indra/llcommon/llfile.cpp +++ b/linden/indra/llcommon/llfile.cpp @@ -286,8 +286,36 @@ llofstream::llofstream(const char *_Filename, llofstream::~llofstream() { // destroy the object + close(); delete _Filebuffer; } #endif // #if USE_LLFILESTREAMS +/************** helper functions ********************************/ + +std::streamsize llifstream_size(llifstream& ifstr) +{ + if(!ifstr.is_open()) return 0; + std::streampos pos_old = ifstr.tellg(); + ifstr.seekg(0, ios_base::beg); + std::streampos pos_beg = ifstr.tellg(); + ifstr.seekg(0, ios_base::end); + std::streampos pos_end = ifstr.tellg(); + ifstr.seekg(pos_old, ios_base::beg); + return pos_end - pos_beg; +} + +std::streamsize llofstream_size(llofstream& ofstr) +{ + if(!ofstr.is_open()) return 0; + std::streampos pos_old = ofstr.tellp(); + ofstr.seekp(0, ios_base::beg); + std::streampos pos_beg = ofstr.tellp(); + ofstr.seekp(0, ios_base::end); + std::streampos pos_end = ofstr.tellp(); + ofstr.seekp(pos_old, ios_base::beg); + return pos_end - pos_beg; +} + + diff --git a/linden/indra/llcommon/llfile.h b/linden/indra/llcommon/llfile.h index 062b183..2650775 100644 --- a/linden/indra/llcommon/llfile.h +++ b/linden/indra/llcommon/llfile.h @@ -168,5 +168,14 @@ private: #endif +/** + * @breif filesize helpers. + * + * The file size helpers are not considered particularly efficient, + * and should only be used for config files and the like -- not in a + * loop. + */ +std::streamsize llifstream_size(llifstream& fstr); +std::streamsize llofstream_size(llofstream& fstr); #endif // not LL_LLFILE_H diff --git a/linden/indra/llcommon/llkeythrottle.h b/linden/indra/llcommon/llkeythrottle.h index c2dc9d2..8314269 100644 --- a/linden/indra/llcommon/llkeythrottle.h +++ b/linden/indra/llcommon/llkeythrottle.h @@ -192,10 +192,7 @@ public: { noteAction(id); typename LLKeyThrottleImpl::Entry& curr = (*m.currMap)[id]; - if (curr.count < m.countLimit) - { - curr.count = m.countLimit; - } + curr.count = llmax(m.countLimit, curr.count); curr.blocked = TRUE; } diff --git a/linden/indra/llcommon/lllog.cpp b/linden/indra/llcommon/lllog.cpp index 147b2d3..10f7c00 100644 --- a/linden/indra/llcommon/lllog.cpp +++ b/linden/indra/llcommon/lllog.cpp @@ -69,7 +69,8 @@ void LLLogImpl::log(const std::string message, LLSD& info) } } } - llinfos << "LLLOGMESSAGE (" << (sequence++) << ") " << message << " " << LLSDNotationStreamer(info) << llendl; + llinfos << "LLLOGMESSAGE (" << (sequence++) << ") " << message + << " " << LLSDNotationStreamer(info) << llendl; } //@brief Function to check if specified legacy log message should be sent. diff --git a/linden/indra/llcommon/llmemory.h b/linden/indra/llcommon/llmemory.h index 8a3ca0b..e1af7ba 100644 --- a/linden/indra/llcommon/llmemory.h +++ b/linden/indra/llcommon/llmemory.h @@ -243,25 +243,25 @@ protected: // Expands LLPointer to return a pointer to a special instance of class Type instead of NULL. // This is useful in instances where operations on NULL pointers are semantically safe and/or // when error checking occurs at a different granularity or in a different part of the code -// than when referencing an object via a LLHandle. +// than when referencing an object via a LLSafeHandle. // template -class LLHandle +class LLSafeHandle { public: - LLHandle() : + LLSafeHandle() : mPointer(NULL) { } - LLHandle(Type* ptr) : + LLSafeHandle(Type* ptr) : mPointer(NULL) { assign(ptr); } - LLHandle(const LLHandle& ptr) : + LLSafeHandle(const LLSafeHandle& ptr) : mPointer(NULL) { assign(ptr.mPointer); @@ -269,13 +269,13 @@ public: // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed. template - LLHandle(const LLHandle& ptr) : + LLSafeHandle(const LLSafeHandle& ptr) : mPointer(NULL) { assign(ptr.get()); } - ~LLHandle() + ~LLSafeHandle() { unref(); } @@ -300,17 +300,17 @@ public: operator const Type*() const { return mPointer; } bool operator !=(Type* ptr) const { return (mPointer != ptr); } bool operator ==(Type* ptr) const { return (mPointer == ptr); } - bool operator ==(const LLHandle& ptr) const { return (mPointer == ptr.mPointer); } - bool operator < (const LLHandle& ptr) const { return (mPointer < ptr.mPointer); } - bool operator > (const LLHandle& ptr) const { return (mPointer > ptr.mPointer); } + bool operator ==(const LLSafeHandle& ptr) const { return (mPointer == ptr.mPointer); } + bool operator < (const LLSafeHandle& ptr) const { return (mPointer < ptr.mPointer); } + bool operator > (const LLSafeHandle& ptr) const { return (mPointer > ptr.mPointer); } - LLHandle& operator =(Type* ptr) + LLSafeHandle& operator =(Type* ptr) { assign(ptr); return *this; } - LLHandle& operator =(const LLHandle& ptr) + LLSafeHandle& operator =(const LLSafeHandle& ptr) { assign(ptr.mPointer); return *this; @@ -318,7 +318,7 @@ public: // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed. template - LLHandle& operator =(const LLHandle& ptr) + LLSafeHandle& operator =(const LLSafeHandle& ptr) { assign(ptr.get()); return *this; @@ -399,11 +399,25 @@ protected: //---------------------------------------------------------------------------- -// LLSingleton implements the getInstance() method part of the Singleton pattern. It can't make -// the derived class constructors protected, though, so you have to do that yourself. -// The proper way to use LLSingleton is to inherit from it while using the typename that you'd -// like to be static as the template parameter, like so: -// class FooBar: public LLSingleton +// LLSingleton implements the getInstance() method part of the Singleton +// pattern. It can't make the derived class constructors protected, though, so +// you have to do that yourself. +// +// There are two ways to use LLSingleton. The first way is to inherit from it +// while using the typename that you'd like to be static as the template +// parameter, like so: +// +// class Foo: public LLSingleton{}; +// +// Foo* instance = Foo::getInstance(); +// +// The second way is to define a seperate class that exposes the singleton +// interface: +// +// class FooSingleton: public LLSingleton{}; +// +// Foo* instance = FooSingleton::getInstance(); +// // As currently written, it is not thread-safe. template class LLSingleton diff --git a/linden/indra/llcommon/llpreprocessor.h b/linden/indra/llcommon/llpreprocessor.h index 8bcad34..8d38904 100644 --- a/linden/indra/llcommon/llpreprocessor.h +++ b/linden/indra/llcommon/llpreprocessor.h @@ -52,33 +52,6 @@ #define LL_FORCE_INLINE __forceinline #endif -// Per-OS feature switches. - -#if LL_DARWIN - #define LL_QUICKTIME_ENABLED 1 - #define LL_LIBXUL_ENABLED 1 -#elif LL_WINDOWS - #define LL_QUICKTIME_ENABLED 1 - #define LL_LIBXUL_ENABLED 1 -#elif LL_LINUX - #define LL_QUICKTIME_ENABLED 0 - #ifndef LL_LIBXUL_ENABLED - #define LL_LIBXUL_ENABLED 1 - #endif // def LL_LIBXUL_ENABLED -#elif LL_SOLARIS - #define LL_QUICKTIME_ENABLED 0 - #ifndef LL_LIBXUL_ENABLED - #define LL_LIBXUL_ENABLED 0 - #endif // def LL_LIBXUL_ENABLED -#endif - -#if LL_LIBXUL_ENABLED && !defined(MOZILLA_INTERNAL_API) - // Without this, nsTAString.h errors out with: - // "Cannot use internal string classes without MOZILLA_INTERNAL_API defined. Use the frozen header nsStringAPI.h instead." - // It might be worth our while to figure out if we can use the frozen apis at some point... - #define MOZILLA_INTERNAL_API 1 -#endif - // Figure out differences between compilers #if defined(__GNUC__) #define GCC_VERSION (__GNUC__ * 10000 \ diff --git a/linden/indra/llcommon/llsdserialize.cpp b/linden/indra/llcommon/llsdserialize.cpp index 7813cf0..a556d5d 100644 --- a/linden/indra/llcommon/llsdserialize.cpp +++ b/linden/indra/llcommon/llsdserialize.cpp @@ -45,26 +45,18 @@ #include "lldate.h" #include "llsd.h" +#include "llstring.h" #include "lluri.h" // File constants static const int MAX_HDR_LEN = 20; static const char LEGACY_NON_HEADER[] = ""; +const std::string LLSD_BINARY_HEADER("LLSD/Binary"); +const std::string LLSD_XML_HEADER("LLSD/XML"); -//static -const char* LLSDSerialize::LLSDBinaryHeader = "LLSD/Binary"; - -//static -const char* LLSDSerialize::LLSDXMLHeader = "LLSD/XML"; - -// virtual -LLSDParser::~LLSDParser() -{ } - -// virtual -LLSDNotationParser::~LLSDNotationParser() -{ } - +/** + * LLSDSerialize + */ // static void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize type, U32 options) @@ -74,12 +66,12 @@ void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize switch (type) { case LLSD_BINARY: - str << "\n"; + str << "\n"; f = new LLSDBinaryFormatter; break; case LLSD_XML: - str << "\n"; + str << "\n"; f = new LLSDXMLFormatter; break; @@ -94,7 +86,7 @@ void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize } // static -bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str) +bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes) { LLPointer p = NULL; char hdr_buf[MAX_HDR_LEN + 1] = ""; /* Flawfinder: ignore */ @@ -102,8 +94,8 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str) int inbuf = 0; bool legacy_no_header = false; bool fail_if_not_legacy = false; - std::string header = ""; - + std::string header; + /* * Get the first line before anything. */ @@ -155,15 +147,15 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str) */ if (legacy_no_header) { - LLSDXMLParser *x = new LLSDXMLParser; + LLSDXMLParser* x = new LLSDXMLParser; x->parsePart(hdr_buf, inbuf); p = x; } - else if (header == LLSDBinaryHeader) + else if (header == LLSD_BINARY_HEADER) { p = new LLSDBinaryParser; } - else if (header == LLSDXMLHeader) + else if (header == LLSD_XML_HEADER) { p = new LLSDXMLParser; } @@ -174,7 +166,7 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str) if (p.notNull()) { - p->parse(str, sd); + p->parse(str, sd, max_bytes); return true; } @@ -230,11 +222,71 @@ F64 ll_ntohd(F64 netdouble) /** * Local functions. */ -bool deserialize_string(std::istream& str, std::string& value); -bool deserialize_string_delim(std::istream& str, std::string& value, char d); -bool deserialize_string_raw(std::istream& str, std::string& value); +/** + * @brief Figure out what kind of string it is (raw or delimited) and handoff. + * + * @param istr The stream to read from. + * @param value [out] The string which was found. + * @param max_bytes The maximum possible length of the string. Passing in + * a negative value will skip this check. + * @return Returns number of bytes read off of the stream. Returns + * PARSE_FAILURE (-1) on failure. + */ +int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes); + +/** + * @brief Parse a delimited string. + * + * @param istr The stream to read from, with the delimiter already popped. + * @param value [out] The string which was found. + * @param d The delimiter to use. + * @return Returns number of bytes read off of the stream. Returns + * PARSE_FAILURE (-1) on failure. + */ +int deserialize_string_delim(std::istream& istr, std::string& value, char d); + +/** + * @brief Read a raw string off the stream. + * + * @param istr The stream to read from, with the (len) parameter + * leading the stream. + * @param value [out] The string which was found. + * @param d The delimiter to use. + * @param max_bytes The maximum possible length of the string. Passing in + * a negative value will skip this check. + * @return Returns number of bytes read off of the stream. Returns + * PARSE_FAILURE (-1) on failure. + */ +int deserialize_string_raw( + std::istream& istr, + std::string& value, + S32 max_bytes); + +/** + * @brief helper method for dealing with the different notation boolean format. + * + * @param istr The stream to read from with the leading character stripped. + * @param data [out] the result of the parse. + * @param compare The string to compare the boolean against + * @param vale The value to assign to data if the parse succeeds. + * @return Returns number of bytes read off of the stream. Returns + * PARSE_FAILURE (-1) on failure. + */ +int deserialize_boolean( + std::istream& istr, + LLSD& data, + const std::string& compare, + bool value); + +/** + * @brief Do notation escaping of a string to an ostream. + * + * @param value The string to escape and serialize + * @param str The stream to serialize to. + */ void serialize_string(const std::string& value, std::ostream& str); + /** * Local constants. */ @@ -244,20 +296,96 @@ static const std::string NOTATION_FALSE_SERIAL("false"); static const char BINARY_TRUE_SERIAL = '1'; static const char BINARY_FALSE_SERIAL = '0'; -static const S32 NOTATION_PARSE_FAILURE = -1; /** * LLSDParser */ -LLSDParser::LLSDParser() +LLSDParser::LLSDParser() : mCheckLimits(true), mMaxBytesLeft(0) +{ +} + +// virtual +LLSDParser::~LLSDParser() +{ } + +S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes) +{ + mCheckLimits = (LLSDSerialize::SIZE_UNLIMITED == max_bytes) ? false : true; + mMaxBytesLeft = max_bytes; + return doParse(istr, data); +} + + +int LLSDParser::get(std::istream& istr) const +{ + if(mCheckLimits) --mMaxBytesLeft; + return istr.get(); +} + +std::istream& LLSDParser::get( + std::istream& istr, + char* s, + std::streamsize n, + char delim) const +{ + istr.get(s, n, delim); + if(mCheckLimits) mMaxBytesLeft -= istr.gcount(); + return istr; +} + +std::istream& LLSDParser::get( + std::istream& istr, + std::streambuf& sb, + char delim) const +{ + istr.get(sb, delim); + if(mCheckLimits) mMaxBytesLeft -= istr.gcount(); + return istr; +} + +std::istream& LLSDParser::ignore(std::istream& istr) const { + istr.ignore(); + if(mCheckLimits) --mMaxBytesLeft; + return istr; } +std::istream& LLSDParser::putback(std::istream& istr, char c) const +{ + istr.putback(c); + if(mCheckLimits) ++mMaxBytesLeft; + return istr; +} + +std::istream& LLSDParser::read( + std::istream& istr, + char* s, + std::streamsize n) const +{ + istr.read(s, n); + if(mCheckLimits) mMaxBytesLeft -= istr.gcount(); + return istr; +} + +void LLSDParser::account(S32 bytes) const +{ + if(mCheckLimits) mMaxBytesLeft -= bytes; +} + + /** * LLSDNotationParser */ +LLSDNotationParser::LLSDNotationParser() +{ +} + +// virtual +LLSDNotationParser::~LLSDNotationParser() +{ } + // virtual -S32 LLSDNotationParser::parse(std::istream& istr, LLSD& data) const +S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const { // map: { string:object, string:object } // array: [ object, object, object ] @@ -275,7 +403,7 @@ S32 LLSDNotationParser::parse(std::istream& istr, LLSD& data) const while(isspace(c)) { // pop the whitespace. - c = istr.get(); + c = get(istr); c = istr.peek(); continue; } @@ -287,107 +415,142 @@ S32 LLSDNotationParser::parse(std::istream& istr, LLSD& data) const switch(c) { case '{': - parse_count += parseMap(istr, data); - if(istr.fail()) + { + S32 child_count = parseMap(istr, data); + if((child_count == PARSE_FAILURE) || data.isUndefined()) { - llinfos << "STREAM FAILURE reading map." << llendl; + parse_count = PARSE_FAILURE; } - if(data.isUndefined()) + else { - parse_count = NOTATION_PARSE_FAILURE; + parse_count += child_count; + } + if(istr.fail()) + { + llinfos << "STREAM FAILURE reading map." << llendl; + parse_count = PARSE_FAILURE; } break; + } case '[': - parse_count += parseArray(istr, data); - if(istr.fail()) + { + S32 child_count = parseArray(istr, data); + if((child_count == PARSE_FAILURE) || data.isUndefined()) { - llinfos << "STREAM FAILURE reading array." << llendl; + parse_count = PARSE_FAILURE; } - if(data.isUndefined()) + else { - parse_count = NOTATION_PARSE_FAILURE; + parse_count += child_count; + } + if(istr.fail()) + { + llinfos << "STREAM FAILURE reading array." << llendl; + parse_count = PARSE_FAILURE; } break; + } case '!': - c = istr.get(); + c = get(istr); data.clear(); break; case '0': - c = istr.get(); + c = get(istr); data = false; break; case 'F': case 'f': - do + ignore(istr); + c = istr.peek(); + if(isalpha(c)) { - istr.ignore(); - c = istr.peek(); - } while (isalpha(c)); - data = false; + int cnt = deserialize_boolean( + istr, + data, + NOTATION_FALSE_SERIAL, + false); + if(PARSE_FAILURE == cnt) parse_count = cnt; + else account(cnt); + } + else + { + data = false; + } if(istr.fail()) { llinfos << "STREAM FAILURE reading boolean." << llendl; + parse_count = PARSE_FAILURE; } break; case '1': - c = istr.get(); + c = get(istr); data = true; break; case 'T': case 't': - do + ignore(istr); + c = istr.peek(); + if(isalpha(c)) { - istr.ignore(); - c = istr.peek(); - } while (isalpha(c)); - data = true; + int cnt = deserialize_boolean(istr,data,NOTATION_TRUE_SERIAL,true); + if(PARSE_FAILURE == cnt) parse_count = cnt; + else account(cnt); + } + else + { + data = true; + } if(istr.fail()) { llinfos << "STREAM FAILURE reading boolean." << llendl; + parse_count = PARSE_FAILURE; } break; case 'i': { - c = istr.get(); + c = get(istr); S32 integer = 0; istr >> integer; data = integer; if(istr.fail()) { llinfos << "STREAM FAILURE reading integer." << llendl; + parse_count = PARSE_FAILURE; } break; } case 'r': { - c = istr.get(); + c = get(istr); F64 real = 0.0; istr >> real; data = real; if(istr.fail()) { llinfos << "STREAM FAILURE reading real." << llendl; + parse_count = PARSE_FAILURE; } break; } case 'u': { - c = istr.get(); + c = get(istr); LLUUID id; istr >> id; data = id; if(istr.fail()) { llinfos << "STREAM FAILURE reading uuid." << llendl; + parse_count = PARSE_FAILURE; } break; } @@ -395,126 +558,144 @@ S32 LLSDNotationParser::parse(std::istream& istr, LLSD& data) const case '\"': case '\'': case 's': - parseString(istr, data); - if(istr.fail()) + if(!parseString(istr, data)) { - llinfos << "STREAM FAILURE reading string." << llendl; + parse_count = PARSE_FAILURE; } - if(data.isUndefined()) + if(istr.fail()) { - parse_count = NOTATION_PARSE_FAILURE; + llinfos << "STREAM FAILURE reading string." << llendl; + parse_count = PARSE_FAILURE; } break; case 'l': { - c = istr.get(); // pop the 'l' - c = istr.get(); // pop the delimiter + c = get(istr); // pop the 'l' + c = get(istr); // pop the delimiter std::string str; - deserialize_string_delim(istr, str, c); - data = LLURI(str); + int cnt = deserialize_string_delim(istr, str, c); + if(PARSE_FAILURE == cnt) + { + parse_count = PARSE_FAILURE; + } + else + { + data = LLURI(str); + account(cnt); + } if(istr.fail()) { llinfos << "STREAM FAILURE reading link." << llendl; + parse_count = PARSE_FAILURE; } break; } case 'd': { - c = istr.get(); // pop the 'd' - c = istr.get(); // pop the delimiter + c = get(istr); // pop the 'd' + c = get(istr); // pop the delimiter std::string str; - deserialize_string_delim(istr, str, c); - data = LLDate(str); + int cnt = deserialize_string_delim(istr, str, c); + if(PARSE_FAILURE == cnt) + { + parse_count = PARSE_FAILURE; + } + else + { + data = LLDate(str); + account(cnt); + } if(istr.fail()) { llinfos << "STREAM FAILURE reading date." << llendl; + parse_count = PARSE_FAILURE; } break; } case 'b': - parseBinary(istr, data); - if(istr.fail()) + if(!parseBinary(istr, data)) { - llinfos << "STREAM FAILURE reading data." << llendl; + parse_count = PARSE_FAILURE; } - if(data.isUndefined()) + if(istr.fail()) { - parse_count = NOTATION_PARSE_FAILURE; + llinfos << "STREAM FAILURE reading data." << llendl; + parse_count = PARSE_FAILURE; } break; default: - data.clear(); - parse_count = NOTATION_PARSE_FAILURE; + parse_count = PARSE_FAILURE; llinfos << "Unrecognized character while parsing: int(" << (int)c - << ")" << llendl; + << ")" << llendl; break; } + if(PARSE_FAILURE == parse_count) + { + data.clear(); + } return parse_count; } -// static -LLSD LLSDNotationParser::parse(std::istream& istr) -{ - LLSDNotationParser parser; - LLSD rv; - S32 count = parser.parse(istr, rv); - lldebugs << "LLSDNotationParser::parse parsed " << count << " objects." - << llendl; - return rv; -} - S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map) const { // map: { string:object, string:object } map = LLSD::emptyMap(); S32 parse_count = 0; - char c = istr.get(); + char c = get(istr); if(c == '{') { // eat commas, white bool found_name = false; std::string name; - c = istr.get(); + c = get(istr); while(c != '}' && istr.good()) { if(!found_name) { if((c == '\"') || (c == '\'') || (c == 's')) { - istr.putback(c); + putback(istr, c); found_name = true; - deserialize_string(istr, name); + int count = deserialize_string(istr, name, mMaxBytesLeft); + if(PARSE_FAILURE == count) return PARSE_FAILURE; + account(count); } - c = istr.get(); + c = get(istr); } else { if(isspace(c) || (c == ':')) { - c = istr.get(); + c = get(istr); continue; } - istr.putback(c); + putback(istr, c); LLSD child; - S32 count = parse(istr, child); + S32 count = doParse(istr, child); if(count > 0) { + // There must be a value for every key, thus + // child_count must be greater than 0. parse_count += count; map.insert(name, child); } else { - map.clear(); - return NOTATION_PARSE_FAILURE; + return PARSE_FAILURE; } found_name = false; - c = istr.get(); + c = get(istr); } } + if(c != '}') + { + map.clear(); + return PARSE_FAILURE; + } } return parse_count; } @@ -524,52 +705,51 @@ S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array) const // array: [ object, object, object ] array = LLSD::emptyArray(); S32 parse_count = 0; - char c = istr.get(); + char c = get(istr); if(c == '[') { // eat commas, white - c = istr.get(); + c = get(istr); while((c != ']') && istr.good()) { LLSD child; if(isspace(c) || (c == ',')) { - c = istr.get(); + c = get(istr); continue; } - istr.putback(c); - S32 count = parse(istr, child); - if(count > 0) + putback(istr, c); + S32 count = doParse(istr, child); + if(PARSE_FAILURE == count) { - parse_count += count; - array.append(child); + return PARSE_FAILURE; } else { - array.clear(); - return NOTATION_PARSE_FAILURE; + parse_count += count; + array.append(child); } - c = istr.get(); + c = get(istr); + } + if(c != ']') + { + return PARSE_FAILURE; } } return parse_count; } -void LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const +bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const { std::string value; - if(deserialize_string(istr, value)) - { - data = value; - } - else - { - // failed to parse. - data.clear(); - } + int count = deserialize_string(istr, value, mMaxBytesLeft); + if(PARSE_FAILURE == count) return false; + account(count); + data = value; + return true; } -void LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const +bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const { // binary: b##"ff3120ab1" // or: b(len)"..." @@ -582,40 +762,44 @@ void LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const // need to read the base out. char buf[BINARY_BUFFER_SIZE]; /* Flawfinder: ignore */ - istr.get(buf, STREAM_GET_COUNT, '"'); - char c = istr.get(); - if((c == '"') && (0 == strncmp("b(", buf, 2))) + get(istr, buf, STREAM_GET_COUNT, '"'); + char c = get(istr); + if(c != '"') return false; + if(0 == strncmp("b(", buf, 2)) { // We probably have a valid raw binary stream. determine // the size, and read it. - // *FIX: Should we set a maximum size? S32 len = strtol(buf + 2, NULL, 0); + if(mCheckLimits && (len > mMaxBytesLeft)) return false; std::vector value; if(len) { value.resize(len); - fullread(istr, (char *)&value[0], len); + account(fullread(istr, (char *)&value[0], len)); } - c = istr.get(); // strip off the trailing double-quote + c = get(istr); // strip off the trailing double-quote data = value; } - else if((c == '"') && (0 == strncmp("b64", buf, 3))) + else if(0 == strncmp("b64", buf, 3)) { // *FIX: A bit inefficient, but works for now. To make the // format better, I would need to add a hint into the // serialization format that indicated how long it was. std::stringstream coded_stream; - istr.get(*(coded_stream.rdbuf()), '\"'); - c = istr.get(); + get(istr, *(coded_stream.rdbuf()), '\"'); + c = get(istr); std::string encoded(coded_stream.str()); S32 len = apr_base64_decode_len(encoded.c_str()); std::vector value; - value.resize(len); - len = apr_base64_decode_binary(&value[0], encoded.c_str()); - value.resize(len); + if(len) + { + value.resize(len); + len = apr_base64_decode_binary(&value[0], encoded.c_str()); + value.resize(len); + } data = value; } - else if((c == '"') && (0 == strncmp("b16", buf, 3))) + else if(0 == strncmp("b16", buf, 3)) { // yay, base 16. We pop the next character which is either a // double quote or base 16 data. If it's a double quote, we're @@ -626,14 +810,14 @@ void LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const U8 byte_buffer[BINARY_BUFFER_SIZE]; U8* write; std::vector value; - c = istr.get(); + c = get(istr); while(c != '"') { - istr.putback(c); + putback(istr, c); read = buf; write = byte_buffer; - istr.get(buf, STREAM_GET_COUNT, '"'); - c = istr.get(); + get(istr, buf, STREAM_GET_COUNT, '"'); + c = get(istr); while(*read != '\0') /*Flawfinder: ignore*/ { byte = hex_as_nybble(*read++); @@ -648,8 +832,9 @@ void LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const } else { - data.clear(); + return false; } + return true; } @@ -666,7 +851,7 @@ LLSDBinaryParser::~LLSDBinaryParser() } // virtual -S32 LLSDBinaryParser::parse(std::istream& istr, LLSD& data) const +S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const { /** * Undefined: '!'
@@ -685,7 +870,7 @@ S32 LLSDBinaryParser::parse(std::istream& istr, LLSD& data) const * notation format. */ char c; - c = istr.get(); + c = get(istr); if(!istr.good()) { return 0; @@ -694,20 +879,42 @@ S32 LLSDBinaryParser::parse(std::istream& istr, LLSD& data) const switch(c) { case '{': - parse_count += parseMap(istr, data); + { + S32 child_count = parseMap(istr, data); + if((child_count == PARSE_FAILURE) || data.isUndefined()) + { + parse_count = PARSE_FAILURE; + } + else + { + parse_count += child_count; + } if(istr.fail()) { llinfos << "STREAM FAILURE reading binary map." << llendl; + parse_count = PARSE_FAILURE; } break; + } case '[': - parse_count += parseArray(istr, data); + { + S32 child_count = parseArray(istr, data); + if((child_count == PARSE_FAILURE) || data.isUndefined()) + { + parse_count = PARSE_FAILURE; + } + else + { + parse_count += child_count; + } if(istr.fail()) { llinfos << "STREAM FAILURE reading binary array." << llendl; + parse_count = PARSE_FAILURE; } break; + } case '!': data.clear(); @@ -724,7 +931,7 @@ S32 LLSDBinaryParser::parse(std::istream& istr, LLSD& data) const case 'i': { U32 value_nbo = 0; - istr.read((char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ + read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ data = (S32)ntohl(value_nbo); if(istr.fail()) { @@ -736,7 +943,7 @@ S32 LLSDBinaryParser::parse(std::istream& istr, LLSD& data) const case 'r': { F64 real_nbo = 0.0; - istr.read((char*)&real_nbo, sizeof(F64)); /*Flawfinder: ignore*/ + read(istr, (char*)&real_nbo, sizeof(F64)); /*Flawfinder: ignore*/ data = ll_ntohd(real_nbo); if(istr.fail()) { @@ -748,7 +955,7 @@ S32 LLSDBinaryParser::parse(std::istream& istr, LLSD& data) const case 'u': { LLUUID id; - istr.read((char*)(&id.mData), UUID_BYTES); /*Flawfinder: ignore*/ + read(istr, (char*)(&id.mData), UUID_BYTES); /*Flawfinder: ignore*/ data = id; if(istr.fail()) { @@ -761,19 +968,40 @@ S32 LLSDBinaryParser::parse(std::istream& istr, LLSD& data) const case '"': { std::string value; - deserialize_string_delim(istr, value, c); - data = value; + int cnt = deserialize_string_delim(istr, value, c); + if(PARSE_FAILURE == cnt) + { + parse_count = PARSE_FAILURE; + } + else + { + data = value; + account(cnt); + } + if(istr.fail()) + { + llinfos << "STREAM FAILURE reading binary (notation-style) string." + << llendl; + parse_count = PARSE_FAILURE; + } break; } case 's': { std::string value; - parseString(istr, value); - data = value; + if(parseString(istr, value)) + { + data = value; + } + else + { + parse_count = PARSE_FAILURE; + } if(istr.fail()) { llinfos << "STREAM FAILURE reading binary string." << llendl; + parse_count = PARSE_FAILURE; } break; } @@ -781,11 +1009,18 @@ S32 LLSDBinaryParser::parse(std::istream& istr, LLSD& data) const case 'l': { std::string value; - parseString(istr, value); - data = LLURI(value); + if(parseString(istr, value)) + { + data = LLURI(value); + } + else + { + parse_count = PARSE_FAILURE; + } if(istr.fail()) { llinfos << "STREAM FAILURE reading binary link." << llendl; + parse_count = PARSE_FAILURE; } break; } @@ -793,11 +1028,12 @@ S32 LLSDBinaryParser::parse(std::istream& istr, LLSD& data) const case 'd': { F64 real = 0.0; - istr.read((char*)&real, sizeof(F64)); /*Flawfinder: ignore*/ + read(istr, (char*)&real, sizeof(F64)); /*Flawfinder: ignore*/ data = LLDate(real); if(istr.fail()) { llinfos << "STREAM FAILURE reading binary date." << llendl; + parse_count = PARSE_FAILURE; } break; } @@ -806,75 +1042,94 @@ S32 LLSDBinaryParser::parse(std::istream& istr, LLSD& data) const { // We probably have a valid raw binary stream. determine // the size, and read it. - // *FIX: Should we set a maximum size? U32 size_nbo = 0; - istr.read((char*)&size_nbo, sizeof(U32)); /*Flawfinder: ignore*/ + read(istr, (char*)&size_nbo, sizeof(U32)); /*Flawfinder: ignore*/ S32 size = (S32)ntohl(size_nbo); - std::vector value; - if(size) + if(mCheckLimits && (size > mMaxBytesLeft)) { - value.resize(size); - istr.read((char*)&value[0], size); /*Flawfinder: ignore*/ + parse_count = PARSE_FAILURE; + } + else + { + std::vector value; + if(size > 0) + { + value.resize(size); + account(fullread(istr, (char*)&value[0], size)); + } + data = value; } - data = value; if(istr.fail()) { llinfos << "STREAM FAILURE reading binary." << llendl; + parse_count = PARSE_FAILURE; } break; } default: - --parse_count; + parse_count = PARSE_FAILURE; llinfos << "Unrecognized character while parsing: int(" << (int)c - << ")" << llendl; + << ")" << llendl; break; } + if(PARSE_FAILURE == parse_count) + { + data.clear(); + } return parse_count; } -// static -LLSD LLSDBinaryParser::parse(std::istream& istr) -{ - LLSDBinaryParser parser; - LLSD rv; - S32 count = parser.parse(istr, rv); - lldebugs << "LLSDBinaryParser::parse parsed " << count << " objects." - << llendl; - return rv; -} - S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const { map = LLSD::emptyMap(); U32 value_nbo = 0; - istr.read((char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ + read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ S32 size = (S32)ntohl(value_nbo); S32 parse_count = 0; S32 count = 0; - char c = istr.get(); + char c = get(istr); while(c != '}' && (count < size) && istr.good()) { std::string name; switch(c) { case 'k': - parseString(istr, name); + if(!parseString(istr, name)) + { + return PARSE_FAILURE; + } break; case '\'': case '"': - deserialize_string_delim(istr, name, c); + { + int cnt = deserialize_string_delim(istr, name, c); + if(PARSE_FAILURE == cnt) return PARSE_FAILURE; + account(cnt); break; } + } LLSD child; - S32 child_count = parse(istr, child); - if(child_count) + S32 child_count = doParse(istr, child); + if(child_count > 0) { + // There must be a value for every key, thus child_count + // must be greater than 0. parse_count += child_count; map.insert(name, child); } + else + { + return PARSE_FAILURE; + } ++count; - c = istr.get(); + c = get(istr); + } + if((c != '}') || (count < size)) + { + // Make sure it is correctly terminated and we parsed as many + // as were said to be there. + return PARSE_FAILURE; } return parse_count; } @@ -883,7 +1138,7 @@ S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const { array = LLSD::emptyArray(); U32 value_nbo = 0; - istr.read((char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ + read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ S32 size = (S32)ntohl(value_nbo); // *FIX: This would be a good place to reserve some space in the @@ -895,7 +1150,11 @@ S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const while((c != ']') && (count < size) && istr.good()) { LLSD child; - S32 child_count = parse(istr, child); + S32 child_count = doParse(istr, child); + if(PARSE_FAILURE == child_count) + { + return PARSE_FAILURE; + } if(child_count) { parse_count += child_count; @@ -904,22 +1163,33 @@ S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const ++count; c = istr.peek(); } - c = istr.get(); + c = get(istr); + if((c != ']') || (count < size)) + { + // Make sure it is correctly terminated and we parsed as many + // as were said to be there. + return PARSE_FAILURE; + } return parse_count; } -void LLSDBinaryParser::parseString( +bool LLSDBinaryParser::parseString( std::istream& istr, std::string& value) const { // *FIX: This is memory inefficient. U32 value_nbo = 0; - istr.read((char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ + read(istr, (char*)&value_nbo, sizeof(U32)); /*Flawfinder: ignore*/ S32 size = (S32)ntohl(value_nbo); + if(mCheckLimits && (size > mMaxBytesLeft)) return false; std::vector buf; - buf.resize(size); - istr.read(&buf[0], size); /*Flawfinder: ignore*/ - value.assign(buf.begin(), buf.end()); + if(size) + { + buf.resize(size); + account(fullread(istr, &buf[0], size)); + value.assign(buf.begin(), buf.end()); + } + return true; } @@ -1217,33 +1487,38 @@ void LLSDBinaryFormatter::formatString( /** * local functions */ -bool deserialize_string(std::istream& str, std::string& value) +int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes) { - char c = str.get(); - if (str.fail()) + char c = istr.get(); + if(istr.fail()) { - // No data in stream, bail out - return false; + // No data in stream, bail out but mention the character we + // grabbed. + return LLSDParser::PARSE_FAILURE; } - bool rv = false; + int rv = LLSDParser::PARSE_FAILURE; switch(c) { case '\'': case '"': - rv = deserialize_string_delim(str, value, c); + rv = deserialize_string_delim(istr, value, c); break; case 's': - rv = deserialize_string_raw(str, value); + // technically, less than max_bytes, but this is just meant to + // catch egregious protocol errors. parse errors will be + // caught in the case of incorrect counts. + rv = deserialize_string_raw(istr, value, max_bytes); break; default: break; } - return rv; + if(LLSDParser::PARSE_FAILURE == rv) return rv; + return rv + 1; // account for the character grabbed at the top. } -bool deserialize_string_delim( - std::istream& str, +int deserialize_string_delim( + std::istream& istr, std::string& value, char delim) { @@ -1252,16 +1527,18 @@ bool deserialize_string_delim( bool found_hex = false; bool found_digit = false; U8 byte = 0; - + int count = 0; + while (true) { - char next_char = str.get(); - - if(str.fail()) + char next_char = istr.get(); + ++count; + + if(istr.fail()) { // If our stream is empty, break out value = write_buffer.str(); - return false; + return LLSDParser::PARSE_FAILURE; } if(found_escape) @@ -1338,35 +1615,48 @@ bool deserialize_string_delim( } value = write_buffer.str(); - return true; + return count; } -bool deserialize_string_raw(std::istream& str, std::string& value) +int deserialize_string_raw( + std::istream& istr, + std::string& value, + S32 max_bytes) { - bool ok = false; + int count = 0; const S32 BUF_LEN = 20; char buf[BUF_LEN]; /* Flawfinder: ignore */ - str.get(buf, BUF_LEN - 1, ')'); - char c = str.get(); - c = str.get(); + istr.get(buf, BUF_LEN - 1, ')'); + count += istr.gcount(); + char c = istr.get(); + c = istr.get(); + count += 2; if(((c == '"') || (c == '\'')) && (buf[0] == '(')) { // We probably have a valid raw string. determine // the size, and read it. - // *FIX: Should we set a maximum size? // *FIX: This is memory inefficient. S32 len = strtol(buf + 1, NULL, 0); + if((max_bytes>0)&&(len>max_bytes)) return LLSDParser::PARSE_FAILURE; std::vector buf; - buf.resize(len); - str.read(&buf[0], len); /*Flawfinder: ignore*/ - value.assign(buf.begin(), buf.end()); - c = str.get(); - if((c == '"') || (c == '\'')) + if(len) + { + buf.resize(len); + count += fullread(istr, (char *)&buf[0], len); + value.assign(buf.begin(), buf.end()); + } + c = istr.get(); + ++count; + if(!((c == '"') || (c == '\''))) { - ok = true; + return LLSDParser::PARSE_FAILURE; } } - return ok; + else + { + return LLSDParser::PARSE_FAILURE; + } + return count; } static const char* NOTATION_STRING_CHARACTERS[256] = @@ -1641,6 +1931,43 @@ void serialize_string(const std::string& value, std::ostream& str) } } +int deserialize_boolean( + std::istream& istr, + LLSD& data, + const std::string& compare, + bool value) +{ + // + // this method is a little goofy, because it gets the stream at + // the point where the t or f has already been + // consumed. Basically, parse for a patch to the string passed in + // starting at index 1. If it's a match: + // * assign data to value + // * return the number of bytes read + // otherwise: + // * set data to LLSD::null + // * return LLSDParser::PARSE_FAILURE (-1) + // + int bytes_read = 0; + std::string::size_type ii = 0; + char c = istr.peek(); + while((++ii < compare.size()) + && (tolower(c) == (int)compare[ii]) + && istr.good()) + { + istr.ignore(); + ++bytes_read; + c = istr.peek(); + } + if(compare.size() != ii) + { + data.clear(); + return LLSDParser::PARSE_FAILURE; + } + data = value; + return bytes_read; +} + std::ostream& operator<<(std::ostream& s, const LLSD& llsd) { s << LLSDNotationStreamer(llsd); diff --git a/linden/indra/llcommon/llsdserialize.h b/linden/indra/llcommon/llsdserialize.h index e1e81d5..41e0aa5 100644 --- a/linden/indra/llcommon/llsdserialize.h +++ b/linden/indra/llcommon/llsdserialize.h @@ -40,7 +40,7 @@ /** * @class LLSDParser - * @brief Abstract base class for simple LLSD parsers. + * @brief Abstract base class for LLSD parsers. */ class LLSDParser : public LLRefCount { @@ -52,6 +52,14 @@ protected: public: /** + * @brief Anonymous enum to indicate parsing failure. + */ + enum + { + PARSE_FAILURE = -1 + }; + + /** * @brief Constructor */ LLSDParser(); @@ -67,12 +75,122 @@ public: * caller. * @param istr The input stream. * @param data[out] The newly parse structured data. - * @return Returns The number of LLSD objects parsed into data. + * @param max_bytes The maximum number of bytes that will be in + * the stream. Pass in LLSDSerialize::SIZE_UNLIMITED (-1) to set no + * byte limit. + * @return Returns the number of LLSD objects parsed into + * data. Returns PARSE_FAILURE (-1) on parse failure. + */ + S32 parse(std::istream& istr, LLSD& data, S32 max_bytes); + +protected: + /** + * @brief Pure virtual base for doing the parse. + * + * This method parses the istream for a structured data. This + * method assumes that the istream is a complete llsd object -- + * for example an opened and closed map with an arbitrary nesting + * of elements. This method will return after reading one data + * object, allowing continued reading from the stream by the + * caller. + * @param istr The input stream. + * @param data[out] The newly parse structured data. + * @return Returns the number of LLSD objects parsed into + * data. Returns PARSE_FAILURE (-1) on parse failure. + */ + virtual S32 doParse(std::istream& istr, LLSD& data) const = 0; + + /* @name Simple istream helper methods + * + * These helper methods exist to help correctly use the + * mMaxBytesLeft without really thinking about it for most simple + * operations. Use of the streamtools in llstreamtools.h will + * require custom wrapping. + */ + //@{ + /** + * @brief get a byte off the stream + * + * @param istr The istream to work with. + * @return returns the next character. + */ + int get(std::istream& istr) const; + + /** + * @brief get several bytes off the stream into a buffer. + * + * @param istr The istream to work with. + * @param s The buffer to get into + * @param n Extract maximum of n-1 bytes and null temrinate. + * @param delim Delimiter to get until found. + * @return Returns istr. + */ + std::istream& get( + std::istream& istr, + char* s, + std::streamsize n, + char delim) const; + + /** + * @brief get several bytes off the stream into a streambuf + * + * @param istr The istream to work with. + * @param sb The streambuf to read into + * @param delim Delimiter to get until found. + * @return Returns istr. + */ + std::istream& get( + std::istream& istr, + std::streambuf& sb, + char delim) const; + + /** + * @brief ignore the next byte on the istream + * + * @param istr The istream to work with. + * @return Returns istr. + */ + std::istream& ignore(std::istream& istr) const; + + /** + * @brief put the last character retrieved back on the stream + * + * @param istr The istream to work with. + * @param c The character to put back + * @return Returns istr. + */ + std::istream& putback(std::istream& istr, char c) const; + + /** + * @brief read a block of n characters into a buffer + * + * @param istr The istream to work with. + * @param s The buffer to read into + * @param n The number of bytes to read. + * @return Returns istr. + */ + std::istream& read(std::istream& istr, char* s, std::streamsize n) const; + //@} + +protected: + /** + * @brief Accunt for bytes read outside of the istream helpers. + * + * Conceptually const since it only modifies mutable members. + * @param bytes The number of bytes read. */ - virtual S32 parse(std::istream& istr, LLSD& data) const = 0; + void account(S32 bytes) const; protected: + /** + * @brief boolean to set if byte counts should be checked during parsing. + */ + bool mCheckLimits; + /** + * @brief The maximum number of bytes left to be parsed. + */ + mutable S32 mMaxBytesLeft; }; /** @@ -91,8 +209,9 @@ public: /** * @brief Constructor */ - LLSDNotationParser() {} + LLSDNotationParser(); +protected: /** * @brief Call this method to parse a stream for LLSD. * @@ -105,21 +224,9 @@ public: * @param istr The input stream. * @param data[out] The newly parse structured data. Undefined on failure. * @return Returns the number of LLSD objects parsed into - * data. Returns -1 on parse failure. - */ - virtual S32 parse(std::istream& istr, LLSD& data) const; - - /** - * @brief Simple notation parse. - * - * This simplified parser cannot not distinguish between a failed - * parse and a parse which yields a single undefined LLSD. You can - * use this if error checking will be implicit in the use of the - * results of the parse. - * @param istr The input stream. - * @return Returns the parsed LLSD object. + * data. Returns PARSE_FAILURE (-1) on parse failure. */ - static LLSD parse(std::istream& istr); + virtual S32 doParse(std::istream& istr, LLSD& data) const; private: /** @@ -145,16 +252,18 @@ private: * * @param istr The input stream. * @param data[out] The data to assign. + * @return Retuns true if a complete string was parsed. */ - void parseString(std::istream& istr, LLSD& data) const; + bool parseString(std::istream& istr, LLSD& data) const; /** * @brief Parse binary data from the stream. * * @param istr The input stream. * @param data[out] The data to assign. + * @return Retuns true if a complete blob was parsed. */ - void parseBinary(std::istream& istr, LLSD& data) const; + bool parseBinary(std::istream& istr, LLSD& data) const; }; /** @@ -175,6 +284,7 @@ public: */ LLSDXMLParser(); +protected: /** * @brief Call this method to parse a stream for LLSD. * @@ -186,15 +296,16 @@ public: * caller. * @param istr The input stream. * @param data[out] The newly parse structured data. - * @return Returns the number of LLSD objects parsed into data. + * @return Returns the number of LLSD objects parsed into + * data. Returns PARSE_FAILURE (-1) on parse failure. */ - virtual S32 parse(std::istream& istr, LLSD& data) const; + virtual S32 doParse(std::istream& istr, LLSD& data) const; private: class Impl; Impl& impl; - void parsePart(const char *buf, int len); + void parsePart(const char* buf, int len); friend class LLSDSerialize; }; @@ -216,6 +327,7 @@ public: */ LLSDBinaryParser(); +protected: /** * @brief Call this method to parse a stream for LLSD. * @@ -227,21 +339,10 @@ public: * caller. * @param istr The input stream. * @param data[out] The newly parse structured data. - * @return Returns the number of LLSD objects parsed into data. - */ - virtual S32 parse(std::istream& istr, LLSD& data) const; - - /** - * @brief Simple notation parse. - * - * This simplified parser cannot not distinguish between a failed - * parse and a parse which yields a single undefined LLSD. You can - * use this if error checking will be implicit in the use of the - * results of the parse. - * @param istr The input stream. - * @return Returns the parsed LLSD object. + * @return Returns the number of LLSD objects parsed into + * data. Returns -1 on parse failure. */ - static LLSD parse(std::istream& istr); + virtual S32 doParse(std::istream& istr, LLSD& data) const; private: /** @@ -267,8 +368,9 @@ private: * * @param istr The input stream. * @param value[out] The string to assign. + * @return Retuns true if a complete string was parsed. */ - void parseString(std::istream& istr, std::string& value) const; + bool parseString(std::istream& istr, std::string& value) const; }; @@ -544,7 +646,7 @@ typedef LLSDOStreamer LLSDXMLStreamer; /** * @class LLSDSerialize - * @Serializer / deserializer for the various LLSD formats + * @brief Serializer / deserializer for the various LLSD formats */ class LLSDSerialize { @@ -554,12 +656,32 @@ public: LLSD_BINARY, LLSD_XML }; + /** + * @brief anonymouse enumeration for useful max_bytes constants. + */ + enum + { + // Setting an unlimited size is discouraged and should only be + // used when reading cin or another stream source which does + // not provide access to size. + SIZE_UNLIMITED = -1, + }; + /* * Generic in/outs */ static void serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize, U32 options = LLSDFormatter::OPTIONS_NONE); - static bool deserialize(LLSD& sd, std::istream& str); + + /** + * @breif Examine a stream, and parse 1 sd object out based on contents. + * + * @param sd [out] The data found on the stream + * @param str The incoming stream + * @param max_bytes the maximum number of bytes to parse + * @return Returns true if the stream appears to contain valid data + */ + static bool deserialize(LLSD& sd, std::istream& str, S32 max_bytes); /* * Notation Methods @@ -569,10 +691,17 @@ public: LLPointer f = new LLSDNotationFormatter; return f->format(sd, str, LLSDFormatter::OPTIONS_NONE); } - static S32 fromNotation(LLSD& sd, std::istream& str) + static S32 fromNotation(LLSD& sd, std::istream& str, S32 max_bytes) + { + LLPointer p = new LLSDNotationParser; + return p->parse(str, sd, max_bytes); + } + static LLSD fromNotation(std::istream& str, S32 max_bytes) { LLPointer p = new LLSDNotationParser; - return p->parse(str, sd); + LLSD sd; + (void)p->parse(str, sd, max_bytes); + return sd; } /* @@ -588,10 +717,13 @@ public: LLPointer f = new LLSDXMLFormatter; return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY); } + static S32 fromXML(LLSD& sd, std::istream& str) { + // no need for max_bytes since xml formatting is not + // subvertable by bad sizes. LLPointer p = new LLSDXMLParser; - return p->parse(str, sd); + return p->parse(str, sd, LLSDSerialize::SIZE_UNLIMITED); } /* @@ -602,14 +734,18 @@ public: LLPointer f = new LLSDBinaryFormatter; return f->format(sd, str, LLSDFormatter::OPTIONS_NONE); } - static S32 fromBinary(LLSD& sd, std::istream& str) + static S32 fromBinary(LLSD& sd, std::istream& str, S32 max_bytes) { LLPointer p = new LLSDBinaryParser; - return p->parse(str, sd); + return p->parse(str, sd, max_bytes); + } + static LLSD fromBinary(std::istream& str, S32 max_bytes) + { + LLPointer p = new LLSDBinaryParser; + LLSD sd; + (void)p->parse(str, sd, max_bytes); + return sd; } -private: - static const char *LLSDBinaryHeader; - static const char *LLSDXMLHeader; }; #endif // LL_LLSDSERIALIZE_H diff --git a/linden/indra/llcommon/llsdserialize_xml.cpp b/linden/indra/llcommon/llsdserialize_xml.cpp index b8adcf1..7de0c35 100644 --- a/linden/indra/llcommon/llsdserialize_xml.cpp +++ b/linden/indra/llcommon/llsdserialize_xml.cpp @@ -305,6 +305,7 @@ private: XML_Parser mParser; LLSD mResult; + S32 mParseCount; bool mInLLSDElement; bool mGracefullStop; @@ -411,12 +412,12 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data) } llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl; data = LLSD(); - return -1; + return LLSDParser::PARSE_FAILURE; } clear_eol(input); data = mResult; - return 1; + return mParseCount; } void LLSDXMLParser::Impl::reset() @@ -428,6 +429,7 @@ void LLSDXMLParser::Impl::reset() } mResult.clear(); + mParseCount = 0; mInLLSDElement = false; mDepth = 0; @@ -472,7 +474,7 @@ LLSDXMLParser::Impl::findAttribute(const XML_Char* name, const XML_Char** pairs) return NULL; } -void LLSDXMLParser::Impl::parsePart(const char *buf, int len) +void LLSDXMLParser::Impl::parsePart(const char* buf, int len) { void * buffer = XML_GetBuffer(mParser, len); if (buffer != NULL && buf != NULL) @@ -486,7 +488,7 @@ void LLSDXMLParser::Impl::parsePart(const char *buf, int len) void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Char** attributes) { - mDepth += 1; + ++mDepth; if (mSkipping) { return; @@ -554,6 +556,7 @@ void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Ch return startSkipping(); } + ++mParseCount; switch (element) { case ELEMENT_MAP: @@ -572,7 +575,7 @@ void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Ch void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name) { - mDepth -= 1; + --mDepth; if (mSkipping) { if (mDepth < mSkipThrough) @@ -715,10 +718,10 @@ LLSDXMLParser::Impl::Element LLSDXMLParser::Impl::readElement(const XML_Char* na - - -LLSDXMLParser::LLSDXMLParser() - : impl(* new Impl) +/** + * LLSDXMLParser + */ +LLSDXMLParser::LLSDXMLParser() : impl(* new Impl) { } @@ -733,7 +736,7 @@ void LLSDXMLParser::parsePart(const char *buf, int len) } // virtual -S32 LLSDXMLParser::parse(std::istream& input, LLSD& data) const +S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const { return impl.parse(input, data); } diff --git a/linden/indra/llcommon/llstreamtools.cpp b/linden/indra/llcommon/llstreamtools.cpp index 5419b24..669bdd0 100644 --- a/linden/indra/llcommon/llstreamtools.cpp +++ b/linden/indra/llcommon/llstreamtools.cpp @@ -538,23 +538,32 @@ void get_keyword_and_value(std::string& keyword, } } -std::istream& fullread(std::istream& str, char *buf, std::streamsize requested) +std::streamsize fullread( + std::istream& istr, + char* buf, + std::streamsize requested) { std::streamsize got; std::streamsize total = 0; - str.read(buf, requested); /*Flawfinder: ignore*/ - got = str.gcount(); + istr.read(buf, requested); /*Flawfinder: ignore*/ + got = istr.gcount(); total += got; - while (got && total < requested) + while(got && total < requested) { - if (str.fail()) - str.clear(); - str.read(buf + total, requested - total); /*Flawfinder: ignore*/ - got = str.gcount(); + if(istr.fail()) + { + // If bad is true, not much we can doo -- it implies loss + // of stream integrity. Bail in that case, and otherwise + // clear and attempt to continue. + if(istr.bad()) return total; + istr.clear(); + } + istr.read(buf + total, requested - total); /*Flawfinder: ignore*/ + got = istr.gcount(); total += got; } - return str; + return total; } std::istream& operator>>(std::istream& str, const char *tocheck) diff --git a/linden/indra/llcommon/llstreamtools.h b/linden/indra/llcommon/llstreamtools.h index 0114e4c..9db90c8 100644 --- a/linden/indra/llcommon/llstreamtools.h +++ b/linden/indra/llcommon/llstreamtools.h @@ -114,7 +114,12 @@ void get_keyword_and_value(std::string& keyword, // continue to read from the stream until you really can't // read anymore or until we hit the count. Some istream // implimentations have a max that they will read. -std::istream& fullread(std::istream& str, char *buf, std::streamsize requested); +// Returns the number of bytes read. +std::streamsize fullread( + std::istream& istr, + char* buf, + std::streamsize requested); + std::istream& operator>>(std::istream& str, const char *tocheck); diff --git a/linden/indra/llcommon/llsys.cpp b/linden/indra/llcommon/llsys.cpp index 2a6e466..ccdcd00 100644 --- a/linden/indra/llcommon/llsys.cpp +++ b/linden/indra/llcommon/llsys.cpp @@ -679,7 +679,8 @@ BOOL gunzip_file(const char *srcfile, const char *dstfile) size_t nwrit = fwrite(buffer, sizeof(U8), bytes, dst); if (nwrit < (size_t) bytes) { - llerrs << "Short write on " << tmpfile << llendl; + llwarns << "Short write on " << tmpfile << ": Wrote " << nwrit << " of " << bytes << " bytes." << llendl; + goto err; } } while(gzeof(src) == 0); fclose(dst); diff --git a/linden/indra/llcommon/llthread.cpp b/linden/indra/llcommon/llthread.cpp index c0e92ca..48ebc4b 100644 --- a/linden/indra/llcommon/llthread.cpp +++ b/linden/indra/llcommon/llthread.cpp @@ -31,6 +31,8 @@ #include "linden_common.h" #include "llapr.h" +#include "apr-1/apr_portable.h" + #include "llthread.h" #include "lltimer.h" @@ -225,6 +227,11 @@ void LLThread::setQuitting() wake(); } +// static +U32 LLThread::currentID() +{ + return (U32)apr_os_thread_current(); +} // static void LLThread::yield() diff --git a/linden/indra/llcommon/llthread.h b/linden/indra/llcommon/llthread.h index 5c71c34..608b218 100644 --- a/linden/indra/llcommon/llthread.h +++ b/linden/indra/llcommon/llthread.h @@ -56,14 +56,14 @@ public: virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state. virtual void shutdown(); // stops the thread - static void yield(); // Static because it can be called by the main thread, which doesn't have an LLThread data structure. - - bool isQuitting() const { return (QUITTING == mStatus); } bool isStopped() const { return (STOPPED == mStatus); } - // PAUSE / RESUME functionality. See source code for important usage notes. + static U32 currentID(); // Return ID of current thread + static void yield(); // Static because it can be called by the main thread, which doesn't have an LLThread data structure. + public: + // PAUSE / RESUME functionality. See source code for important usage notes. // Called from MAIN THREAD. void pause(); void unpause(); @@ -127,7 +127,7 @@ protected: class LLMutex { public: - LLMutex(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well. + LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex ~LLMutex(); void lock(); // blocks diff --git a/linden/indra/llcommon/llversionserver.h b/linden/indra/llcommon/llversionserver.h index 079fa85..922e4ac 100644 --- a/linden/indra/llcommon/llversionserver.h +++ b/linden/indra/llcommon/llversionserver.h @@ -33,9 +33,9 @@ #define LL_LLVERSIONSERVER_H const S32 LL_VERSION_MAJOR = 1; -const S32 LL_VERSION_MINOR = 18; -const S32 LL_VERSION_PATCH = 6; -const S32 LL_VERSION_BUILD = 76747; +const S32 LL_VERSION_MINOR = 19; +const S32 LL_VERSION_PATCH = 1; +const S32 LL_VERSION_BUILD = 80913; const char * const LL_CHANNEL = "Second Life Server"; diff --git a/linden/indra/llcommon/llversionviewer.h b/linden/indra/llcommon/llversionviewer.h index c14efe8..c1e6778 100644 --- a/linden/indra/llcommon/llversionviewer.h +++ b/linden/indra/llcommon/llversionviewer.h @@ -34,8 +34,8 @@ const S32 LL_VERSION_MAJOR = 1; const S32 LL_VERSION_MINOR = 19; -const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 5; +const S32 LL_VERSION_PATCH = 1; +const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Release"; diff --git a/linden/indra/llcrashlogger/llcrashlogger.cpp b/linden/indra/llcrashlogger/llcrashlogger.cpp index ab464bd..ebd2303 100755 --- a/linden/indra/llcrashlogger/llcrashlogger.cpp +++ b/linden/indra/llcrashlogger/llcrashlogger.cpp @@ -119,8 +119,10 @@ void LLCrashLogger::gatherFiles() updateApplication("Gathering logs..."); // Figure out the filename of the debug log - LLString db_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log").c_str(); - std::ifstream debug_log_file(db_file_name.c_str()); + std::string db_file_name = gDirUtilp->getExpandedFilename( + LL_PATH_LOGS, + "debug_info.log"); + llifstream debug_log_file(db_file_name.c_str()); // Look for it in the debug_info.log file if (debug_log_file.is_open()) @@ -128,14 +130,14 @@ void LLCrashLogger::gatherFiles() LLSDSerialize::fromXML(mDebugLog, debug_log_file); mFileMap["SecondLifeLog"] = mDebugLog["SLLog"].asString(); mFileMap["SettingsXml"] = mDebugLog["SettingsFilename"].asString(); - LLHTTPClient::setCABundle(mDebugLog["CAFilename"].asString()); + LLCurl::setCAFile(mDebugLog["CAFilename"].asString()); llinfos << "Using log file from debug log " << mFileMap["SecondLifeLog"] << llendl; llinfos << "Using settings file from debug log " << mFileMap["SettingsXml"] << llendl; } else { // Figure out the filename of the second life log - LLHTTPClient::setCABundle(gDirUtilp->getCAFile()); + LLCurl::setCAFile(gDirUtilp->getCAFile()); mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log"); mFileMap["SettingsXml"] = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml"); } diff --git a/linden/indra/llimage/llimage.vcproj b/linden/indra/llimage/llimage.vcproj index aeb3e8e..d6689ae 100644 --- a/linden/indra/llimage/llimage.vcproj +++ b/linden/indra/llimage/llimage.vcproj @@ -20,7 +20,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="..\llcommon;..\llmath; ..\llvfs; ..\..\libraries\i686-win32\include;..\..\libraries\include\" - PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;LL_DEBUG" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;LL_DEBUG;JPEG_SUPPORT" MinimalRebuild="TRUE" BasicRuntimeChecks="3" RuntimeLibrary="1" @@ -70,7 +70,7 @@ OptimizeForProcessor="3" OptimizeForWindowsApplication="TRUE" AdditionalIncludeDirectories="..\llcommon;..\llmath; ..\llvfs; ..\..\libraries\i686-win32\include;..\..\libraries\include\" - PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE;JPEG_SUPPORT" RuntimeLibrary="0" StructMemberAlignment="0" ForceConformanceInForLoopScope="TRUE" @@ -114,7 +114,7 @@ AdditionalOptions="/Oy-" Optimization="0" AdditionalIncludeDirectories="..\llcommon;..\llmath; ..\llvfs; ..\..\libraries\i686-win32\include;..\..\libraries\include\" - PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE" + PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE;JPEG_SUPPORT" RuntimeLibrary="0" StructMemberAlignment="0" ForceConformanceInForLoopScope="TRUE" diff --git a/linden/indra/llimage/llimage_vc8.vcproj b/linden/indra/llimage/llimage_vc8.vcproj index 7030436..4265ea4 100644 --- a/linden/indra/llimage/llimage_vc8.vcproj +++ b/linden/indra/llimage/llimage_vc8.vcproj @@ -1,325 +1,325 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llimage/llimage_vc9.vcproj b/linden/indra/llimage/llimage_vc9.vcproj index 67ff6b3..244bc78 100644 --- a/linden/indra/llimage/llimage_vc9.vcproj +++ b/linden/indra/llimage/llimage_vc9.vcproj @@ -1,326 +1,326 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llinventory/llinventory.cpp b/linden/indra/llinventory/llinventory.cpp index 3e3290c..e6c1175 100644 --- a/linden/indra/llinventory/llinventory.cpp +++ b/linden/indra/llinventory/llinventory.cpp @@ -54,6 +54,7 @@ static const std::string INV_INVENTORY_TYPE_LABEL("inv_type"); static const std::string INV_NAME_LABEL("name"); static const std::string INV_DESC_LABEL("desc"); static const std::string INV_PERMISSIONS_LABEL("permissions"); +static const std::string INV_SHADOW_ID_LABEL("shadow_id"); static const std::string INV_ASSET_ID_LABEL("asset_id"); static const std::string INV_SALE_INFO_LABEL("sale_info"); static const std::string INV_FLAGS_LABEL("flags"); @@ -927,34 +928,34 @@ BOOL LLInventoryItem::exportLegacyStream(std::ostream& output_stream, BOOL inclu LLSD LLInventoryItem::asLLSD() const { LLSD sd = LLSD(); - sd["item_id"] = mUUID; - sd["parent_id"] = mParentUUID; - sd["permissions"] = ll_create_sd_from_permissions(mPermissions); + sd[INV_ITEM_ID_LABEL] = mUUID; + sd[INV_PARENT_ID_LABEL] = mParentUUID; + sd[INV_PERMISSIONS_LABEL] = ll_create_sd_from_permissions(mPermissions); U32 mask = mPermissions.getMaskBase(); if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) || (mAssetUUID.isNull())) { - sd["asset_id"] = mAssetUUID; + sd[INV_ASSET_ID_LABEL] = mAssetUUID; } else { LLUUID shadow_id(mAssetUUID); LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES); cipher.encrypt(shadow_id.mData, UUID_BYTES); - sd["shadow_id"] = shadow_id; + sd[INV_SHADOW_ID_LABEL] = shadow_id; } - sd["type"] = LLAssetType::lookup(mType); + sd[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType); const char* inv_type_str = LLInventoryType::lookup(mInventoryType); if(inv_type_str) { - sd["inv_type"] = inv_type_str; + sd[INV_INVENTORY_TYPE_LABEL] = inv_type_str; } - sd["flags"] = ll_sd_from_U32(mFlags); - sd["sale_info"] = mSaleInfo; - sd["name"] = mName; - sd["desc"] = mDescription; - sd["creation_date"] = mCreationDate; + sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags); + sd[INV_SALE_INFO_LABEL] = mSaleInfo; + sd[INV_NAME_LABEL] = mName; + sd[INV_DESC_LABEL] = mDescription; + sd[INV_CREATION_DATE_LABEL] = mCreationDate; return sd; } @@ -1007,7 +1008,7 @@ bool LLInventoryItem::fromLLSD(LLSD& sd) mPermissions.setMaskNext(perm_mask); } } - w = "shadow_id"; + w = INV_SHADOW_ID_LABEL; if (sd.has(w)) { mAssetUUID = sd[w]; @@ -1357,6 +1358,19 @@ void LLInventoryCategory::setPreferredType(LLAssetType::EType type) mPreferredType = type; } +LLSD LLInventoryCategory::asLLSD() const +{ + LLSD sd = LLSD(); + sd["item_id"] = mUUID; + sd["parent_id"] = mParentUUID; + S8 type = static_cast(mPreferredType); + sd["type"] = type; + sd["name"] = mName; + + return sd; +} + + // virtual void LLInventoryCategory::packMessage(LLMessageSystem* msg) const { @@ -1367,6 +1381,36 @@ void LLInventoryCategory::packMessage(LLMessageSystem* msg) const msg->addStringFast(_PREHASH_Name, mName); } +bool LLInventoryCategory::fromLLSD(LLSD& sd) +{ + std::string w; + + w = INV_ITEM_ID_LABEL; + if (sd.has(w)) + { + mUUID = sd[w]; + } + w = INV_PARENT_ID_LABEL; + if (sd.has(w)) + { + mParentUUID = sd[w]; + } + w = INV_ASSET_TYPE_LABEL; + if (sd.has(w)) + { + S8 type = (U8)sd[w].asInteger(); + mPreferredType = static_cast(type); + } + w = INV_NAME_LABEL; + if (sd.has(w)) + { + mName = sd[w].asString(); + LLString::replaceNonstandardASCII(mName, ' '); + LLString::replaceChar(mName, '|', ' '); + } + return true; +} + // virtual void LLInventoryCategory::unpackMessage(LLMessageSystem* msg, const char* block, diff --git a/linden/indra/llinventory/llinventory.h b/linden/indra/llinventory/llinventory.h index 76d439b..3662d63 100644 --- a/linden/indra/llinventory/llinventory.h +++ b/linden/indra/llinventory/llinventory.h @@ -230,7 +230,6 @@ public: // network ok. It uses a simple crc check which is defeatable, but // we want to detect network mangling somehow. virtual BOOL unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0); - // file support virtual BOOL importFile(FILE* fp); virtual BOOL exportFile(FILE* fp, BOOL include_asset_key = TRUE) const; @@ -288,6 +287,9 @@ public: virtual void packMessage(LLMessageSystem* msg) const; virtual void unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0); + LLSD asLLSD() const; + bool fromLLSD(LLSD& sd); + // file support virtual BOOL importFile(FILE* fp); virtual BOOL exportFile(FILE* fp, BOOL include_asset_key = TRUE) const; diff --git a/linden/indra/llinventory/llinventory_vc8.vcproj b/linden/indra/llinventory/llinventory_vc8.vcproj index 306e6a5..34dadc9 100644 --- a/linden/indra/llinventory/llinventory_vc8.vcproj +++ b/linden/indra/llinventory/llinventory_vc8.vcproj @@ -1,347 +1,347 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llinventory/llinventory_vc9.vcproj b/linden/indra/llinventory/llinventory_vc9.vcproj index c48b962..cdc6c43 100644 --- a/linden/indra/llinventory/llinventory_vc9.vcproj +++ b/linden/indra/llinventory/llinventory_vc9.vcproj @@ -1,348 +1,348 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llinventory/llparcel.cpp b/linden/indra/llinventory/llparcel.cpp index f8fb4d5..5f8a000 100644 --- a/linden/indra/llinventory/llparcel.cpp +++ b/linden/indra/llinventory/llparcel.cpp @@ -42,6 +42,7 @@ #include "llsdutil.h" #include "lltransactiontypes.h" #include "lltransactionflags.h" +#include "llsdutil.h" #include "message.h" #include "u64.h" @@ -170,73 +171,80 @@ void LLParcel::init(const LLUUID &owner_id, S32 rent_price_per_meter, S32 area, S32 sim_object_limit, F32 parcel_object_bonus, BOOL is_group_owned) { - mID.setNull(); - mOwnerID = owner_id; - mGroupOwned = is_group_owned; - mClaimDate = claim_date; - mClaimPricePerMeter = claim_price_per_meter; - mRentPricePerMeter = rent_price_per_meter; - mArea = area; - mDiscountRate = 1.0f; - mDrawDistance = 512.f; - - mUserLookAt.setVec(0.0f, 0.f, 0.f); - // Default to using the parcel's landing point, if any. - mLandingType = L_LANDING_POINT; - - // *FIX: if owner_id != null, should be owned or sale pending, - // investigate init callers. - mStatus = OS_NONE; - mCategory = C_NONE; - mAuthBuyerID.setNull(); - //mBuyerID.setNull(); - //mJoinNeighbors = 0x0; - mSaleTimerExpires.setTimerExpirySec(0); - mSaleTimerExpires.stop(); - mGraceExtension = 0; - //mExpireAction = STEA_REVERT; - mRecordTransaction = FALSE; - - mAuctionID = 0; - mInEscrow = false; - - mParcelFlags = PF_DEFAULT; - setParcelFlag(PF_CREATE_OBJECTS, modify); - setParcelFlag(PF_ALLOW_TERRAFORM, terraform); - setParcelFlag(PF_ALLOW_DAMAGE, damage); - - mSalePrice = 10000; - setName(NULL); - setDesc(NULL); - setMusicURL(NULL); - setMediaURL(NULL); - mMediaID.setNull(); - mMediaAutoScale = 0; - - mGroupID.setNull(); - - mPassPrice = PARCEL_PASS_PRICE_DEFAULT; - mPassHours = PARCEL_PASS_HOURS_DEFAULT; - - mAABBMin.setVec(SOME_BIG_NUMBER, SOME_BIG_NUMBER, SOME_BIG_NUMBER); - mAABBMax.setVec(SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER); - - mLocalID = 0; - - //mSimWidePrimCorrection = 0; - setMaxPrimCapacity((S32)(sim_object_limit * area / (F32)(REGION_WIDTH_METERS * REGION_WIDTH_METERS))); - setSimWideMaxPrimCapacity(0); - setSimWidePrimCount(0); - setOwnerPrimCount(0); - setGroupPrimCount(0); - setOtherPrimCount(0); - setSelectedPrimCount(0); - setTempPrimCount(0); - setCleanOtherTime(0); - setParcelPrimBonus(parcel_object_bonus); - - setPreviousOwnerID(LLUUID::null); - setPreviouslyGroupOwned(FALSE); + mID.setNull(); + mOwnerID = owner_id; + mGroupOwned = is_group_owned; + mClaimDate = claim_date; + mClaimPricePerMeter = claim_price_per_meter; + mRentPricePerMeter = rent_price_per_meter; + mArea = area; + mDiscountRate = 1.0f; + mDrawDistance = 512.f; + + mUserLookAt.setVec(0.0f, 0.f, 0.f); + // Default to using the parcel's landing point, if any. + mLandingType = L_LANDING_POINT; + + // *FIX: if owner_id != null, should be owned or sale pending, + // investigate init callers. + mStatus = OS_NONE; + mCategory = C_NONE; + mAuthBuyerID.setNull(); + //mBuyerID.setNull(); + //mJoinNeighbors = 0x0; + mSaleTimerExpires.setTimerExpirySec(0); + mSaleTimerExpires.stop(); + mGraceExtension = 0; + //mExpireAction = STEA_REVERT; + mRecordTransaction = FALSE; + + mAuctionID = 0; + mInEscrow = false; + + mParcelFlags = PF_DEFAULT; + setParcelFlag(PF_CREATE_OBJECTS, modify); + setParcelFlag(PF_ALLOW_TERRAFORM, terraform); + setParcelFlag(PF_ALLOW_DAMAGE, damage); + + mSalePrice = 10000; + setName(NULL); + setDesc(NULL); + setMusicURL(NULL); + setMediaURL(NULL); + setMediaDesc(NULL); + setMediaType(NULL); + mMediaID.setNull(); + mMediaAutoScale = 0; + mMediaLoop = TRUE; + mObscureMedia = 0; + mObscureMusic = 0; + mMediaWidth = 0; + mMediaHeight = 0; + + mGroupID.setNull(); + + mPassPrice = PARCEL_PASS_PRICE_DEFAULT; + mPassHours = PARCEL_PASS_HOURS_DEFAULT; + + mAABBMin.setVec(SOME_BIG_NUMBER, SOME_BIG_NUMBER, SOME_BIG_NUMBER); + mAABBMax.setVec(SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER, SOME_BIG_NEG_NUMBER); + + mLocalID = 0; + + //mSimWidePrimCorrection = 0; + setMaxPrimCapacity((S32)(sim_object_limit * area / (F32)(REGION_WIDTH_METERS * REGION_WIDTH_METERS))); + setSimWideMaxPrimCapacity(0); + setSimWidePrimCount(0); + setOwnerPrimCount(0); + setGroupPrimCount(0); + setOtherPrimCount(0); + setSelectedPrimCount(0); + setTempPrimCount(0); + setCleanOtherTime(0); + setParcelPrimBonus(parcel_object_bonus); + + setPreviousOwnerID(LLUUID::null); + setPreviouslyGroupOwned(FALSE); } void LLParcel::overrideOwner(const LLUUID& owner_id, BOOL is_group_owned) @@ -260,7 +268,21 @@ void LLParcel::overrideParcelFlags(U32 flags) { mParcelFlags = flags; } - +void set_std_string(const char* src, std::string& dest) +{ + if(src) + { + dest.assign(src); + } + else + { +#if (LL_LINUX && __GNUC__ < 3) + dest.assign(std::string("")); +#else + dest.clear(); +#endif + } +} void LLParcel::setName(const LLString& name) { // The escaping here must match the escaping in the database @@ -297,6 +319,34 @@ void LLParcel::setMediaURL(const LLString& url) LLStringFn::replace_nonprintable(mMediaURL, LL_UNKNOWN_CHAR); } +void LLParcel::setMediaDesc(const char* desc) +{ + // The escaping here must match the escaping in the database + // abstraction layer. + set_std_string(desc, mMediaDesc); + mMediaDesc = rawstr_to_utf8(mMediaDesc); +} +void LLParcel::setMediaType(const char* type) +{ + // The escaping here must match the escaping in the database + // abstraction layer. + set_std_string(type, mMediaType); + mMediaType = rawstr_to_utf8(mMediaType); + + // This code attempts to preserve legacy movie functioning + if(mMediaType.empty() && ! mMediaURL.empty()) + { + setMediaType("video/vnd.secondlife.qt.legacy"); + } +} +void LLParcel::setMediaWidth(S32 width) +{ + mMediaWidth = width; +} +void LLParcel::setMediaHeight(S32 height) +{ + mMediaHeight = height; +} // virtual void LLParcel::setLocalID(S32 local_id) { @@ -512,338 +562,367 @@ void LLParcel::setDiscountRate(F32 rate) // WARNING: Area will be wrong until you calculate it. BOOL LLParcel::importStream(std::istream& input_stream) { - U32 setting; - S32 secs_until_revert = 0; - - skip_to_end_of_next_keyword("{", input_stream); - if (!input_stream.good()) - { - llwarns << "LLParcel::importStream() - bad input_stream" << llendl; - return FALSE; - } - - while (input_stream.good()) - { - skip_comments_and_emptyspace(input_stream); - LLString line, keyword, value; - get_line(line, input_stream, MAX_STRING); - get_keyword_and_value(keyword, value, line); - - if ("}" == keyword) - { - break; - } - else if ("parcel_id" == keyword) - { - mID.set(value.c_str()); - } - else if ("status" == keyword) - { - mStatus = ownership_string_to_status(value.c_str()); - } - else if ("category" == keyword) - { - mCategory = category_string_to_category(value.c_str()); - } - else if ("local_id" == keyword) - { - LLString::convertToS32(value, mLocalID); - } - else if ("name" == keyword) - { - setName( value ); - } - else if ("desc" == keyword) - { - setDesc( value ); - } - else if ("music_url" == keyword) - { - setMusicURL( value ); - } - else if ("media_url" == keyword) - { - setMediaURL( value ); - } - else if ("media_id" == keyword) - { - mMediaID.set( value.c_str() ); - } - else if ("media_auto_scale" == keyword) - { - LLString::convertToU8(value, mMediaAutoScale); - } - else if ("owner_id" == keyword) - { - mOwnerID.set( value.c_str() ); - } - else if ("group_owned" == keyword) - { - LLString::convertToBOOL(value, mGroupOwned); - } - else if ("clean_other_time" == keyword) - { - S32 time; - LLString::convertToS32(value, time); - setCleanOtherTime(time); - } - else if ("auth_buyer_id" == keyword) - { - mAuthBuyerID.set(value.c_str()); - } - else if ("snapshot_id" == keyword) - { - mSnapshotID.set(value.c_str()); - } - else if ("user_location" == keyword) - { - sscanf(value.c_str(), "%f %f %f", - &mUserLocation.mV[VX], - &mUserLocation.mV[VY], - &mUserLocation.mV[VZ]); - } - else if ("user_look_at" == keyword) - { - sscanf(value.c_str(), "%f %f %f", - &mUserLookAt.mV[VX], - &mUserLookAt.mV[VY], - &mUserLookAt.mV[VZ]); - } - else if ("landing_type" == keyword) - { - S32 landing_type = 0; - LLString::convertToS32(value, landing_type); - mLandingType = (ELandingType) landing_type; - } - else if ("join_neighbors" == keyword) - { - llinfos << "found deprecated keyword join_neighbors" << llendl; - } - else if ("revert_sale" == keyword) - { - LLString::convertToS32(value, secs_until_revert); - if (secs_until_revert > 0) - { - mSaleTimerExpires.start(); - mSaleTimerExpires.setTimerExpirySec((F32)secs_until_revert); - } - } - else if("extended_grace" == keyword) - { - LLString::convertToS32(value, mGraceExtension); - } - else if ("user_list_type" == keyword) - { - // deprecated - } - else if("auction_id" == keyword) - { - LLString::convertToU32(value, mAuctionID); - } - else if ("allow_modify" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_CREATE_OBJECTS, setting); - } - else if ("allow_group_modify" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_CREATE_GROUP_OBJECTS, setting); - } - else if ("allow_all_object_entry" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY, setting); - } - else if ("allow_group_object_entry" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY, setting); - } - else if ("allow_deed_to_group" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_DEED_TO_GROUP, setting); - } - else if("contribute_with_deed" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_CONTRIBUTE_WITH_DEED, setting); - } - else if ("allow_terraform" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_TERRAFORM, setting); - } - else if ("allow_damage" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_DAMAGE, setting); - } - else if ("allow_fly" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_FLY, setting); - } - else if ("allow_landmark" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_LANDMARK, setting); - } - else if ("sound_local" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_SOUND_LOCAL, setting); - } - else if ("allow_group_scripts" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, setting); - } - else if ("allow_voice_chat" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_VOICE_CHAT, setting); - } - else if ("use_estate_voice_chan" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, setting); - } - else if ("allow_scripts" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, setting); - } - else if ("for_sale" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_FOR_SALE, setting); - } - else if ("sell_w_objects" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_SELL_PARCEL_OBJECTS, setting); - } - else if ("use_pass_list" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_USE_PASS_LIST, setting); - } - else if ("show_directory" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_SHOW_DIRECTORY, setting); - } - else if ("allow_publish" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_PUBLISH, setting); - } - else if ("mature_publish" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_MATURE_PUBLISH, setting); - } - else if ("claim_date" == keyword) - { - // BUG: This will fail when time rolls over in 2038. - S32 time; - LLString::convertToS32(value, time); - mClaimDate = time; - } - else if ("claim_price" == keyword) - { - LLString::convertToS32(value, mClaimPricePerMeter); - } - else if ("rent_price" == keyword) - { - LLString::convertToS32(value, mRentPricePerMeter); - } - else if ("discount_rate" == keyword) - { - LLString::convertToF32(value, mDiscountRate); - } - else if ("draw_distance" == keyword) - { - LLString::convertToF32(value, mDrawDistance); - } - else if ("sale_price" == keyword) - { - LLString::convertToS32(value, mSalePrice); - } - else if ("pass_price" == keyword) - { - LLString::convertToS32(value, mPassPrice); - } - else if ("pass_hours" == keyword) - { - LLString::convertToF32(value, mPassHours); - } - else if ("box" == keyword) - { - // deprecated - } - else if ("aabb_min" == keyword) - { - sscanf(value.c_str(), "%f %f %f", - &mAABBMin.mV[VX], &mAABBMin.mV[VY], &mAABBMin.mV[VZ]); - } - else if ("use_access_group" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_USE_ACCESS_GROUP, setting); - } - else if ("use_access_list" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_USE_ACCESS_LIST, setting); - } - else if ("use_ban_list" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_USE_BAN_LIST, setting); - } - else if ("group_name" == keyword) - { - llinfos << "found deprecated keyword group_name" << llendl; - } - else if ("group_id" == keyword) - { - mGroupID.set( value.c_str() ); - } - // TODO: DEPRECATED FLAG - // Flag removed from simstate files in 1.11.1 - // Keep if statement until we have guarenteed this flag - // no longer exists anywhere in simstate files. - else if ("require_identified" == keyword) - { -// LLString::convertToU32(value, setting); -// setParcelFlag(PF_DENY_ANONYMOUS, setting); - } - // TODO: DEPRECATED FLAG - // Flag removed from simstate files in 1.11.1 - // Keep if statement until we have guarenteed this flag - // no longer exists anywhere in simstate files. - else if ("require_transacted" == keyword) - { -// LLString::convertToU32(value, setting); -// setParcelFlag(PF_DENY_ANONYMOUS, setting); -// setParcelFlag(PF_DENY_IDENTIFIED, setting); - } - else if ("restrict_pushobject" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_RESTRICT_PUSHOBJECT, setting); - } - else if ("deny_anonymous" == keyword) - { - LLString::convertToU32(value, setting); - setParcelFlag(PF_DENY_ANONYMOUS, setting); - } - // TODO: DEPRECATED FLAG - // Keep if statement until we have guarenteed this flag - // no longer exists anywhere in simstate files. + U32 setting; + S32 secs_until_revert = 0; + + skip_to_end_of_next_keyword("{", input_stream); + if (!input_stream.good()) + { + llwarns << "LLParcel::importStream() - bad input_stream" << llendl; + return FALSE; + } + + while (input_stream.good()) + { + skip_comments_and_emptyspace(input_stream); + LLString line, keyword, value; + get_line(line, input_stream, MAX_STRING); + get_keyword_and_value(keyword, value, line); + + if ("}" == keyword) + { + break; + } + else if ("parcel_id" == keyword) + { + mID.set(value.c_str()); + } + else if ("status" == keyword) + { + mStatus = ownership_string_to_status(value.c_str()); + } + else if ("category" == keyword) + { + mCategory = category_string_to_category(value.c_str()); + } + else if ("local_id" == keyword) + { + LLString::convertToS32(value, mLocalID); + } + else if ("name" == keyword) + { + setName( value ); + } + else if ("desc" == keyword) + { + setDesc( value ); + } + else if ("music_url" == keyword) + { + setMusicURL( value ); + } + else if ("media_url" == keyword) + { + setMediaURL( value ); + } + else if ("media_desc" == keyword) + { + setMediaDesc( value.c_str() ); + } + else if ("media_type" == keyword) + { + setMediaType( value.c_str() ); + } + else if ("media_width" == keyword) + { + S32 width; + LLString::convertToS32(value, width); + setMediaWidth( width ); + } + else if ("media_height" == keyword) + { + S32 height; + LLString::convertToS32(value, height); + setMediaHeight( height ); + } + else if ("media_id" == keyword) + { + mMediaID.set( value.c_str() ); + } + else if ("media_auto_scale" == keyword) + { + LLString::convertToU8(value, mMediaAutoScale); + } + else if ("media_loop" == keyword) + { + LLString::convertToU8(value, mMediaLoop); + } + else if ("obscure_media" == keyword) + { + LLString::convertToU8(value, mObscureMedia); + } + else if ("obscure_music" == keyword) + { + LLString::convertToU8(value, mObscureMusic); + } + else if ("owner_id" == keyword) + { + mOwnerID.set( value.c_str() ); + } + else if ("group_owned" == keyword) + { + LLString::convertToBOOL(value, mGroupOwned); + } + else if ("clean_other_time" == keyword) + { + S32 time; + LLString::convertToS32(value, time); + setCleanOtherTime(time); + } + else if ("auth_buyer_id" == keyword) + { + mAuthBuyerID.set(value.c_str()); + } + else if ("snapshot_id" == keyword) + { + mSnapshotID.set(value.c_str()); + } + else if ("user_location" == keyword) + { + sscanf(value.c_str(), "%f %f %f", + &mUserLocation.mV[VX], + &mUserLocation.mV[VY], + &mUserLocation.mV[VZ]); + } + else if ("user_look_at" == keyword) + { + sscanf(value.c_str(), "%f %f %f", + &mUserLookAt.mV[VX], + &mUserLookAt.mV[VY], + &mUserLookAt.mV[VZ]); + } + else if ("landing_type" == keyword) + { + S32 landing_type = 0; + LLString::convertToS32(value, landing_type); + mLandingType = (ELandingType) landing_type; + } + else if ("join_neighbors" == keyword) + { + llinfos << "found deprecated keyword join_neighbors" << llendl; + } + else if ("revert_sale" == keyword) + { + LLString::convertToS32(value, secs_until_revert); + if (secs_until_revert > 0) + { + mSaleTimerExpires.start(); + mSaleTimerExpires.setTimerExpirySec((F32)secs_until_revert); + } + } + else if("extended_grace" == keyword) + { + LLString::convertToS32(value, mGraceExtension); + } + else if ("user_list_type" == keyword) + { + // deprecated + } + else if("auction_id" == keyword) + { + LLString::convertToU32(value, mAuctionID); + } + else if ("allow_modify" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_CREATE_OBJECTS, setting); + } + else if ("allow_group_modify" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_CREATE_GROUP_OBJECTS, setting); + } + else if ("allow_all_object_entry" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY, setting); + } + else if ("allow_group_object_entry" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY, setting); + } + else if ("allow_deed_to_group" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_DEED_TO_GROUP, setting); + } + else if("contribute_with_deed" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_CONTRIBUTE_WITH_DEED, setting); + } + else if ("allow_terraform" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_TERRAFORM, setting); + } + else if ("allow_damage" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_DAMAGE, setting); + } + else if ("allow_fly" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_FLY, setting); + } + else if ("allow_landmark" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_LANDMARK, setting); + } + else if ("sound_local" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_SOUND_LOCAL, setting); + } + else if ("allow_group_scripts" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, setting); + } + else if ("allow_voice_chat" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_VOICE_CHAT, setting); + } + else if ("use_estate_voice_chan" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, setting); + } + else if ("allow_scripts" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, setting); + } + else if ("for_sale" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_FOR_SALE, setting); + } + else if ("sell_w_objects" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_SELL_PARCEL_OBJECTS, setting); + } + else if ("use_pass_list" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_USE_PASS_LIST, setting); + } + else if ("show_directory" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_SHOW_DIRECTORY, setting); + } + else if ("allow_publish" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_ALLOW_PUBLISH, setting); + } + else if ("mature_publish" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_MATURE_PUBLISH, setting); + } + else if ("claim_date" == keyword) + { + // BUG: This will fail when time rolls over in 2038. + S32 time; + LLString::convertToS32(value, time); + mClaimDate = time; + } + else if ("claim_price" == keyword) + { + LLString::convertToS32(value, mClaimPricePerMeter); + } + else if ("rent_price" == keyword) + { + LLString::convertToS32(value, mRentPricePerMeter); + } + else if ("discount_rate" == keyword) + { + LLString::convertToF32(value, mDiscountRate); + } + else if ("draw_distance" == keyword) + { + LLString::convertToF32(value, mDrawDistance); + } + else if ("sale_price" == keyword) + { + LLString::convertToS32(value, mSalePrice); + } + else if ("pass_price" == keyword) + { + LLString::convertToS32(value, mPassPrice); + } + else if ("pass_hours" == keyword) + { + LLString::convertToF32(value, mPassHours); + } + else if ("box" == keyword) + { + // deprecated + } + else if ("aabb_min" == keyword) + { + sscanf(value.c_str(), "%f %f %f", + &mAABBMin.mV[VX], &mAABBMin.mV[VY], &mAABBMin.mV[VZ]); + } + else if ("use_access_group" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_USE_ACCESS_GROUP, setting); + } + else if ("use_access_list" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_USE_ACCESS_LIST, setting); + } + else if ("use_ban_list" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_USE_BAN_LIST, setting); + } + else if ("group_name" == keyword) + { + llinfos << "found deprecated keyword group_name" << llendl; + } + else if ("group_id" == keyword) + { + mGroupID.set( value.c_str() ); + } + // TODO: DEPRECATED FLAG + // Flag removed from simstate files in 1.11.1 + // Remove at some point where we have guarenteed this flag + // no longer exists anywhere in simstate files. + else if ("require_identified" == keyword) + { + // LLString::convertToU32(value, setting); + // setParcelFlag(PF_DENY_ANONYMOUS, setting); + } + // TODO: DEPRECATED FLAG + // Flag removed from simstate files in 1.11.1 + // Remove at some point where we have guarenteed this flag + // no longer exists anywhere in simstate files. + else if ("require_transacted" == keyword) + { + // LLString::convertToU32(value, setting); + // setParcelFlag(PF_DENY_ANONYMOUS, setting); + // setParcelFlag(PF_DENY_IDENTIFIED, setting); + } + else if ("restrict_pushobject" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_RESTRICT_PUSHOBJECT, setting); + } + else if ("deny_anonymous" == keyword) + { + LLString::convertToU32(value, setting); + setParcelFlag(PF_DENY_ANONYMOUS, setting); + } else if ("deny_identified" == keyword) { // LLString::convertToU32(value, setting); @@ -1018,211 +1097,223 @@ BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entr BOOL LLParcel::exportStream(std::ostream& output_stream) { - S32 setting; - char id_string[MAX_STRING]; /* Flawfinder: ignore */ - - std::ios::fmtflags old_flags = output_stream.flags(); - output_stream.setf(std::ios::showpoint); - output_stream << "\t{\n"; - - mID.toString(id_string); - output_stream << "\t\t parcel_id " << id_string << "\n"; - output_stream << "\t\t status " << ownership_status_to_string(mStatus) << "\n"; - output_stream << "\t\t category " << category_to_string(mCategory) << "\n"; - - output_stream << "\t\t local_id " << mLocalID << "\n"; - - const char* name = (mName.empty() ? "" : mName.c_str() ); - output_stream << "\t\t name " << name << "\n"; - - const char* desc = (mDesc.empty() ? "" : mDesc.c_str() ); - output_stream << "\t\t desc " << desc << "\n"; - - const char* music_url = (mMusicURL.empty() ? "" : mMusicURL.c_str() ); - output_stream << "\t\t music_url " << music_url << "\n"; - - const char* media_url = (mMediaURL.empty() ? "" : mMediaURL.c_str() ); - output_stream << "\t\t media_url " << media_url << "\n"; - - output_stream << "\t\t media_auto_scale " << (mMediaAutoScale ? 1 : 0) << "\n"; - - mMediaID.toString(id_string); - output_stream << "\t\t media_id " << id_string << "\n"; - - mOwnerID.toString(id_string); - output_stream << "\t\t owner_id " << id_string << "\n"; - output_stream << "\t\t group_owned " << (mGroupOwned ? 1 : 0) << "\n"; - output_stream << "\t\t clean_other_time " << getCleanOtherTime() << "\n"; - - if(!mAuthBuyerID.isNull()) - { - mAuthBuyerID.toString(id_string); - output_stream << "\t\t auth_buyer_id " << id_string << "\n"; - } - if (!mSnapshotID.isNull()) - { - mSnapshotID.toString(id_string); - output_stream << "\t\t snapshot_id " << id_string << "\n"; - } - if (!mUserLocation.isExactlyZero()) - { - output_stream << "\t\t user_location " - << (F64)mUserLocation.mV[VX] - << " " << (F64)mUserLocation.mV[VY] - << " " << (F64)mUserLocation.mV[VZ] << "\n"; - output_stream << "\t\t user_look_at " - << (F64)mUserLookAt.mV[VX] - << " " << (F64)mUserLookAt.mV[VY] - << " " << (F64)mUserLookAt.mV[VZ] << "\n"; - } - output_stream << "\t\t landing_type " << mLandingType << "\n"; - //if(mJoinNeighbors) - //{ - // output_stream << "\t\t join_neighbors " << mJoinNeighbors << "\n"; - //} - if(mSaleTimerExpires.getStarted()) - { - S32 dt_sec = (S32) mSaleTimerExpires.getRemainingTimeF32()+60; // Add a minute to prevent race conditions - output_stream << "\t\t revert_sale " << dt_sec << "\n"; - //output_stream << "\t\t revert_action " << revert_action_to_string(mExpireAction) << "\n"; - output_stream << "\t\t extended_grace " << mGraceExtension << "\n"; - } - - if(0 != mAuctionID) - { - output_stream << "\t\t auction_id " << mAuctionID << "\n"; - } - - output_stream << "\t\t allow_modify " << getAllowModify() << "\n"; - output_stream << "\t\t allow_group_modify " << getAllowGroupModify() << "\n"; - output_stream << "\t\t allow_all_object_entry " << getAllowAllObjectEntry() << "\n"; - output_stream << "\t\t allow_group_object_entry " << getAllowGroupObjectEntry() << "\n"; - output_stream << "\t\t allow_terraform " << getAllowTerraform() << "\n"; - output_stream << "\t\t allow_deed_to_group " << getAllowDeedToGroup() << "\n"; - output_stream << "\t\t contribute_with_deed " << getContributeWithDeed() << "\n"; - output_stream << "\t\t allow_damage " << getAllowDamage() << "\n"; - output_stream << "\t\t claim_date " << (S32)mClaimDate << "\n"; - output_stream << "\t\t claim_price " << mClaimPricePerMeter << "\n"; - output_stream << "\t\t rent_price " << mRentPricePerMeter << "\n"; - output_stream << "\t\t discount_rate " << mDiscountRate << "\n"; - output_stream << "\t\t allow_fly " << (getAllowFly() ? 1 : 0) << "\n"; - output_stream << "\t\t allow_landmark " << (getAllowLandmark() ? 1 : 0) << "\n"; - output_stream << "\t\t sound_local " << (getSoundLocal() ? 1 : 0) << "\n"; - output_stream << "\t\t allow_scripts " << (getAllowOtherScripts() ? 1 : 0) << "\n"; - output_stream << "\t\t allow_group_scripts " << (getAllowGroupScripts() ? 1 : 0) << "\n"; - output_stream << "\t\t allow_voice_chat " << (getVoiceEnabled() ? 1 : 0) << "\n"; - output_stream << "\t\t use_estate_voice_chan " << (getVoiceUseEstateChannel() ? 1 : 0) << "\n"; - output_stream << "\t\t for_sale " << (getForSale() ? 1 : 0) << "\n"; - output_stream << "\t\t sell_w_objects " << (getSellWithObjects() ? 1 : 0) << "\n"; - output_stream << "\t\t draw_distance " << mDrawDistance << "\n"; - output_stream << "\t\t sale_price " << mSalePrice << "\n"; - - setting = (getParcelFlag(PF_USE_ACCESS_GROUP) ? 1 : 0); - output_stream << "\t\t use_access_group " << setting << "\n"; - - setting = (getParcelFlag(PF_USE_ACCESS_LIST) ? 1 : 0); - output_stream << "\t\t use_access_list " << setting << "\n"; - - setting = (getParcelFlag(PF_USE_BAN_LIST) ? 1 : 0); - output_stream << "\t\t use_ban_list " << setting << "\n"; - - mGroupID.toString(id_string); - output_stream << "\t\t group_id " << id_string << "\n"; - - //const char* group_name - // = (mGroupName.isEmpty() ? "" : mGroupName.c_str() ); - //output_stream << "\t\t group_name " << group_name << "\n"; - - setting = (getParcelFlag(PF_USE_PASS_LIST) ? 1 : 0); - output_stream << "\t\t use_pass_list " << setting << "\n"; - - output_stream << "\t\t pass_price " << mPassPrice << "\n"; - output_stream << "\t\t pass_hours " << mPassHours << "\n"; - - setting = (getParcelFlag(PF_SHOW_DIRECTORY) ? 1 : 0); - output_stream << "\t\t show_directory " << setting << "\n"; - - setting = (getParcelFlag(PF_ALLOW_PUBLISH) ? 1 : 0); - output_stream << "\t\t allow_publish " << setting << "\n"; - - setting = (getParcelFlag(PF_MATURE_PUBLISH) ? 1 : 0); - output_stream << "\t\t mature_publish " << setting << "\n"; - - setting = (getParcelFlag(PF_DENY_ANONYMOUS) ? 1 : 0); - output_stream << "\t\t deny_anonymous " << setting << "\n"; - -// setting = (getParcelFlag(PF_DENY_IDENTIFIED) ? 1 : 0); -// output_stream << "\t\t deny_identified " << setting << "\n"; - -// setting = (getParcelFlag(PF_DENY_TRANSACTED) ? 1 : 0); -// output_stream << "\t\t deny_transacted " << setting << "\n"; - - setting = (getParcelFlag(PF_DENY_AGEUNVERIFIED) ? 1 : 0); - output_stream << "\t\t deny_age_unverified " << setting << "\n"; - - setting = (getParcelFlag(PF_RESTRICT_PUSHOBJECT) ? 1 : 0); - output_stream << "\t\t restrict_pushobject " << setting << "\n"; - - output_stream << "\t\t aabb_min " - << mAABBMin.mV[VX] - << " " << mAABBMin.mV[VY] - << " " << mAABBMin.mV[VZ] << "\n"; - - if (!mAccessList.empty()) - { - output_stream << "\t\t access_list " << mAccessList.size() << "\n"; - access_map_const_iterator cit = mAccessList.begin(); - access_map_const_iterator end = mAccessList.end(); - - for ( ; cit != end; ++cit) - { - output_stream << "\t\t{\n"; - const LLAccessEntry& entry = (*cit).second; - entry.mID.toString(id_string); - output_stream << "\t\t\tid " << id_string << "\n"; - output_stream << "\t\t\ttime " << entry.mTime << "\n"; - output_stream << "\t\t\tflags " << entry.mFlags << "\n"; - output_stream << "\t\t}\n"; - } - } - - if (!mBanList.empty()) - { - output_stream << "\t\t ban_list " << mBanList.size() << "\n"; - access_map_const_iterator cit = mBanList.begin(); - access_map_const_iterator end = mBanList.end(); - - for ( ; cit != end; ++cit) - { - output_stream << "\t\t{\n"; - const LLAccessEntry& entry = (*cit).second; - entry.mID.toString(id_string); - output_stream << "\t\t\tid " << id_string << "\n"; - output_stream << "\t\t\ttime " << entry.mTime << "\n"; - output_stream << "\t\t\tflags " << entry.mFlags << "\n"; - output_stream << "\t\t}\n"; - } - } - - /*if (mRenterList.count() > 0) - { - output_stream << "\t\t renter_list " << mRenterList.count() << "\n"; - for (i = 0; i < mRenterList.count(); i++) - { - output_stream << "\t\t{\n"; - const LLAccessEntry& entry = mRenterList.get(i); - entry.mID.toString(id_string); - output_stream << "\t\t\tid " << id_string << "\n"; - output_stream << "\t\t\ttime " << entry.mTime << "\n"; - output_stream << "\t\t\tflags " << entry.mFlags << "\n"; - output_stream << "\t\t}\n"; - } - }*/ - - output_stream << "\t}\n"; - output_stream.flags(old_flags); - - return TRUE; + S32 setting; + char id_string[MAX_STRING]; /* Flawfinder: ignore */ + + std::ios::fmtflags old_flags = output_stream.flags(); + output_stream.setf(std::ios::showpoint); + output_stream << "\t{\n"; + + mID.toString(id_string); + output_stream << "\t\t parcel_id " << id_string << "\n"; + output_stream << "\t\t status " << ownership_status_to_string(mStatus) << "\n"; + output_stream << "\t\t category " << category_to_string(mCategory) << "\n"; + + output_stream << "\t\t local_id " << mLocalID << "\n"; + + const char* name = (mName.empty() ? "" : mName.c_str() ); + output_stream << "\t\t name " << name << "\n"; + + const char* desc = (mDesc.empty() ? "" : mDesc.c_str() ); + output_stream << "\t\t desc " << desc << "\n"; + + const char* music_url = (mMusicURL.empty() ? "" : mMusicURL.c_str() ); + output_stream << "\t\t music_url " << music_url << "\n"; + + const char* media_url = (mMediaURL.empty() ? "" : mMediaURL.c_str() ); + output_stream << "\t\t media_url " << media_url << "\n"; + + const char* media_type = (mMediaType.empty() ? "" : mMediaType.c_str() ); + output_stream << "\t\t media_type " << media_type << "\n"; + + const char* media_desc = (mMediaDesc.empty() ? "" : mMediaDesc.c_str() ); + output_stream << "\t\t media_desc " << media_desc << "\n"; + + output_stream << "\t\t media_auto_scale " << (mMediaAutoScale ? 1 : 0) << "\n"; + output_stream << "\t\t media_loop " << (mMediaLoop ? 1 : 0) << "\n"; + output_stream << "\t\t obscure_media " << (mObscureMedia ? 1 : 0) << "\n"; + output_stream << "\t\t obscure_music " << (mObscureMusic ? 1 : 0) << "\n"; + + mMediaID.toString(id_string); + output_stream << "\t\t media_id " << id_string << "\n"; + + output_stream << "\t\t media_width " << mMediaWidth << "\n"; + output_stream << "\t\t media_height " << mMediaHeight << "\n"; + + mOwnerID.toString(id_string); + output_stream << "\t\t owner_id " << id_string << "\n"; + output_stream << "\t\t group_owned " << (mGroupOwned ? 1 : 0) << "\n"; + output_stream << "\t\t clean_other_time " << getCleanOtherTime() << "\n"; + + if(!mAuthBuyerID.isNull()) + { + mAuthBuyerID.toString(id_string); + output_stream << "\t\t auth_buyer_id " << id_string << "\n"; + } + if (!mSnapshotID.isNull()) + { + mSnapshotID.toString(id_string); + output_stream << "\t\t snapshot_id " << id_string << "\n"; + } + if (!mUserLocation.isExactlyZero()) + { + output_stream << "\t\t user_location " + << (F64)mUserLocation.mV[VX] + << " " << (F64)mUserLocation.mV[VY] + << " " << (F64)mUserLocation.mV[VZ] << "\n"; + output_stream << "\t\t user_look_at " + << (F64)mUserLookAt.mV[VX] + << " " << (F64)mUserLookAt.mV[VY] + << " " << (F64)mUserLookAt.mV[VZ] << "\n"; + } + output_stream << "\t\t landing_type " << mLandingType << "\n"; + //if(mJoinNeighbors) + //{ + // output_stream << "\t\t join_neighbors " << mJoinNeighbors << "\n"; + //} + if(mSaleTimerExpires.getStarted()) + { + S32 dt_sec = (S32) mSaleTimerExpires.getRemainingTimeF32()+60; // Add a minute to prevent race conditions + output_stream << "\t\t revert_sale " << dt_sec << "\n"; + //output_stream << "\t\t revert_action " << revert_action_to_string(mExpireAction) << "\n"; + output_stream << "\t\t extended_grace " << mGraceExtension << "\n"; + } + + if(0 != mAuctionID) + { + output_stream << "\t\t auction_id " << mAuctionID << "\n"; + } + + output_stream << "\t\t allow_modify " << getAllowModify() << "\n"; + output_stream << "\t\t allow_group_modify " << getAllowGroupModify() << "\n"; + output_stream << "\t\t allow_all_object_entry " << getAllowAllObjectEntry() << "\n"; + output_stream << "\t\t allow_group_object_entry " << getAllowGroupObjectEntry() << "\n"; + output_stream << "\t\t allow_terraform " << getAllowTerraform() << "\n"; + output_stream << "\t\t allow_deed_to_group " << getAllowDeedToGroup() << "\n"; + output_stream << "\t\t contribute_with_deed " << getContributeWithDeed() << "\n"; + output_stream << "\t\t allow_damage " << getAllowDamage() << "\n"; + output_stream << "\t\t claim_date " << (S32)mClaimDate << "\n"; + output_stream << "\t\t claim_price " << mClaimPricePerMeter << "\n"; + output_stream << "\t\t rent_price " << mRentPricePerMeter << "\n"; + output_stream << "\t\t discount_rate " << mDiscountRate << "\n"; + output_stream << "\t\t allow_fly " << (getAllowFly() ? 1 : 0) << "\n"; + output_stream << "\t\t allow_landmark " << (getAllowLandmark() ? 1 : 0) << "\n"; + output_stream << "\t\t sound_local " << (getSoundLocal() ? 1 : 0) << "\n"; + output_stream << "\t\t allow_scripts " << (getAllowOtherScripts() ? 1 : 0) << "\n"; + output_stream << "\t\t allow_group_scripts " << (getAllowGroupScripts() ? 1 : 0) << "\n"; + output_stream << "\t\t allow_voice_chat " << (getVoiceEnabled() ? 1 : 0) << "\n"; + output_stream << "\t\t use_estate_voice_chan " << (getVoiceUseEstateChannel() ? 1 : 0) << "\n"; + output_stream << "\t\t for_sale " << (getForSale() ? 1 : 0) << "\n"; + output_stream << "\t\t sell_w_objects " << (getSellWithObjects() ? 1 : 0) << "\n"; + output_stream << "\t\t draw_distance " << mDrawDistance << "\n"; + output_stream << "\t\t sale_price " << mSalePrice << "\n"; + + setting = (getParcelFlag(PF_USE_ACCESS_GROUP) ? 1 : 0); + output_stream << "\t\t use_access_group " << setting << "\n"; + + setting = (getParcelFlag(PF_USE_ACCESS_LIST) ? 1 : 0); + output_stream << "\t\t use_access_list " << setting << "\n"; + + setting = (getParcelFlag(PF_USE_BAN_LIST) ? 1 : 0); + output_stream << "\t\t use_ban_list " << setting << "\n"; + + mGroupID.toString(id_string); + output_stream << "\t\t group_id " << id_string << "\n"; + + //const char* group_name + // = (mGroupName.isEmpty() ? "" : mGroupName.c_str() ); + //output_stream << "\t\t group_name " << group_name << "\n"; + + setting = (getParcelFlag(PF_USE_PASS_LIST) ? 1 : 0); + output_stream << "\t\t use_pass_list " << setting << "\n"; + + output_stream << "\t\t pass_price " << mPassPrice << "\n"; + output_stream << "\t\t pass_hours " << mPassHours << "\n"; + + setting = (getParcelFlag(PF_SHOW_DIRECTORY) ? 1 : 0); + output_stream << "\t\t show_directory " << setting << "\n"; + + setting = (getParcelFlag(PF_ALLOW_PUBLISH) ? 1 : 0); + output_stream << "\t\t allow_publish " << setting << "\n"; + + setting = (getParcelFlag(PF_MATURE_PUBLISH) ? 1 : 0); + output_stream << "\t\t mature_publish " << setting << "\n"; + + setting = (getParcelFlag(PF_DENY_ANONYMOUS) ? 1 : 0); + output_stream << "\t\t deny_anonymous " << setting << "\n"; + +// setting = (getParcelFlag(PF_DENY_IDENTIFIED) ? 1 : 0); +// output_stream << "\t\t deny_identified " << setting << "\n"; + +// setting = (getParcelFlag(PF_DENY_TRANSACTED) ? 1 : 0); +// output_stream << "\t\t deny_transacted " << setting << "\n"; + + setting = (getParcelFlag(PF_DENY_AGEUNVERIFIED) ? 1 : 0); + output_stream << "\t\t deny_age_unverified " << setting << "\n"; + + setting = (getParcelFlag(PF_RESTRICT_PUSHOBJECT) ? 1 : 0); + output_stream << "\t\t restrict_pushobject " << setting << "\n"; + + output_stream << "\t\t aabb_min " + << mAABBMin.mV[VX] + << " " << mAABBMin.mV[VY] + << " " << mAABBMin.mV[VZ] << "\n"; + + if (!mAccessList.empty()) + { + output_stream << "\t\t access_list " << mAccessList.size() << "\n"; + access_map_const_iterator cit = mAccessList.begin(); + access_map_const_iterator end = mAccessList.end(); + + for ( ; cit != end; ++cit) + { + output_stream << "\t\t{\n"; + const LLAccessEntry& entry = (*cit).second; + entry.mID.toString(id_string); + output_stream << "\t\t\tid " << id_string << "\n"; + output_stream << "\t\t\ttime " << entry.mTime << "\n"; + output_stream << "\t\t\tflags " << entry.mFlags << "\n"; + output_stream << "\t\t}\n"; + } + } + + if (!mBanList.empty()) + { + output_stream << "\t\t ban_list " << mBanList.size() << "\n"; + access_map_const_iterator cit = mBanList.begin(); + access_map_const_iterator end = mBanList.end(); + + for ( ; cit != end; ++cit) + { + output_stream << "\t\t{\n"; + const LLAccessEntry& entry = (*cit).second; + entry.mID.toString(id_string); + output_stream << "\t\t\tid " << id_string << "\n"; + output_stream << "\t\t\ttime " << entry.mTime << "\n"; + output_stream << "\t\t\tflags " << entry.mFlags << "\n"; + output_stream << "\t\t}\n"; + } + } + + /*if (mRenterList.count() > 0) + { + output_stream << "\t\t renter_list " << mRenterList.count() << "\n"; + for (i = 0; i < mRenterList.count(); i++) + { + output_stream << "\t\t{\n"; + const LLAccessEntry& entry = mRenterList.get(i); + entry.mID.toString(id_string); + output_stream << "\t\t\tid " << id_string << "\n"; + output_stream << "\t\t\ttime " << entry.mTime << "\n"; + output_stream << "\t\t\tflags " << entry.mFlags << "\n"; + output_stream << "\t\t}\n"; + } + }*/ + + output_stream << "\t}\n"; + output_stream.flags(old_flags); + + return TRUE; } @@ -1248,6 +1339,38 @@ void LLParcel::packMessage(LLMessageSystem* msg) msg->addU8Fast( _PREHASH_LandingType, (U8)mLandingType); } +// Assumes we are in a block "ParcelData" +void LLParcel::packMessage(LLSD& msg) +{ + msg["local_id"] = getLocalID(); + msg["parcel_flags"] = ll_sd_from_U32(getParcelFlags()); + msg["sale_price"] = getSalePrice(); + msg["name"] = getName(); + msg["description"] = getDesc(); + msg["music_url"] = getMusicURL(); + msg["media_url"] = getMediaURL(); + msg["media_desc"] = getMediaDesc(); + msg["media_type"] = getMediaType(); + msg["media_width"] = getMediaWidth(); + msg["media_height"] = getMediaHeight(); + msg["auto_scale"] = getMediaAutoScale(); + msg["media_loop"] = getMediaLoop(); + msg["obscure_media"] = getObscureMedia(); + msg["obscure_music"] = getObscureMusic(); + msg["media_id"] = getMediaID(); + msg["group_id"] = getGroupID(); + msg["pass_price"] = mPassPrice; + msg["pass_hours"] = mPassHours; + msg["category"] = (U8)mCategory; + msg["auth_buyer_id"] = mAuthBuyerID; + msg["snapshot_id"] = mSnapshotID; + msg["snapshot_id"] = mSnapshotID; + msg["user_location"] = ll_sd_from_vector3(mUserLocation); + msg["user_look_at"] = ll_sd_from_vector3(mUserLookAt); + msg["landing_type"] = (U8)mLandingType; + +} + void LLParcel::unpackMessage(LLMessageSystem* msg) { @@ -1281,8 +1404,30 @@ void LLParcel::unpackMessage(LLMessageSystem* msg) U8 landing_type; msg->getU8Fast( _PREHASH_ParcelData,_PREHASH_LandingType, landing_type); mLandingType = (ELandingType)landing_type; -} + // New Media Data + // Note: the message has been converted to TCP + if(msg->getNumberOfBlocks("MediaData") > 0) + { + msg->getString("MediaData", "MediaDesc", 256, buffer); + setMediaDesc(buffer); + msg->getString("MediaData", "MediaType", 256, buffer); + setMediaType(buffer); + msg->getS32("MediaData", "MediaWidth", mMediaWidth); + msg->getS32("MediaData", "MediaHeight", mMediaHeight); + msg->getU8 ( "MediaData", "MediaLoop", mMediaLoop ); + msg->getU8 ( "MediaData", "ObscureMedia", mObscureMedia ); + msg->getU8 ( "MediaData", "ObscureMusic", mObscureMusic ); + } + else + { + setMediaType("video/vnd.secondlife.qt.legacy"); + setMediaDesc("No Description available without Server Upgrade"); + mMediaLoop = true; + mObscureMedia = true; + mObscureMusic = true; + } +} void LLParcel::packAccessEntries(LLMessageSystem* msg, const std::map& list) @@ -1702,27 +1847,34 @@ BOOL LLParcel::isBuyerAuthorized(const LLUUID& buyer_id) const void LLParcel::clearParcel() { - overrideParcelFlags(PF_DEFAULT); - setName(NULL); - setDesc(NULL); - setMusicURL(NULL); - setMediaURL(NULL); - setMediaID(LLUUID::null); - setMediaAutoScale(0); - setInEscrow(FALSE); - setAuthorizedBuyerID(LLUUID::null); - setCategory(C_NONE); - setSnapshotID(LLUUID::null); - setUserLocation(LLVector3::zero); - setUserLookAt(LLVector3::x_axis); - setLandingType(L_LANDING_POINT); - setAuctionID(0); - setGroupID(LLUUID::null); - setPassPrice(0); - setPassHours(0.f); - mAccessList.clear(); - mBanList.clear(); - //mRenterList.reset(); + overrideParcelFlags(PF_DEFAULT); + setName(NULL); + setDesc(NULL); + setMediaURL(NULL); + setMediaType(NULL); + setMediaID(LLUUID::null); + setMediaDesc(NULL); + setMediaAutoScale(0); + setMediaLoop(TRUE); + mObscureMedia = 0; + mObscureMusic = 0; + mMediaWidth = 0; + mMediaHeight = 0; + setMusicURL(NULL); + setInEscrow(FALSE); + setAuthorizedBuyerID(LLUUID::null); + setCategory(C_NONE); + setSnapshotID(LLUUID::null); + setUserLocation(LLVector3::zero); + setUserLookAt(LLVector3::x_axis); + setLandingType(L_LANDING_POINT); + setAuctionID(0); + setGroupID(LLUUID::null); + setPassPrice(0); + setPassHours(0.f); + mAccessList.clear(); + mBanList.clear(); + //mRenterList.reset(); } void LLParcel::dump() @@ -1826,6 +1978,3 @@ LLParcel::ECategory category_ui_string_to_category(const char* s) // is a distinct option from "None" and "Other" return LLParcel::C_ANY; } - - - diff --git a/linden/indra/llinventory/llparcel.h b/linden/indra/llinventory/llparcel.h index 10fe6dc..9c91d94 100644 --- a/linden/indra/llinventory/llparcel.h +++ b/linden/indra/llinventory/llparcel.h @@ -211,8 +211,15 @@ public: void setDesc(const LLString& desc); void setMusicURL(const LLString& url); void setMediaURL(const LLString& url); + void setMediaType(const char* type); + void setMediaDesc(const char* desc); void setMediaID(const LLUUID& id) { mMediaID = id; } void setMediaAutoScale ( U8 flagIn ) { mMediaAutoScale = flagIn; } + void setMediaLoop (U8 loop) { mMediaLoop = loop; } + void setObscureMedia( U8 flagIn ) { mObscureMedia = flagIn; } + void setObscureMusic( U8 flagIn ) { mObscureMusic = flagIn; } + void setMediaWidth(S32 width); + void setMediaHeight(S32 height); virtual void setLocalID(S32 local_id); // blow away all the extra crap lurking in parcels, including urls, access lists, etc @@ -268,6 +275,7 @@ public: BOOL exportStream(std::ostream& output_stream); void packMessage(LLMessageSystem* msg); + void packMessage(LLSD& msg); void unpackMessage(LLMessageSystem* msg); void packAccessEntries(LLMessageSystem* msg, @@ -299,8 +307,15 @@ public: const LLString& getDesc() const { return mDesc; } const LLString& getMusicURL() const { return mMusicURL; } const LLString& getMediaURL() const { return mMediaURL; } + const char* getMediaDesc() const { return mMediaDesc.c_str(); } + const char* getMediaType() const { return mMediaType.c_str(); } const LLUUID& getMediaID() const { return mMediaID; } + S32 getMediaWidth() const { return mMediaWidth; } + S32 getMediaHeight() const { return mMediaHeight; } U8 getMediaAutoScale() const { return mMediaAutoScale; } + U8 getMediaLoop() const { return mMediaLoop; } + U8 getObscureMedia() const { return mObscureMedia; } + U8 getObscureMusic() const { return mObscureMusic; } S32 getLocalID() const { return mLocalID; } const LLUUID& getOwnerID() const { return mOwnerID; } const LLUUID& getGroupID() const { return mGroupID; } @@ -576,7 +591,14 @@ protected: LLString mDesc; LLString mMusicURL; LLString mMediaURL; + std::string mMediaDesc; + std::string mMediaType; + S32 mMediaWidth; + S32 mMediaHeight; U8 mMediaAutoScale; + U8 mMediaLoop; + U8 mObscureMedia; + U8 mObscureMusic; LLUUID mMediaID; S32 mPassPrice; F32 mPassHours; diff --git a/linden/indra/llinventory/llpermissions.cpp b/linden/indra/llinventory/llpermissions.cpp index 0fec5b8..8d800aa 100644 --- a/linden/indra/llinventory/llpermissions.cpp +++ b/linden/indra/llinventory/llpermissions.cpp @@ -37,6 +37,7 @@ // library includes #include "message.h" #include "metapropertyt.h" +#include "llsd.h" ///---------------------------------------------------------------------------- /// Class LLPermissions @@ -473,6 +474,25 @@ BOOL LLPermissions::allowOperationBy(PermissionBit op, const LLUUID& requester, } // +// LLSD support for HTTP messages. +// +LLSD LLPermissions::packMessage() const +{ + LLSD result; + result["creator-id"] = mCreator; + result["owner-id"] = mOwner; + result["group-id"] = mGroup; + + result["base-mask"] = (S32)mMaskBase; + result["owner-mask"] = (S32)mMaskOwner; + result["group-mask"] = (S32)mMaskGroup; + result["everyone-mask"] = (S32)mMaskEveryone; + result["next-owner-mask"]= (S32)mMaskNextOwner; + result["group-owned"] = (BOOL)mIsGroupOwned; + return result; +} + +// // Messaging support // void LLPermissions::packMessage(LLMessageSystem* msg) const @@ -489,6 +509,19 @@ void LLPermissions::packMessage(LLMessageSystem* msg) const msg->addBOOLFast(_PREHASH_GroupOwned, (BOOL)mIsGroupOwned); } +void LLPermissions::unpackMessage(LLSD perms) +{ + mCreator = perms["creator-id"]; + mOwner = perms["owner-id"]; + mGroup = perms["group-id"]; + + mMaskBase = (U32)perms["base-mask"].asInteger(); + mMaskOwner = (U32)perms["owner-mask"].asInteger(); + mMaskGroup = (U32)perms["group-mask"].asInteger(); + mMaskEveryone = (U32)perms["everyone-mask"].asInteger(); + mMaskNextOwner = (U32)perms["next-owner-mask"].asInteger(); + mIsGroupOwned = perms["group-owned"].asBoolean(); +} void LLPermissions::unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num) { diff --git a/linden/indra/llinventory/llpermissions.h b/linden/indra/llinventory/llpermissions.h index cb4f4b5..05a30f6 100644 --- a/linden/indra/llinventory/llpermissions.h +++ b/linden/indra/llinventory/llpermissions.h @@ -294,6 +294,9 @@ public: // MISC METHODS and OPERATORS // + LLSD packMessage() const; + void unpackMessage(LLSD perms); + // For messaging system support void packMessage(LLMessageSystem* msg) const; void unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0); diff --git a/linden/indra/llinventory/llsaleinfo.cpp b/linden/indra/llinventory/llsaleinfo.cpp index e7c429b..bff075b 100644 --- a/linden/indra/llinventory/llsaleinfo.cpp +++ b/linden/indra/llinventory/llsaleinfo.cpp @@ -280,6 +280,17 @@ void LLSaleInfo::setSalePrice(S32 price) mSalePrice = llclamp(mSalePrice, 0, S32_MAX); } +LLSD LLSaleInfo::packMessage() const +{ + LLSD result; + + U8 sale_type = static_cast(mSaleType); + result["sale-type"] = (U8)sale_type; + result["sale-price"] = (S32)mSalePrice; + //result[_PREHASH_NextOwnerMask] = mNextOwnerPermMask; + return result; +} + void LLSaleInfo::packMessage(LLMessageSystem* msg) const { U8 sale_type = static_cast(mSaleType); @@ -288,6 +299,16 @@ void LLSaleInfo::packMessage(LLMessageSystem* msg) const //msg->addU32Fast(_PREHASH_NextOwnerMask, mNextOwnerPermMask); } +void LLSaleInfo::unpackMessage(LLSD sales) +{ + U8 sale_type = (U8)sales["sale-type"].asInteger(); + mSaleType = static_cast(sale_type); + + mSalePrice = (S32)sales["sale-price"].asInteger(); + mSalePrice = llclamp(mSalePrice, 0, S32_MAX); + //msg->getU32Fast(block, _PREHASH_NextOwnerMask, mNextOwnerPermMask); +} + void LLSaleInfo::unpackMessage(LLMessageSystem* msg, const char* block) { U8 sale_type; diff --git a/linden/indra/llinventory/llsaleinfo.h b/linden/indra/llinventory/llsaleinfo.h index 2fc2fd0..0af8d89 100644 --- a/linden/indra/llinventory/llsaleinfo.h +++ b/linden/indra/llinventory/llsaleinfo.h @@ -103,6 +103,9 @@ public: LLXMLNode *exportFileXML() const; BOOL importXML(LLXMLNode* node); + LLSD packMessage() const; + void unpackMessage(LLSD sales); + // message serialization void packMessage(LLMessageSystem* msg) const; void unpackMessage(LLMessageSystem* msg, const char* block); diff --git a/linden/indra/llmath/llcamera.cpp b/linden/indra/llmath/llcamera.cpp index 82c401f..7a9d576 100644 --- a/linden/indra/llmath/llcamera.cpp +++ b/linden/indra/llmath/llcamera.cpp @@ -43,7 +43,8 @@ LLCamera::LLCamera() : mViewHeightInPixels( -1 ), // invalid height mNearPlane(DEFAULT_NEAR_PLANE), mFarPlane(DEFAULT_FAR_PLANE), - mFixedDistance(-1.f) + mFixedDistance(-1.f), + mPlaneCount(6) { calculateFrustumPlanes(); } @@ -56,7 +57,8 @@ LLCamera::LLCamera(F32 z_field_of_view, F32 aspect_ratio, S32 view_height_in_pix mViewHeightInPixels(view_height_in_pixels), mNearPlane(near_plane), mFarPlane(far_plane), - mFixedDistance(-1.f) + mFixedDistance(-1.f), + mPlaneCount(6) { if (mView < MIN_FIELD_OF_VIEW) { mView = MIN_FIELD_OF_VIEW; } else if (mView > MAX_FIELD_OF_VIEW) { mView = MAX_FIELD_OF_VIEW; } @@ -78,6 +80,18 @@ LLCamera::LLCamera(F32 z_field_of_view, F32 aspect_ratio, S32 view_height_in_pix // ---------------- LLCamera::setFoo() member functions ---------------- +void LLCamera::setUserClipPlane(LLPlane plane) +{ + mPlaneCount = 7; + mAgentPlanes[6].p = plane; + mAgentPlanes[6].mask = calcPlaneMask(plane); +} + +void LLCamera::disableUserClipPlane() +{ + mPlaneCount = 6; +} + void LLCamera::setView(F32 field_of_view) { mView = field_of_view; @@ -150,7 +164,7 @@ size_t LLCamera::readFrustumFromBuffer(const char *buffer) // ---------------- test methods ---------------- -int LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius) +S32 LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius) { static const LLVector3 scaler[] = { LLVector3(-1,-1,-1), @@ -166,10 +180,56 @@ int LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius) U8 mask = 0; S32 result = 2; - for (int i = 0; i < 6; i++) + for (U32 i = 0; i < mPlaneCount; i++) + { + mask = mAgentPlanes[i].mask; + LLPlane p = mAgentPlanes[i].p; + LLVector3 n = LLVector3(p); + float d = p.mV[3]; + LLVector3 rscale = radius.scaledVec(scaler[mask]); + + LLVector3 minp = center - rscale; + LLVector3 maxp = center + rscale; + + if (n * minp > -d) + { + return 0; + } + + if (n * maxp > -d) + { + result = 1; + } + } + + return result; +} + +S32 LLCamera::AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& radius) +{ + static const LLVector3 scaler[] = { + LLVector3(-1,-1,-1), + LLVector3( 1,-1,-1), + LLVector3(-1, 1,-1), + LLVector3( 1, 1,-1), + LLVector3(-1,-1, 1), + LLVector3( 1,-1, 1), + LLVector3(-1, 1, 1), + LLVector3( 1, 1, 1) + }; + + U8 mask = 0; + S32 result = 2; + + for (U32 i = 0; i < mPlaneCount; i++) { - mask = mAgentPlaneMask[i]; - LLPlane p = mAgentPlanes[i]; + if (i == 5) + { + continue; + } + + mask = mAgentPlanes[i].mask; + LLPlane p = mAgentPlanes[i].p; LLVector3 n = LLVector3(p); float d = p.mV[3]; LLVector3 rscale = radius.scaledVec(scaler[mask]); @@ -312,7 +372,7 @@ int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) int res = 2; for (int i = 0; i < 6; i++) { - float d = mAgentPlanes[i].dist(sphere_center); + float d = mAgentPlanes[i].p.dist(sphere_center); if (d > radius) { @@ -477,6 +537,25 @@ LLPlane planeFromPoints(LLVector3 p1, LLVector3 p2, LLVector3 p3) return LLPlane(p1, n); } +U8 LLCamera::calcPlaneMask(const LLPlane& plane) +{ + U8 mask = 0; + + if (plane.mV[0] >= 0) + { + mask |= 1; + } + if (plane.mV[1] >= 0) + { + mask |= 2; + } + if (plane.mV[2] >= 0) + { + mask |= 4; + } + + return mask; +} void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) { @@ -486,48 +565,34 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) mAgentFrustum[i] = frust[i]; } + mFrustumCornerDist = (frust[5] - getOrigin()).magVec(); + //frust contains the 8 points of the frustum, calculate 6 planes //order of planes is important, keep most likely to fail in the front of the list //near - frust[0], frust[1], frust[2] - mAgentPlanes[2] = planeFromPoints(frust[0], frust[1], frust[2]); + mAgentPlanes[2].p = planeFromPoints(frust[0], frust[1], frust[2]); //far - mAgentPlanes[5] = planeFromPoints(frust[5], frust[4], frust[6]); + mAgentPlanes[5].p = planeFromPoints(frust[5], frust[4], frust[6]); //left - mAgentPlanes[0] = planeFromPoints(frust[4], frust[0], frust[7]); + mAgentPlanes[0].p = planeFromPoints(frust[4], frust[0], frust[7]); //right - mAgentPlanes[1] = planeFromPoints(frust[1], frust[5], frust[6]); + mAgentPlanes[1].p = planeFromPoints(frust[1], frust[5], frust[6]); //top - mAgentPlanes[4] = planeFromPoints(frust[3], frust[2], frust[6]); + mAgentPlanes[4].p = planeFromPoints(frust[3], frust[2], frust[6]); //bottom - mAgentPlanes[3] = planeFromPoints(frust[1], frust[0], frust[4]); + mAgentPlanes[3].p = planeFromPoints(frust[1], frust[0], frust[4]); //cache plane octant facing mask for use in AABBInFrustum - for (int i = 0; i < 6; i++) + for (U32 i = 0; i < mPlaneCount; i++) { - U8 mask = 0; - LLPlane p = mAgentPlanes[i]; - LLVector3 n = LLVector3(p); - - if (n.mV[0] >= 0) - { - mask |= 1; - } - if (n.mV[1] >= 0) - { - mask |= 2; - } - if (n.mV[2] >= 0) - { - mask |= 4; - } - mAgentPlaneMask[i] = mask; + mAgentPlanes[i].mask = calcPlaneMask(mAgentPlanes[i].p); } } diff --git a/linden/indra/llmath/llcamera.h b/linden/indra/llmath/llcamera.h index 0e20798..7066b9f 100644 --- a/linden/indra/llmath/llcamera.h +++ b/linden/indra/llmath/llcamera.h @@ -46,7 +46,7 @@ const F32 MAX_FIELD_OF_VIEW = F_PI; const F32 MAX_ASPECT_RATIO = 50.0f; const F32 MAX_NEAR_PLANE = 10.f; const F32 MAX_FAR_PLANE = 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though. -const F32 MAX_FAR_CLIP = 1024.0f; +const F32 MAX_FAR_CLIP = 512.0f; const F32 MIN_FIELD_OF_VIEW = 0.1f; const F32 MIN_ASPECT_RATIO = 0.02f; @@ -114,16 +114,28 @@ protected: LLPlane mWorldPlanes[PLANE_NUM]; LLPlane mHorizPlanes[HORIZ_PLANE_NUM]; - LLPlane mAgentPlanes[6]; //frustum in agent space a la gluUnproject (I'm a bastard, I know) - DaveP - U8 mAgentPlaneMask[6]; + + typedef struct + { + LLPlane p; + U8 mask; + } frustum_plane; + frustum_plane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP + + U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in + LLVector3 mWorldPlanePos; // Position of World Planes (may be offset from camera) public: - LLVector3 mAgentFrustum[8]; + LLVector3 mAgentFrustum[8]; //8 corners of 6-plane frustum + F32 mFrustumCornerDist; //distance to corner of frustum against far clip plane public: LLCamera(); LLCamera(F32 z_field_of_view, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane); + void setUserClipPlane(LLPlane plane); + void disableUserClipPlane(); + U8 calcPlaneMask(const LLPlane& plane); void setView(F32 new_view); void setViewHeightInPixels(S32 height); void setAspect(F32 new_aspect); @@ -164,6 +176,8 @@ public: S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); } S32 sphereInFrustumFull(const LLVector3 ¢er, const F32 radius) const { return sphereInFrustum(center, radius); } S32 AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius); + S32 AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& radius); + //does a quick 'n dirty sphere-sphere check S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius); diff --git a/linden/indra/llmath/llcoordframe.cpp b/linden/indra/llmath/llcoordframe.cpp index 6d18c8b..0196424 100644 --- a/linden/indra/llmath/llcoordframe.cpp +++ b/linden/indra/llmath/llcoordframe.cpp @@ -730,7 +730,11 @@ void LLCoordFrame::lookDir(const LLVector3 &at, const LLVector3 &up_direction) left.normVec(); LLVector3 up = at % left; - setAxes(at, left, up); + + if (at.isFinite() && left.isFinite() && up.isFinite()) + { + setAxes(at, left, up); + } } void LLCoordFrame::lookDir(const LLVector3 &xuv) diff --git a/linden/indra/llmath/llmath.h b/linden/indra/llmath/llmath.h index affdbf1..d3c0d86 100644 --- a/linden/indra/llmath/llmath.h +++ b/linden/indra/llmath/llmath.h @@ -440,4 +440,20 @@ inline F32 llsimple_angle(F32 angle) return angle; } +//calculate the nearesr power of two number for val, bounded by max_power_two +inline U32 get_nearest_power_two(U32 val, U32 max_power_two) +{ + if(!max_power_two) + { + max_power_two = 1 << 31 ; + } + if(max_power_two & (max_power_two - 1)) + { + return 0 ; + } + + for(; val < max_power_two ; max_power_two >>= 1) ; + + return max_power_two ; +} #endif diff --git a/linden/indra/llmath/llmath_vc8.vcproj b/linden/indra/llmath/llmath_vc8.vcproj index ed4193d..e85a852 100644 --- a/linden/indra/llmath/llmath_vc8.vcproj +++ b/linden/indra/llmath/llmath_vc8.vcproj @@ -1,472 +1,472 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llmath/llmath_vc9.vcproj b/linden/indra/llmath/llmath_vc9.vcproj index 1f6d05b..6d60d1e 100644 --- a/linden/indra/llmath/llmath_vc9.vcproj +++ b/linden/indra/llmath/llmath_vc9.vcproj @@ -1,473 +1,473 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llmath/lloctree.h b/linden/indra/llmath/lloctree.h index 6eee9fb..203cb41 100644 --- a/linden/indra/llmath/lloctree.h +++ b/linden/indra/llmath/lloctree.h @@ -47,10 +47,9 @@ #if LL_DARWIN #define LL_OCTREE_MAX_CAPACITY 32 #else -#define LL_OCTREE_MAX_CAPACITY 256 +#define LL_OCTREE_MAX_CAPACITY 128 #endif -template class LLOctreeState; template class LLOctreeNode; template @@ -64,15 +63,27 @@ public: virtual void handleChildRemoval(const oct_node* parent, const oct_node* child) = 0; }; +template +class LLOctreeTraveler : public LLTreeTraveler +{ +public: + virtual void traverse(const LLTreeNode* node); + virtual void visit(const LLTreeNode* state) { } + virtual void visit(const LLOctreeNode* branch) = 0; +}; template class LLOctreeNode : public LLTreeNode { public: - + typedef LLOctreeTraveler oct_traveler; + typedef LLTreeTraveler tree_traveler; + typedef typename std::set > element_list; + typedef typename std::set >::iterator element_iter; + typedef typename std::set >::const_iterator const_element_iter; + typedef typename std::vector*>::iterator tree_listener_iter; + typedef typename std::vector* > child_list; typedef LLTreeNode BaseType; - typedef LLTreeState tree_state; - typedef LLOctreeState oct_state; typedef LLOctreeNode oct_node; typedef LLOctreeListener oct_listener; @@ -82,11 +93,9 @@ public: LLOctreeNode( LLVector3d center, LLVector3d size, - tree_state* state, BaseType* parent, U8 octant = 255) - : BaseType(state), - mParent((oct_node*)parent), + : mParent((oct_node*)parent), mCenter(center), mSize(size), mOctant(octant) @@ -96,9 +105,19 @@ public: { mOctant = ((oct_node*) mParent)->getOctant(mCenter.mdV); } + + clearChildren(); } - ~LLOctreeNode() { BaseType::destroyListeners(); delete this->mState; } + virtual ~LLOctreeNode() + { + BaseType::destroyListeners(); + + for (U32 i = 0; i < getChildCount(); i++) + { + delete getChild(i); + } + } inline const BaseType* getParent() const { return mParent; } inline void setParent(BaseType* parent) { mParent = (oct_node*) parent; } @@ -106,25 +125,12 @@ public: inline const LLVector3d& getSize() const { return mSize; } inline void setCenter(LLVector3d center) { mCenter = center; } inline void setSize(LLVector3d size) { mSize = size; } - inline bool balance() { return getOctState()->balance(); } - inline void validate() { getOctState()->validate(); } - inline U32 getChildCount() const { return getOctState()->getChildCount(); } - inline oct_node* getChild(U32 index) { return getOctState()->getChild(index); } - inline const oct_node* getChild(U32 index) const { return getOctState()->getChild(index); } - inline U32 getElementCount() const { return getOctState()->getElementCount(); } - inline void removeByAddress(T* data) { getOctState()->removeByAddress(data); } - inline bool hasLeafState() const { return getOctState()->isLeaf(); } - inline void destroy() { getOctState()->destroy(); } - inline oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); } - inline oct_node* getNodeAt(const LLVector3d& pos, const F64& rad) { return getOctState()->getNodeAt(pos, rad); } + inline oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); } inline U8 getOctant() const { return mOctant; } inline void setOctant(U8 octant) { mOctant = octant; } - inline const oct_state* getOctState() const { return (const oct_state*) BaseType::mState; } - inline oct_state* getOctState() { return (oct_state*) BaseType::mState; } inline const oct_node* getOctParent() const { return (const oct_node*) getParent(); } inline oct_node* getOctParent() { return (oct_node*) getParent(); } - inline void deleteChild(oct_node* child) { getOctState()->deleteChild(child); } - + U8 getOctant(const F64 pos[]) const //get the octant pos is in { U8 ret = 0; @@ -205,9 +211,9 @@ public: (radius <= p_size && radius > size); } - static void pushCenter(LLVector3d ¢er, LLVector3d &size, T* data) + static void pushCenter(LLVector3d ¢er, const LLVector3d &size, const T* data) { - LLVector3d pos(data->getPositionGroup()); + const LLVector3d& pos = data->getPositionGroup(); for (U32 i = 0; i < 3; i++) { if (pos.mdV[i] > center.mdV[i]) @@ -221,76 +227,25 @@ public: } } -protected: - oct_node* mParent; - LLVector3d mCenter; - LLVector3d mSize; - LLVector3d mMax; - LLVector3d mMin; - U8 mOctant; -}; - -template -class LLOctreeTraveler : public LLTreeTraveler -{ -public: - virtual void traverse(const LLTreeNode* node); - virtual void visit(const LLTreeState* state) { } - virtual void visit(const LLOctreeState* branch) = 0; -}; - -//will pass requests to a child, might make a new child -template -class LLOctreeState : public LLTreeState -{ -public: - typedef LLTreeState BaseType; - typedef LLOctreeTraveler oct_traveler; - typedef LLOctreeNode oct_node; - typedef LLOctreeListener oct_listener; - typedef LLTreeTraveler tree_traveler; - typedef typename std::set > element_list; - typedef typename std::set >::iterator element_iter; - typedef typename std::set >::const_iterator const_element_iter; - typedef typename std::vector*>::iterator tree_listener_iter; - typedef typename std::vector* > child_list; + void accept(oct_traveler* visitor) { visitor->visit(this); } + virtual bool isLeaf() const { return mChild.empty(); } - LLOctreeState(oct_node* node = NULL): BaseType(node) { this->clearChildren(); } - virtual ~LLOctreeState() - { - for (U32 i = 0; i < getChildCount(); i++) - { - delete getChild(i); - } - } - + U32 getElementCount() const { return mData.size(); } + element_list& getData() { return mData; } + const element_list& getData() const { return mData; } - virtual void accept(oct_traveler* visitor) { visitor->visit(this); } - virtual bool isLeaf() const { return mChild.empty(); } + U32 getChildCount() const { return mChild.size(); } + oct_node* getChild(U32 index) { return mChild[index]; } + const oct_node* getChild(U32 index) const { return mChild[index]; } + child_list& getChildren() { return mChild; } + const child_list& getChildren() const { return mChild; } - virtual U32 getElementCount() const { return mData.size(); } - virtual element_list& getData() { return mData; } - virtual const element_list& getData() const { return mData; } + void accept(tree_traveler* visitor) const { visitor->visit(this); } + void accept(oct_traveler* visitor) const { visitor->visit(this); } - virtual U32 getChildCount() const { return mChild.size(); } - virtual oct_node* getChild(U32 index) { return mChild[index]; } - virtual const oct_node* getChild(U32 index) const { return mChild[index]; } - virtual child_list& getChildren() { return mChild; } - virtual const child_list& getChildren() const { return mChild; } - - virtual void accept(tree_traveler* visitor) const { visitor->visit(this); } - virtual void accept(oct_traveler* visitor) const { visitor->visit(this); } - const oct_node* getOctNode() const { return (const oct_node*) BaseType::getNode(); } - oct_node* getOctNode() { return (oct_node*) BaseType::getNode(); } - - virtual oct_node* getNodeAt(T* data) - { - return getNodeAt(data->getPositionGroup(), data->getBinRadius()); - } - - virtual oct_node* getNodeAt(const LLVector3d& pos, const F64& rad) + oct_node* getNodeAt(const LLVector3d& pos, const F64& rad) { - LLOctreeNode* node = getOctNode(); + LLOctreeNode* node = this; if (node->isInside(pos, rad)) { @@ -328,26 +283,19 @@ public: { if (data == NULL) { - OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl; + //OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl; return false; } - LLOctreeNode* node = getOctNode(); - LLOctreeNode* parent = node->getOctParent(); + LLOctreeNode* parent = getOctParent(); //is it here? - if (node->isInside(data->getPositionGroup())) + if (isInside(data->getPositionGroup())) { if (getElementCount() < LL_OCTREE_MAX_CAPACITY && - (node->contains(data->getBinRadius()) || - (data->getBinRadius() > node->getSize().mdV[0] && + (contains(data->getBinRadius()) || + (data->getBinRadius() > getSize().mdV[0] && parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY))) { //it belongs here - if (data == NULL) - { - OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE LEAF !!!" << llendl; - return false; - } - #if LL_OCTREE_PARANOIA_CHECK //if this is a redundant insertion, error out (should never happen) if (mData.find(data) != mData.end()) @@ -358,6 +306,7 @@ public: #endif mData.insert(data); + BaseType::insert(data); return true; } else @@ -375,8 +324,8 @@ public: } //it's here, but no kids are in the right place, make a new kid - LLVector3d center(node->getCenter()); - LLVector3d size(node->getSize()*0.5); + LLVector3d center(getCenter()); + LLVector3d size(getSize()*0.5); //push center in direction of data LLOctreeNode::pushCenter(center, size, data); @@ -386,7 +335,6 @@ public: { //this really isn't possible, something bad has happened OCT_ERRS << "Octree detected floating point error and gave up." << llendl; - //bool check = node->isInside(data); return false; } @@ -396,25 +344,25 @@ public: if (mChild[i]->getCenter() == center) { OCT_ERRS << "Octree detected duplicate child center and gave up." << llendl; - //bool check = node->isInside(data); - //check = getChild(i)->isInside(data); return false; } } #endif //make the new kid - LLOctreeState* newstate = new LLOctreeState(); - child = new LLOctreeNode(center, size, newstate, node); + child = new LLOctreeNode(center, size, this); addChild(child); - + child->insert(data); } } else { //it's not in here, give it to the root - LLOctreeNode* parent = node->getOctParent(); + //OCT_ERRS << "Octree insertion failed, starting over from root!" << llendl; + + oct_node* node = this; + while (parent) { node = parent; @@ -427,22 +375,20 @@ public: return false; } - virtual bool remove(T* data) + bool remove(T* data) { - oct_node* node = getOctNode(); - if (mData.find(data) != mData.end()) { //we have data mData.erase(data); - node->notifyRemoval(data); + notifyRemoval(data); checkAlive(); return true; } - else if (node->isInside(data)) + else if (isInside(data)) { oct_node* dest = getNodeAt(data); - if (dest != node) + if (dest != this) { return dest->remove(data); } @@ -451,7 +397,9 @@ public: //SHE'S GONE MISSING... //none of the children have it, let's just brute force this bastard out //starting with the root node (UGLY CODE COMETH!) - oct_node* parent = node->getOctParent(); + oct_node* parent = getOctParent(); + oct_node* node = this; + while (parent != NULL) { node = parent; @@ -464,12 +412,12 @@ public: return true; } - virtual void removeByAddress(T* data) + void removeByAddress(T* data) { if (mData.find(data) != mData.end()) { mData.erase(data); - getOctNode()->notifyRemoval(data); + notifyRemoval(data); llwarns << "FOUND!" << llendl; checkAlive(); return; @@ -482,20 +430,18 @@ public: } } - virtual void clearChildren() + void clearChildren() { mChild.clear(); } - virtual void validate() + void validate() { #if LL_OCTREE_PARANOIA_CHECK - LLOctreeNode* node = this->getOctNode(); - for (U32 i = 0; i < getChildCount(); i++) { mChild[i]->validate(); - if (mChild[i]->getParent() != node) + if (mChild[i]->getParent() != this) { llerrs << "Octree child has invalid parent." << llendl; } @@ -508,7 +454,7 @@ public: return false; } - virtual void destroy() + void destroy() { for (U32 i = 0; i < getChildCount(); i++) { @@ -517,7 +463,7 @@ public: } } - virtual void addChild(oct_node* child, BOOL silent = FALSE) + void addChild(oct_node* child, BOOL silent = FALSE) { #if LL_OCTREE_PARANOIA_CHECK for (U32 i = 0; i < getChildCount(); i++) @@ -539,27 +485,24 @@ public: #endif mChild.push_back(child); - child->setParent(getOctNode()); + child->setParent(this); if (!silent) { - oct_node* node = getOctNode(); - - for (U32 i = 0; i < node->getListenerCount(); i++) + for (U32 i = 0; i < this->getListenerCount(); i++) { - oct_listener* listener = node->getOctListener(i); - listener->handleChildAddition(node, child); + oct_listener* listener = getOctListener(i); + listener->handleChildAddition(this, child); } } } - virtual void removeChild(U8 index, BOOL destroy = FALSE) + void removeChild(U8 index, BOOL destroy = FALSE) { - oct_node* node = getOctNode(); - for (U32 i = 0; i < node->getListenerCount(); i++) + for (U32 i = 0; i < this->getListenerCount(); i++) { - oct_listener* listener = node->getOctListener(i); - listener->handleChildRemoval(node, getChild(index)); + oct_listener* listener = getOctListener(i); + listener->handleChildRemoval(this, getChild(index)); } if (destroy) @@ -572,20 +515,19 @@ public: checkAlive(); } - virtual void checkAlive() + void checkAlive() { if (getChildCount() == 0 && getElementCount() == 0) { - oct_node* node = getOctNode(); - oct_node* parent = node->getOctParent(); + oct_node* parent = getOctParent(); if (parent) { - parent->deleteChild(node); + parent->deleteChild(this); } } } - virtual void deleteChild(oct_node* node) + void deleteChild(oct_node* node) { for (U32 i = 0; i < getChildCount(); i++) { @@ -596,55 +538,62 @@ public: } } - OCT_ERRS << "Octree failed to delete requested child." << llendl; + //OCT_ERRS << "Octree failed to delete requested child." << llendl; } -protected: +protected: child_list mChild; element_list mData; + oct_node* mParent; + LLVector3d mCenter; + LLVector3d mSize; + LLVector3d mMax; + LLVector3d mMin; + U8 mOctant; }; -//just like a branch, except it might expand the node it points to +//just like a regular node, except it might expand on insert and compress on balance template -class LLOctreeRoot : public LLOctreeState +class LLOctreeRoot : public LLOctreeNode { public: - typedef LLOctreeState BaseType; + typedef LLOctreeNode BaseType; typedef LLOctreeNode oct_node; + + LLOctreeRoot( LLVector3d center, + LLVector3d size, + BaseType* parent) + : BaseType(center, size, parent) + { + } - LLOctreeRoot(oct_node* node = NULL) : BaseType(node) { } - - oct_node* getOctNode() { return BaseType::getOctNode(); } - virtual bool isLeaf() { return false; } + bool isLeaf() { return false; } - virtual bool balance() + bool balance() { - //the cached node might be invalid, so don't reference it if (this->getChildCount() == 1 && - !(this->mChild[0]->hasLeafState()) && + !(this->mChild[0]->isLeaf()) && this->mChild[0]->getElementCount() == 0) { //if we have only one child and that child is an empty branch, make that child the root - BaseType* state = this->mChild[0]->getOctState(); oct_node* child = this->mChild[0]; - oct_node* root = getOctNode(); - + //make the root node look like the child - root->setCenter(this->mChild[0]->getCenter()); - root->setSize(this->mChild[0]->getSize()); - root->updateMinMax(); + this->setCenter(this->mChild[0]->getCenter()); + this->setSize(this->mChild[0]->getSize()); + this->updateMinMax(); //reset root node child list this->clearChildren(); //copy the child's children into the root node silently //(don't notify listeners of addition) - for (U32 i = 0; i < state->getChildCount(); i++) + for (U32 i = 0; i < child->getChildCount(); i++) { - addChild(state->getChild(i), TRUE); + addChild(child->getChild(i), TRUE); } //destroy child - state->clearChildren(); + child->clearChildren(); delete child; } @@ -652,69 +601,90 @@ public: } // LLOctreeRoot::insert - virtual bool insert(T* data) + bool insert(T* data) { if (data == NULL) { - OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE ROOT !!!" << llendl; + //OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE ROOT !!!" << llendl; return false; } if (data->getBinRadius() > 4096.0) { - OCT_ERRS << "!!! ELEMENT EXCEDES MAXIMUM SIZE IN OCTREE ROOT !!!" << llendl; + //OCT_ERRS << "!!! ELEMENT EXCEEDS MAXIMUM SIZE IN OCTREE ROOT !!!" << llendl; + return false; } - LLOctreeNode* node = getOctNode(); - if (node->getSize().mdV[0] > data->getBinRadius() && node->isInside(data->getPositionGroup())) + const F64 MAX_MAG = 1024.0*1024.0; + + const LLVector3d& v = data->getPositionGroup(); + if (!(fabs(v.mdV[0]-this->mCenter.mdV[0]) < MAX_MAG && + fabs(v.mdV[1]-this->mCenter.mdV[1]) < MAX_MAG && + fabs(v.mdV[2]-this->mCenter.mdV[2]) < MAX_MAG)) + { + //OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl; + return false; + } + + if (this->getSize().mdV[0] > data->getBinRadius() && isInside(data->getPositionGroup())) { //we got it, just act like a branch - LLOctreeState::insert(data); + oct_node* node = getNodeAt(data); + if (node == this) + { + LLOctreeNode::insert(data); + } + else + { + node->insert(data); + } } else if (this->getChildCount() == 0) { //first object being added, just wrap it up - while (!(node->getSize().mdV[0] > data->getBinRadius() && node->isInside(data->getPositionGroup()))) + while (!(this->getSize().mdV[0] > data->getBinRadius() && isInside(data->getPositionGroup()))) { LLVector3d center, size; - center = node->getCenter(); - size = node->getSize(); + center = this->getCenter(); + size = this->getSize(); LLOctreeNode::pushCenter(center, size, data); - node->setCenter(center); - node->setSize(size*2); - node->updateMinMax(); + this->setCenter(center); + this->setSize(size*2); + this->updateMinMax(); } - LLOctreeState::insert(data); + LLOctreeNode::insert(data); } else { - //the data is outside the root node, we need to grow - LLVector3d center(node->getCenter()); - LLVector3d size(node->getSize()); - - //expand this node - LLVector3d newcenter(center); - LLOctreeNode::pushCenter(newcenter, size, data); - node->setCenter(newcenter); - node->setSize(size*2); - node->updateMinMax(); - - //copy our children to a new branch - LLOctreeState* newstate = new LLOctreeState(); - LLOctreeNode* newnode = new LLOctreeNode(center, size, newstate, node); - - for (U32 i = 0; i < this->getChildCount(); i++) + while (!(this->getSize().mdV[0] > data->getBinRadius() && isInside(data->getPositionGroup()))) { - LLOctreeNode* child = this->getChild(i); - newstate->addChild(child); - } + //the data is outside the root node, we need to grow + LLVector3d center(this->getCenter()); + LLVector3d size(this->getSize()); + + //expand this node + LLVector3d newcenter(center); + LLOctreeNode::pushCenter(newcenter, size, data); + this->setCenter(newcenter); + this->setSize(size*2); + this->updateMinMax(); + + //copy our children to a new branch + LLOctreeNode* newnode = new LLOctreeNode(center, size, this); + + for (U32 i = 0; i < this->getChildCount(); i++) + { + LLOctreeNode* child = this->getChild(i); + newnode->addChild(child); + } - //clear our children and add the root copy - this->clearChildren(); - addChild(newnode); + //clear our children and add the root copy + this->clearChildren(); + addChild(newnode); + } //insert the data - node->insert(data); + insert(data); } return false; @@ -726,13 +696,13 @@ public: // LLOctreeTraveler //======================== template -void LLOctreeTraveler::traverse(const LLTreeNode* node) +void LLOctreeTraveler::traverse(const LLTreeNode* tree_node) { - const LLOctreeState* state = (const LLOctreeState*) node->getState(); - state->accept(this); - for (U32 i = 0; i < state->getChildCount(); i++) + const LLOctreeNode* node = (const LLOctreeNode*) tree_node; + node->accept(this); + for (U32 i = 0; i < node->getChildCount(); i++) { - traverse(state->getChild(i)); + traverse(node->getChild(i)); } } diff --git a/linden/indra/llmath/llrect.h b/linden/indra/llmath/llrect.h index 76b5a27..9aadf9f 100644 --- a/linden/indra/llmath/llrect.h +++ b/linden/indra/llmath/llrect.h @@ -152,68 +152,74 @@ public: mBottom <= rect->mTop && rect->mBottom <= mTop ; } - void set(Type left, Type top, Type right, Type bottom) + LLRectBase& set(Type left, Type top, Type right, Type bottom) { mLeft = left; mTop = top; mRight = right; mBottom = bottom; + return *this; } // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect - void setOriginAndSize( Type left, Type bottom, Type width, Type height) + LLRectBase& setOriginAndSize( Type left, Type bottom, Type width, Type height) { mLeft = left; mTop = bottom + height; mRight = left + width; mBottom = bottom; + return *this; } // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect - void setLeftTopAndSize( Type left, Type top, Type width, Type height) + LLRectBase& setLeftTopAndSize( Type left, Type top, Type width, Type height) { mLeft = left; mTop = top; mRight = left + width; mBottom = top - height; + return *this; } - void setCenterAndSize(Type x, Type y, Type width, Type height) + LLRectBase& setCenterAndSize(Type x, Type y, Type width, Type height) { mLeft = x - width/2; mTop = y + height/2; mRight = x + width/2; mBottom = y - height/2; + return *this; } - void translate(Type horiz, Type vertical) + LLRectBase& translate(Type horiz, Type vertical) { mLeft += horiz; mRight += horiz; mTop += vertical; mBottom += vertical; + return *this; } - void stretch( Type dx, Type dy) + LLRectBase& stretch( Type dx, Type dy) { mLeft -= dx; mRight += dx; mTop += dy; mBottom -= dy; - makeValid(); + return makeValid(); } - void stretch( Type delta ) + LLRectBase& stretch( Type delta ) { stretch(delta, delta); - + return *this; } - void makeValid() + LLRectBase& makeValid() { mLeft = llmin(mLeft, mRight); mBottom = llmin(mBottom, mTop); + return *this; } bool isNull() const @@ -221,15 +227,16 @@ public: return mLeft == mRight || mBottom == mTop; } - void unionWith(const LLRectBase &other) + LLRectBase& unionWith(const LLRectBase &other) { mLeft = llmin(mLeft, other.mLeft); mRight = llmax(mRight, other.mRight); mBottom = llmin(mBottom, other.mBottom); mTop = llmax(mTop, other.mTop); + return *this; } - void intersectWith(const LLRectBase &other) + LLRectBase& intersectWith(const LLRectBase &other) { mLeft = llmax(mLeft, other.mLeft); mRight = llmin(mRight, other.mRight); @@ -243,6 +250,7 @@ public: { mBottom = mTop; } + return *this; } friend std::ostream &operator<<(std::ostream &s, const LLRectBase &rect) diff --git a/linden/indra/llmath/lltreenode.h b/linden/indra/llmath/lltreenode.h index 160a5bd..64beed8 100644 --- a/linden/indra/llmath/lltreenode.h +++ b/linden/indra/llmath/lltreenode.h @@ -40,23 +40,6 @@ template class LLTreeTraveler; template class LLTreeListener; template -class LLTreeState -{ -public: - LLTreeState(LLTreeNode* node) { setNode(node); } - virtual ~LLTreeState() { }; - virtual bool insert(T* data) = 0; - virtual bool remove(T* data) = 0; - virtual void setNode(LLTreeNode* node); - virtual const LLTreeNode* getNode() const { return mNode; } - virtual LLTreeNode* getNode() { return mNode; } - virtual void accept(LLTreeTraveler* traveler) const = 0; - virtual LLTreeListener* getListener(U32 index) const; -private: - LLTreeNode* mNode; -}; - -template class LLTreeListener: public LLRefCount { public: @@ -70,19 +53,14 @@ template class LLTreeNode { public: - LLTreeNode(LLTreeState* state) { setState(state); } virtual ~LLTreeNode(); - LLTreeState* getState() { return mState; } - const LLTreeState* getState() const { return mState; } - - void setState(LLTreeState* state); - void insert(T* data); - bool remove(T* data); - void notifyRemoval(T* data); - inline U32 getListenerCount() { return mListeners.size(); } - inline LLTreeListener* getListener(U32 index) const { return mListeners[index]; } - inline void addListener(LLTreeListener* listener) { mListeners.push_back(listener); } - inline void removeListener(U32 index) { mListeners.erase(mListeners.begin()+index); } + + virtual bool insert(T* data); + virtual bool remove(T* data); + virtual void notifyRemoval(T* data); + virtual U32 getListenerCount() { return mListeners.size(); } + virtual LLTreeListener* getListener(U32 index) const { return mListeners[index]; } + virtual void addListener(LLTreeListener* listener) { mListeners.push_back(listener); } protected: void destroyListeners() @@ -94,7 +72,6 @@ protected: mListeners.clear(); } - LLTreeState* mState; public: std::vector > > mListeners; }; @@ -105,7 +82,7 @@ class LLTreeTraveler public: virtual ~LLTreeTraveler() { }; virtual void traverse(const LLTreeNode* node) = 0; - virtual void visit(const LLTreeState* state) = 0; + virtual void visit(const LLTreeNode* node) = 0; }; template @@ -115,25 +92,19 @@ LLTreeNode::~LLTreeNode() }; template -void LLTreeNode::insert(T* data) +bool LLTreeNode::insert(T* data) { - if (mState->insert(data)) + for (U32 i = 0; i < mListeners.size(); i++) { - for (U32 i = 0; i < mListeners.size(); i++) - { - mListeners[i]->handleInsertion(this, data); - } + mListeners[i]->handleInsertion(this, data); } + return true; }; template bool LLTreeNode::remove(T* data) { - if (mState->remove(data)) - { - return true; - } - return false; + return true; }; template @@ -145,38 +116,4 @@ void LLTreeNode::notifyRemoval(T* data) } } -template -void LLTreeNode::setState(LLTreeState* state) -{ - mState = state; - if (state) - { - if (state->getNode() != this) - { - state->setNode(this); - } - - for (U32 i = 0; i < mListeners.size(); i++) - { - mListeners[i]->handleStateChange(this); - } - } -}; - -template -void LLTreeState::setNode(LLTreeNode* node) -{ - mNode = node; - if (node && node->getState() != this) - { - node->setState(this); - } -}; - -template -LLTreeListener* LLTreeState::getListener(U32 index) const -{ - return mNode->getListener(index); -} - #endif diff --git a/linden/indra/llmath/llvolume.cpp b/linden/indra/llmath/llvolume.cpp index 3316168..266ec08 100644 --- a/linden/indra/llmath/llvolume.cpp +++ b/linden/indra/llmath/llvolume.cpp @@ -1639,12 +1639,27 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge } } +void LLVolume::resizePath(S32 length) +{ + mPathp->resizePath(length); + if (mVolumeFaces != NULL) + { + delete[] mVolumeFaces; + mVolumeFaces = NULL; + } +} + void LLVolume::regen() { generate(); createVolumeFaces(); } +void LLVolume::genBinormals(S32 face) +{ + mVolumeFaces[face].createBinormals(); +} + LLVolume::~LLVolume() { sNumMeshPoints -= mMesh.size(); @@ -1746,12 +1761,6 @@ void LLVolume::createVolumeFaces() { S32 i; - if (mVolumeFaces != NULL) - { - delete[] mVolumeFaces; - mVolumeFaces = NULL; - } - if (mGenerateSingleFace) { mNumVolumeFaces = 0; @@ -1760,7 +1769,12 @@ void LLVolume::createVolumeFaces() { S32 num_faces = getNumFaces(); mNumVolumeFaces = num_faces; - mVolumeFaces = new LLVolumeFace[num_faces]; + BOOL partial_build = TRUE; + if (!mVolumeFaces) + { + partial_build = FALSE; + mVolumeFaces = new LLVolumeFace[num_faces]; + } // Initialize volume faces with parameter data for (i = 0; i < num_faces; i++) { @@ -1823,7 +1837,7 @@ void LLVolume::createVolumeFaces() for (i = 0; i < mNumVolumeFaces; i++) { - mVolumeFaces[i].create(); + mVolumeFaces[i].create(partial_build); } } } @@ -1840,55 +1854,70 @@ inline LLVector3 sculpt_rgb_to_vector(U8 r, U8 g, U8 b) return value; } +inline U32 sculpt_xy_to_index(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components) +{ + U32 index = (x + y * sculpt_width) * sculpt_components; -// sculpt replaces generate() for sculpted surfaces -void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level) + // attempt to resolve DEV-11158 - remove assert later. + llassert(index < sculpt_width * sculpt_height * sculpt_components); + + return index; +} + + +inline U32 sculpt_st_to_index(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components) { - U8 sculpt_type = mParams.getSculptType(); + U32 x = (U32) ((F32)s/(size_s) * (F32) sculpt_width); + U32 y = (U32) ((F32)t/(size_t) * (F32) sculpt_height); - BOOL data_is_empty = FALSE; + return sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); +} - if (sculpt_width == 0 || sculpt_height == 0 || sculpt_data == NULL) - { - sculpt_level = -1; - data_is_empty = TRUE; - } - mPathp->generate(mDetail, 0, TRUE); - mProfilep->generate(mPathp->isOpen(), mDetail, 0, TRUE); - +inline LLVector3 sculpt_index_to_vector(U32 index, const U8* sculpt_data) +{ + LLVector3 v = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]); + + return v; +} + +inline LLVector3 sculpt_st_to_vector(S32 s, S32 t, S32 size_s, S32 size_t, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) +{ + U32 index = sculpt_st_to_index(s, t, size_s, size_t, sculpt_width, sculpt_height, sculpt_components); + + return sculpt_index_to_vector(index, sculpt_data); +} + +inline LLVector3 sculpt_xy_to_vector(U32 x, U32 y, U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) +{ + U32 index = sculpt_xy_to_index(x, y, sculpt_width, sculpt_height, sculpt_components); + + return sculpt_index_to_vector(index, sculpt_data); +} + + +F32 LLVolume::sculptGetSurfaceArea(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data) +{ + // test to see if image has enough variation to create non-degenerate geometry + S32 sizeS = mPathp->mPath.size(); S32 sizeT = mProfilep->mProfile.size(); - sNumMeshPoints -= mMesh.size(); - mMesh.resize(sizeS * sizeT); - sNumMeshPoints += mMesh.size(); - F32 area = 0; - // first test to see if image has enough variation to create non-degenerate geometry - if (!data_is_empty) + + if ((sculpt_width != 0) && + (sculpt_height != 0) && + (sculpt_components != 0) && + (sculpt_data != NULL)) { for (S32 s = 0; s < sizeS - 1; s++) { for (S32 t = 0; t < sizeT - 1; t++) { - // first coordinate - U32 x = (U32) ((F32)s/(sizeS) * (F32) sculpt_width); - U32 y = (U32) ((F32)t/(sizeT) * (F32) sculpt_height); - - // coordinate offset by 1 - U32 x2 = (U32) ((F32)(s+1)/(sizeS) * (F32) sculpt_width); - U32 y2 = (U32) ((F32)(t+1)/(sizeT) * (F32) sculpt_height); - - // three points on a triagle - find the image indices first - U32 p1_index = (x + y * sculpt_width) * sculpt_components; - U32 p2_index = (x2 + y * sculpt_width) * sculpt_components; - U32 p3_index = (x + y2 * sculpt_width) * sculpt_components; - // convert image data to vectors - LLVector3 p1 = sculpt_rgb_to_vector(sculpt_data[p1_index], sculpt_data[p1_index+1], sculpt_data[p1_index+2]); - LLVector3 p2 = sculpt_rgb_to_vector(sculpt_data[p2_index], sculpt_data[p2_index+1], sculpt_data[p2_index+2]); - LLVector3 p3 = sculpt_rgb_to_vector(sculpt_data[p3_index], sculpt_data[p3_index+1], sculpt_data[p3_index+2]); + LLVector3 p1 = sculpt_st_to_vector(s, t, sizeS, sizeT, sculpt_width, sculpt_height, sculpt_components, sculpt_data); + LLVector3 p2 = sculpt_st_to_vector(s+1, t, sizeS, sizeT, sculpt_width, sculpt_height, sculpt_components, sculpt_data); + LLVector3 p3 = sculpt_st_to_vector(s, t+1, sizeS, sizeT, sculpt_width, sculpt_height, sculpt_components, sculpt_data); // compute the area of the parallelogram by taking the length of the cross product: // (parallegram is an approximation of two triangles) @@ -1896,99 +1925,151 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, area += cross.magVec(); } } - if (area < SCULPT_MIN_AREA) - data_is_empty = TRUE; } - //generate vertex positions - if (data_is_empty) // if empty, make a sphere - { - S32 line = 0; + return area; +} + +// create placeholder shape +void LLVolume::sculptGeneratePlaceholder() +{ + S32 sizeS = mPathp->mPath.size(); + S32 sizeT = mProfilep->mProfile.size(); + + S32 line = 0; - for (S32 s = 0; s < sizeS; s++) + // for now, this is a sphere. + for (S32 s = 0; s < sizeS; s++) + { + for (S32 t = 0; t < sizeT; t++) { - for (S32 t = 0; t < sizeT; t++) - { - S32 i = t + line; - Point& pt = mMesh[i]; + S32 i = t + line; + Point& pt = mMesh[i]; - F32 u = (F32)s/(sizeS-1); - F32 v = (F32)t/(sizeT-1); + F32 u = (F32)s/(sizeS-1); + F32 v = (F32)t/(sizeT-1); - const F32 RADIUS = (F32) 0.3; + const F32 RADIUS = (F32) 0.3; - pt.mPos.mV[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); - pt.mPos.mV[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); - pt.mPos.mV[2] = (F32)(cos(F_PI * v) * RADIUS); + pt.mPos.mV[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS); + pt.mPos.mV[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS); + pt.mPos.mV[2] = (F32)(cos(F_PI * v) * RADIUS); - } - line += sizeT; } - } - else + line += sizeT; + } +} + +// create the vertices from the map +void LLVolume::sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type) +{ + S32 sizeS = mPathp->mPath.size(); + S32 sizeT = mProfilep->mProfile.size(); + + S32 line = 0; + for (S32 s = 0; s < sizeS; s++) { - S32 line = 0; - for (S32 s = 0; s < sizeS; s++) + // Run along the profile. + for (S32 t = 0; t < sizeT; t++) { - // Run along the profile. - for (S32 t = 0; t < sizeT; t++) - { - S32 i = t + line; - Point& pt = mMesh[i]; + S32 i = t + line; + Point& pt = mMesh[i]; - U32 x = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_width); - U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); + U32 x = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_width); + U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height); - if (y == 0) // top row stitching + if (y == 0) // top row stitching + { + // pinch? + if (sculpt_type == LL_SCULPT_TYPE_SPHERE) { - // pinch? - if (sculpt_type == LL_SCULPT_TYPE_SPHERE) - { - x = sculpt_width / 2; - } + x = sculpt_width / 2; } + } - if (y == sculpt_height) // bottom row stitching + if (y == sculpt_height) // bottom row stitching + { + // wrap? + if (sculpt_type == LL_SCULPT_TYPE_TORUS) { - // wrap? - if (sculpt_type == LL_SCULPT_TYPE_TORUS) - { - y = 0; - } - else - { - y = sculpt_height - 1; - } + y = 0; + } + else + { + y = sculpt_height - 1; + } - // pinch? - if (sculpt_type == LL_SCULPT_TYPE_SPHERE) - { - x = sculpt_width / 2; - } + // pinch? + if (sculpt_type == LL_SCULPT_TYPE_SPHERE) + { + x = sculpt_width / 2; } + } - if (x == sculpt_width) // side stitching + if (x == sculpt_width) // side stitching + { + // wrap? + if ((sculpt_type == LL_SCULPT_TYPE_SPHERE) || + (sculpt_type == LL_SCULPT_TYPE_TORUS) || + (sculpt_type == LL_SCULPT_TYPE_CYLINDER)) { - // wrap? - if ((sculpt_type == LL_SCULPT_TYPE_SPHERE) || - (sculpt_type == LL_SCULPT_TYPE_TORUS) || - (sculpt_type == LL_SCULPT_TYPE_CYLINDER)) - { - x = 0; - } + x = 0; + } - else - { - x = sculpt_width - 1; - } + else + { + x = sculpt_width - 1; } - - U32 index = (x + y * sculpt_width) * sculpt_components; - pt.mPos = sculpt_rgb_to_vector(sculpt_data[index], sculpt_data[index+1], sculpt_data[index+2]); } - line += sizeT; + + pt.mPos = sculpt_xy_to_vector(x, y, sculpt_width, sculpt_height, sculpt_components, sculpt_data); } + line += sizeT; + } +} + + +// sculpt replaces generate() for sculpted surfaces +void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level) +{ + U8 sculpt_type = mParams.getSculptType(); + + BOOL data_is_empty = FALSE; + + if (sculpt_width == 0 || sculpt_height == 0 || sculpt_components == 0 || sculpt_data == NULL) + { + sculpt_level = -1; + data_is_empty = TRUE; + } + + mPathp->generate(mDetail, 0, TRUE); + mProfilep->generate(mPathp->isOpen(), mDetail, 0, TRUE); + + S32 sizeS = mPathp->mPath.size(); + S32 sizeT = mProfilep->mProfile.size(); + + // weird crash bug - DEV-11158 - trying to collect more data: + if ((sizeS == 0) || (sizeT == 0)) + { + llwarns << "sculpt bad mesh size " << sizeS << " " << sizeT << llendl; + } + + sNumMeshPoints -= mMesh.size(); + mMesh.resize(sizeS * sizeT); + sNumMeshPoints += mMesh.size(); + + if (sculptGetSurfaceArea(sculpt_width, sculpt_height, sculpt_components, sculpt_data) < SCULPT_MIN_AREA) + data_is_empty = TRUE; + + //generate vertex positions + if (data_is_empty) // if empty, make a placeholder mesh + { + sculptGeneratePlaceholder(); + } + else + { + sculptGenerateMapVertices(sculpt_width, sculpt_height, sculpt_components, sculpt_data, sculpt_type); } for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++) @@ -3967,18 +4048,19 @@ LLVolumeFace::LLVolumeFace() mBeginT = 0; mNumS = 0; mNumT = 0; + mHasBinormals = FALSE; } -BOOL LLVolumeFace::create() +BOOL LLVolumeFace::create(BOOL partial_build) { if (mTypeMask & CAP_MASK) { - return createCap(); + return createCap(partial_build); } else if ((mTypeMask & END_MASK) || (mTypeMask & SIDE_MASK)) { - return createSide(); + return createSide(partial_build); } else { @@ -4000,7 +4082,7 @@ void LerpPlanarVertex(LLVolumeFace::VertexData& v0, vout.mBinormal = v0.mBinormal; } -BOOL LLVolumeFace::createUnCutCubeCap() +BOOL LLVolumeFace::createUnCutCubeCap(BOOL partial_build) { const std::vector& mesh = mVolumep->getMesh(); const std::vector& profile = mVolumep->getProfile().mProfile; @@ -4055,6 +4137,12 @@ BOOL LLVolumeFace::createUnCutCubeCap() corners[t].mBinormal = baseVert.mBinormal; corners[t].mNormal = baseVert.mNormal; } + mHasBinormals = TRUE; + + if (partial_build) + { + mVertices.clear(); + } S32 vtop = mVertices.size(); for(int gx = 0;gx=0;i--)mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); - }else{ - for(int i=0;i<6;i++)mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); + if (!partial_build) + { + int idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0}; + for(int gx = 0;gx=0;i--)mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); + }else{ + for(int i=0;i<6;i++)mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]); + } } } } - + return TRUE; } -BOOL LLVolumeFace::createCap() +BOOL LLVolumeFace::createCap(BOOL partial_build) { if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK) && @@ -4106,7 +4197,7 @@ BOOL LLVolumeFace::createCap() (mVolumep->getProfile().mParams.getCurveType()==LL_PCODE_PROFILE_SQUARE && mVolumep->getPath().mParams.getCurveType()==LL_PCODE_PATH_LINE) ){ - return createUnCutCubeCap(); + return createUnCutCubeCap(partial_build); } S32 i; @@ -4118,8 +4209,13 @@ BOOL LLVolumeFace::createCap() // All types of caps have the same number of vertices and indices num_vertices = profile.size(); num_indices = (profile.size() - 2)*3; - vector_append(mVertices,num_vertices); - vector_append(mIndices,num_indices); + + mVertices.resize(num_vertices); + + if (!partial_build) + { + mIndices.resize(num_indices); + } S32 max_s = mVolumep->getProfile().getTotal(); S32 max_t = mVolumep->getPath().mPath.size(); @@ -4203,7 +4299,10 @@ BOOL LLVolumeFace::createCap() { mVertices.push_back(vd); num_vertices++; - vector_append(mIndices, 3); + if (!partial_build) + { + vector_append(mIndices, 3); + } } @@ -4213,6 +4312,13 @@ BOOL LLVolumeFace::createCap() mVertices[i].mNormal = normal; } + mHasBinormals = TRUE; + + if (partial_build) + { + return TRUE; + } + if (mTypeMask & HOLLOW_MASK) { if (mTypeMask & TOP_MASK) @@ -4480,7 +4586,50 @@ BOOL LLVolumeFace::createCap() return TRUE; } -BOOL LLVolumeFace::createSide() +void LLVolumeFace::createBinormals() +{ + if (!mHasBinormals) + { + //generate binormals + for (U32 i = 0; i < mIndices.size()/3; i++) + { //for each triangle + const VertexData& v0 = mVertices[mIndices[i*3+0]]; + const VertexData& v1 = mVertices[mIndices[i*3+1]]; + const VertexData& v2 = mVertices[mIndices[i*3+2]]; + + //calculate binormal + LLVector3 binorm = calc_binormal_from_triangle(v0.mPosition, v0.mTexCoord, + v1.mPosition, v1.mTexCoord, + v2.mPosition, v2.mTexCoord); + + for (U32 j = 0; j < 3; j++) + { //add triangle normal to vertices + mVertices[mIndices[i*3+j]].mBinormal += binorm; // * (weight_sum - d[j])/weight_sum; + } + + //even out quad contributions + if (i % 2 == 0) + { + mVertices[mIndices[i*3+2]].mBinormal += binorm; + } + else + { + mVertices[mIndices[i*3+1]].mBinormal += binorm; + } + } + + //normalize binormals + for (U32 i = 0; i < mVertices.size(); i++) + { + mVertices[i].mBinormal.normVec(); + mVertices[i].mNormal.normVec(); + } + + mHasBinormals = TRUE; + } +} + +BOOL LLVolumeFace::createSide(BOOL partial_build) { BOOL flat = mTypeMask & FLAT_MASK; S32 num_vertices, num_indices; @@ -4496,9 +4645,14 @@ BOOL LLVolumeFace::createSide() num_vertices = mNumS*mNumT; num_indices = (mNumS-1)*(mNumT-1)*6; - vector_append(mVertices,num_vertices); - vector_append(mIndices,num_indices); - vector_append(mEdge, num_indices); + + mVertices.resize(num_vertices); + + if (!partial_build) + { + mIndices.resize(num_indices); + mEdge.resize(num_indices); + } LLVector3& face_min = mExtents[0]; LLVector3& face_max = mExtents[1]; @@ -4609,61 +4763,63 @@ BOOL LLVolumeFace::createSide() S32 cur_edge = 0; BOOL flat_face = mTypeMask & FLAT_MASK; - // Now we generate the indices. - for (t = 0; t < (mNumT-1); t++) - { - for (s = 0; s < (mNumS-1); s++) - { - mIndices[cur_index++] = s + mNumS*t; //bottom left - mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right - mIndices[cur_index++] = s + mNumS*(t+1); //top left - mIndices[cur_index++] = s + mNumS*t; //bottom left - mIndices[cur_index++] = s+1 + mNumS*t; //bottom right - mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right - - mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face - if (t < mNumT-2) { //top right/top left neighbor face - mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1; - } - else if (mNumT <= 3 || mVolumep->getPath().isOpen() == TRUE) { //no neighbor - mEdge[cur_edge++] = -1; - } - else { //wrap on T - mEdge[cur_edge++] = s*2+1; - } - if (s > 0) { //top left/bottom left neighbor face - mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1; - } - else if (flat_face || mVolumep->getProfile().isOpen() == TRUE) { //no neighbor - mEdge[cur_edge++] = -1; - } - else { //wrap on S - mEdge[cur_edge++] = (mNumS-1)*2*t+(mNumS-2)*2+1; - } - - if (t > 0) { //bottom left/bottom right neighbor face - mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2; - } - else if (mNumT <= 3 || mVolumep->getPath().isOpen() == TRUE) { //no neighbor - mEdge[cur_edge++] = -1; - } - else { //wrap on T - mEdge[cur_edge++] = (mNumS-1)*2*(mNumT-2)+s*2; - } - if (s < mNumS-2) { //bottom right/top right neighbor face - mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2; - } - else if (flat_face || mVolumep->getProfile().isOpen() == TRUE) { //no neighbor - mEdge[cur_edge++] = -1; - } - else { //wrap on S - mEdge[cur_edge++] = (mNumS-1)*2*t; + if (!partial_build) + { + // Now we generate the indices. + for (t = 0; t < (mNumT-1); t++) + { + for (s = 0; s < (mNumS-1); s++) + { + mIndices[cur_index++] = s + mNumS*t; //bottom left + mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right + mIndices[cur_index++] = s + mNumS*(t+1); //top left + mIndices[cur_index++] = s + mNumS*t; //bottom left + mIndices[cur_index++] = s+1 + mNumS*t; //bottom right + mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right + + mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face + if (t < mNumT-2) { //top right/top left neighbor face + mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1; + } + else if (mNumT <= 3 || mVolumep->getPath().isOpen() == TRUE) { //no neighbor + mEdge[cur_edge++] = -1; + } + else { //wrap on T + mEdge[cur_edge++] = s*2+1; + } + if (s > 0) { //top left/bottom left neighbor face + mEdge[cur_edge++] = (mNumS-1)*2*t+s*2-1; + } + else if (flat_face || mVolumep->getProfile().isOpen() == TRUE) { //no neighbor + mEdge[cur_edge++] = -1; + } + else { //wrap on S + mEdge[cur_edge++] = (mNumS-1)*2*t+(mNumS-2)*2+1; + } + + if (t > 0) { //bottom left/bottom right neighbor face + mEdge[cur_edge++] = (mNumS-1)*2*(t-1)+s*2; + } + else if (mNumT <= 3 || mVolumep->getPath().isOpen() == TRUE) { //no neighbor + mEdge[cur_edge++] = -1; + } + else { //wrap on T + mEdge[cur_edge++] = (mNumS-1)*2*(mNumT-2)+s*2; + } + if (s < mNumS-2) { //bottom right/top right neighbor face + mEdge[cur_edge++] = (mNumS-1)*2*t+(s+1)*2; + } + else if (flat_face || mVolumep->getProfile().isOpen() == TRUE) { //no neighbor + mEdge[cur_edge++] = -1; + } + else { //wrap on S + mEdge[cur_edge++] = (mNumS-1)*2*t; + } + mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face } - mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face } } - //generate normals for (U32 i = 0; i < mIndices.size()/3; i++) { //for each triangle const VertexData& v0 = mVertices[mIndices[i*3+0]]; @@ -4674,27 +4830,22 @@ BOOL LLVolumeFace::createSide() LLVector3 norm = (v0.mPosition-v1.mPosition)% (v0.mPosition-v2.mPosition); - //calculate binormal - LLVector3 binorm = calc_binormal_from_triangle(v0.mPosition, v0.mTexCoord, - v1.mPosition, v1.mTexCoord, - v2.mPosition, v2.mTexCoord); - - for (U32 j = 0; j < 3; j++) { //add triangle normal to vertices + for (U32 j = 0; j < 3; j++) + { //add triangle normal to vertices mVertices[mIndices[i*3+j]].mNormal += norm; // * (weight_sum - d[j])/weight_sum; - mVertices[mIndices[i*3+j]].mBinormal += binorm; // * (weight_sum - d[j])/weight_sum; } //even out quad contributions - if (i % 2 == 0) { + if (i % 2 == 0) + { mVertices[mIndices[i*3+2]].mNormal += norm; - mVertices[mIndices[i*3+2]].mBinormal += binorm; } - else { + else + { mVertices[mIndices[i*3+1]].mNormal += norm; - mVertices[mIndices[i*3+1]].mBinormal += binorm; } } - + // adjust normals based on wrapping and stitching BOOL s_bottom_converges = ((mVertices[0].mPosition - mVertices[mNumS*(mNumT-2)].mPosition).magVecSquared() < 0.000001f); @@ -4820,15 +4971,6 @@ BOOL LLVolumeFace::createSide() } - - //normalize normals and binormals here so the meshes that reference - //this volume data don't have to - for (U32 i = 0; i < mVertices.size(); i++) - { - mVertices[i].mNormal.normVec(); - mVertices[i].mBinormal.normVec(); - } - return TRUE; } diff --git a/linden/indra/llmath/llvolume.h b/linden/indra/llmath/llvolume.h index 7b384f2..5ec7997 100644 --- a/linden/indra/llmath/llvolume.h +++ b/linden/indra/llmath/llvolume.h @@ -762,7 +762,8 @@ class LLVolumeFace { public: LLVolumeFace(); - BOOL create(); + BOOL create(BOOL partial_build = FALSE); + void createBinormals(); class VertexData { @@ -792,6 +793,7 @@ public: S32 mID; U32 mTypeMask; LLVector3 mCenter; + BOOL mHasBinormals; // Only used for INNER/OUTER faces S32 mBeginS; @@ -802,7 +804,7 @@ public: LLVector3 mExtents[2]; //minimum and maximum point of face std::vector mVertices; - std::vector mIndices; + std::vector mIndices; std::vector mEdge; LLVolume *mVolumep; // Deliberately NOT reference counted - djs 11/20/03 - otherwise would make an annoying circular reference @@ -811,9 +813,9 @@ public: LLStrider &new_colors, const S32 num_new, const LLVolumeFace &new_face); protected: - BOOL createUnCutCubeCap(); - BOOL createCap(); - BOOL createSide(); + BOOL createUnCutCubeCap(BOOL partial_build = FALSE); + BOOL createCap(BOOL partial_build = FALSE); + BOOL createSide(BOOL partial_build = FALSE); }; class LLVolume : public LLRefCount @@ -850,12 +852,14 @@ public: LLVolumeParams getCopyOfParams() const { return mParams; } const LLProfile& getProfile() const { return *mProfilep; } LLPath& getPath() const { return *mPathp; } + void resizePath(S32 length); const std::vector& getMesh() const { return mMesh; } const LLVector3& getMeshPt(const U32 i) const { return mMesh[i].mPos; } void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); } void regen(); + void genBinormals(S32 face); BOOL isConvex() const; BOOL isCap(S32 face); @@ -899,6 +903,10 @@ public: LLVector3 mLODScaleBias; // vector for biasing LOD based on scale void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level); +private: + F32 sculptGetSurfaceArea(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data); + void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type); + void sculptGeneratePlaceholder(); protected: BOOL generate(); diff --git a/linden/indra/llmath/llvolumemgr.cpp b/linden/indra/llmath/llvolumemgr.cpp index 17bafcd..4bf7ca6 100644 --- a/linden/indra/llmath/llvolumemgr.cpp +++ b/linden/indra/llmath/llvolumemgr.cpp @@ -283,6 +283,29 @@ S32 LLVolumeLODGroup::getDetailFromTan(const F32 tan_angle) return NUM_LODS - 1; } +void LLVolumeLODGroup::getDetailProximity(const F32 tan_angle, F32 &to_lower, F32& to_higher) +{ + S32 detail = getDetailFromTan(tan_angle); + + if (detail > 0) + { + to_lower = tan_angle - mDetailThresholds[detail]; + } + else + { + to_lower = 1024.f*1024.f; + } + + if (detail < NUM_LODS-1) + { + to_higher = mDetailThresholds[detail+1] - tan_angle; + } + else + { + to_higher = 1024.f*1024.f; + } +} + F32 LLVolumeLODGroup::getVolumeScaleFromDetail(const S32 detail) { return mDetailScales[detail]; diff --git a/linden/indra/llmath/llvolumemgr.h b/linden/indra/llmath/llvolumemgr.h index 0688163..0d6aa56 100644 --- a/linden/indra/llmath/llvolumemgr.h +++ b/linden/indra/llmath/llvolumemgr.h @@ -56,6 +56,7 @@ public: BOOL derefLOD(LLVolume *volumep); static S32 getDetailFromTan(const F32 tan_angle); + static void getDetailProximity(const F32 tan_angle, F32 &to_lower, F32& to_higher); static F32 getVolumeScaleFromDetail(const S32 detail); LLVolume *getLOD(const S32 detail); diff --git a/linden/indra/llmath/v3color.cpp b/linden/indra/llmath/v3color.cpp index cc4f874..9bdcd27 100644 --- a/linden/indra/llmath/v3color.cpp +++ b/linden/indra/llmath/v3color.cpp @@ -33,6 +33,7 @@ #include "v3color.h" #include "v4color.h" +#include "v4math.h" LLColor3 LLColor3::white(1.0f, 1.0f, 1.0f); LLColor3 LLColor3::black(0.0f, 0.0f, 0.0f); @@ -45,6 +46,13 @@ LLColor3::LLColor3(const LLColor4 &a) mV[2] = a.mV[2]; } +LLColor3::LLColor3(const LLVector4 &a) +{ + mV[0] = a.mV[0]; + mV[1] = a.mV[1]; + mV[2] = a.mV[2]; +} + LLColor3::LLColor3(const LLSD &sd) { mV[0] = (F32) sd[0].asReal(); diff --git a/linden/indra/llmath/v3color.h b/linden/indra/llmath/v3color.h index 782ccd7..a3bf385 100644 --- a/linden/indra/llmath/v3color.h +++ b/linden/indra/llmath/v3color.h @@ -33,6 +33,7 @@ #define LL_V3COLOR_H class LLColor4; +class LLVector4; #include "llerror.h" #include "llmath.h" @@ -57,6 +58,7 @@ public: LLColor3(const F32 *vec); // Initializes LLColor3 to (vec[0]. vec[1], vec[2]) LLColor3(char *color_string); // html format color ie "#FFDDEE" explicit LLColor3(const LLColor4& color4); // "explicit" to avoid automatic conversion + explicit LLColor3(const LLVector4& vector4); // "explicit" to avoid automatic conversion LLColor3(const LLSD& sd); @@ -87,6 +89,7 @@ public: F32 magVec() const; // Returns magnitude of LLColor3 F32 magVecSquared() const; // Returns magnitude squared of LLColor3 F32 normVec(); // Normalizes and returns the magnitude of LLColor3 + F32 brightness() const; // Returns brightness of LLColor3 const LLColor3& operator=(const LLColor4 &a); @@ -98,7 +101,7 @@ public: friend const LLColor3& operator-=(LLColor3 &a, const LLColor3 &b); // Return vector a minus b friend const LLColor3& operator*=(LLColor3 &a, const LLColor3 &b); - friend LLColor3 operator*(const LLColor3 &a, const LLColor3 &b); // Return a dot b + friend LLColor3 operator*(const LLColor3 &a, const LLColor3 &b); // Return component wise a * b friend LLColor3 operator*(const LLColor3 &a, F32 k); // Return a times scaler k friend LLColor3 operator*(F32 k, const LLColor3 &a); // Return a times scaler k @@ -231,6 +234,11 @@ inline const LLColor3& LLColor3::setVec(const F32 *vec) return (*this); } +inline F32 LLColor3::brightness(void) const +{ + return (mV[0] + mV[1] + mV[2]) / 3.0f; +} + inline F32 LLColor3::magVec(void) const { return fsqrtf(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); diff --git a/linden/indra/llmath/v4color.cpp b/linden/indra/llmath/v4color.cpp index b1884b7..8e6907e 100644 --- a/linden/indra/llmath/v4color.cpp +++ b/linden/indra/llmath/v4color.cpp @@ -36,7 +36,7 @@ #include "v4color.h" #include "v4coloru.h" #include "v3color.h" -//#include "vmath.h" +#include "v4math.h" #include "llmath.h" // LLColor4 @@ -153,6 +153,14 @@ LLColor4::LLColor4(const LLColor4U& color4u) mV[VW] = color4u.mV[VW] * SCALE; } +LLColor4::LLColor4(const LLVector4& vector4) +{ + mV[VX] = vector4.mV[VX]; + mV[VY] = vector4.mV[VY]; + mV[VZ] = vector4.mV[VZ]; + mV[VW] = vector4.mV[VW]; +} + const LLColor4& LLColor4::setVec(const LLColor4U& color4u) { const F32 SCALE = 1.f/255.f; diff --git a/linden/indra/llmath/v4color.h b/linden/indra/llmath/v4color.h index 9ba2690..a2c0fb6 100644 --- a/linden/indra/llmath/v4color.h +++ b/linden/indra/llmath/v4color.h @@ -39,6 +39,7 @@ class LLColor3; class LLColor4U; +class LLVector4; // LLColor4 = |x y z w| @@ -58,6 +59,7 @@ class LLColor4 LLColor4(const LLColor3 &vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a) LLColor4(const LLSD& sd); explicit LLColor4(const LLColor4U& color4u); // "explicit" to avoid automatic conversion + explicit LLColor4(const LLVector4& vector4); // "explicit" to avoid automatic conversion LLSD getValue() const { @@ -107,7 +109,7 @@ class LLColor4 friend std::ostream& operator<<(std::ostream& s, const LLColor4 &a); // Print a friend LLColor4 operator+(const LLColor4 &a, const LLColor4 &b); // Return vector a + b friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b); // Return vector a minus b - friend LLColor4 operator*(const LLColor4 &a, const LLColor4 &b); // Return a * b + friend LLColor4 operator*(const LLColor4 &a, const LLColor4 &b); // Return component wise a * b friend LLColor4 operator*(const LLColor4 &a, F32 k); // Return rgb times scaler k (no alpha change) friend LLColor4 operator*(F32 k, const LLColor4 &a); // Return rgb times scaler k (no alpha change) friend LLColor4 operator%(const LLColor4 &a, F32 k); // Return alpha times scaler k (no rgb change) diff --git a/linden/indra/llmath/v4math.h b/linden/indra/llmath/v4math.h index f9d0c43..60e30e3 100644 --- a/linden/indra/llmath/v4math.h +++ b/linden/indra/llmath/v4math.h @@ -312,7 +312,8 @@ inline bool operator!=(const LLVector4 &a, const LLVector4 &b) { return ( (a.mV[VX] != b.mV[VX]) ||(a.mV[VY] != b.mV[VY]) - ||(a.mV[VZ] != b.mV[VZ])); + ||(a.mV[VZ] != b.mV[VZ]) + ||(a.mV[VW] != b.mV[VW]) ); } inline const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b) diff --git a/linden/indra/llmedia/files.lst b/linden/indra/llmedia/files.lst index bda6459..3ce18e5 100644 --- a/linden/indra/llmedia/files.lst +++ b/linden/indra/llmedia/files.lst @@ -1,7 +1,11 @@ -llmedia/llmediabase.cpp -llmedia/llmediaengine.cpp +llmedia/llmediaimplcommon.cpp +llmedia/llmediaimplexample1.cpp +llmedia/llmediaimplexample2.cpp +llmedia/llmediaimplfactory.cpp llmedia/llmediaimplgstreamer.cpp llmedia/llmediaimplgstreamer_syms.cpp llmedia/llmediaimplgstreamervidplug.cpp +llmedia/llmediaimplllmozlib.cpp llmedia/llmediaimplquicktime.cpp -llmedia/llmediamoviebase.cpp +llmedia/llmediamanager.cpp + diff --git a/linden/indra/llmedia/llmedia.vcproj b/linden/indra/llmedia/llmedia.vcproj index da87e26..38c53f0 100644 --- a/linden/indra/llmedia/llmedia.vcproj +++ b/linden/indra/llmedia/llmedia.vcproj @@ -20,7 +20,7 @@ + AdditionalLibraryDirectories=""..\..\libraries\i686-win32\lib_debug""/> + RelativePath=".\llmediaimplfactory.cpp"> + RelativePath=".\llmediamanager.cpp"> + + + RelativePath=".\llmediabase.h"> + RelativePath=".\llmediaemitter.h"> + RelativePath=".\llmediaimplfactory.h"> + + + + + + + Name="impls" + Filter=""> + RelativePath=".\llmediaimplcommon.cpp"> + RelativePath=".\llmediaimplcommon.h"> + RelativePath=".\llmediaimplexample1.cpp"> + RelativePath=".\llmediaimplexample1.h"> + RelativePath=".\llmediaimplexample2.cpp"> + + + RelativePath=".\llmediaimplllmozlib.cpp"> + + + + + + diff --git a/linden/indra/llmedia/llmedia_vc8.vcproj b/linden/indra/llmedia/llmedia_vc8.vcproj index e343f1e..4681a6c 100644 --- a/linden/indra/llmedia/llmedia_vc8.vcproj +++ b/linden/indra/llmedia/llmedia_vc8.vcproj @@ -41,8 +41,8 @@ + + + + @@ -269,19 +277,27 @@ UniqueIdentifier="{D188664C-B9B7-4982-8C4B-8D9A44B4D9EF}" > + + + + + + + + diff --git a/linden/indra/llmedia/llmedia_vc9.vcproj b/linden/indra/llmedia/llmedia_vc9.vcproj index 440f714..d032711 100644 --- a/linden/indra/llmedia/llmedia_vc9.vcproj +++ b/linden/indra/llmedia/llmedia_vc9.vcproj @@ -1,300 +1,326 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llmedia/llmediabase.cpp b/linden/indra/llmedia/llmediabase.cpp deleted file mode 100644 index 40acc5c..0000000 --- a/linden/indra/llmedia/llmediabase.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/** - * @file llmediabase.cpp - * @brief LLMedia support - base class - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llmediabase.h" -#include "llmediaimplquicktime.h" -#include "llmediaimplgstreamer.h" - -LLMediaBase::LLMediaBase() : - mBufferChangeCount ( 1 ), - mLastBufferChangeCount ( 0 ), - mMediaWidth ( 0 ), - mMediaHeight ( 0 ), - mMediaDepthBytes ( 0 ), - mMediaRowbytes( 0 ), - mTextureWidth ( 0 ), - mTextureHeight ( 0 ), - mTextureDepth ( 0 ), - mTextureFormatInternal ( 0 ), - mTextureFormatPrimary ( 0 ), - mTextureFormatType ( 0 ), - mTextureFormatSwapBytes ( 0 ) -{ - -} - -/////////////////////////////////////////////////////////////////////////////// -// factory method based on explicit media type -LLMediaBase* LLMediaBase::make( const MediaType mediaTypeIn, S32 width_pixels, S32 height_pixels ) -{ -#if LL_QUICKTIME_ENABLED - if ( mediaTypeIn == QuickTime ) - { - return new LLMediaImplQuickTime (); - } - else -#endif -#if LL_GSTREAMER_ENABLED - if ( mediaTypeIn == QuickTime ) - { - return new LLMediaImplGStreamer (); - } - else -#endif - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaBase:: -init () -{ - // build event and emit it - LLMediaEvent event ( 0, "" ); - mMediaEventEmitter.update ( &LLMediaObserver::onInit, event ); - - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaBase:: -load ( const LLString& urlIn ) -{ - // build event and emit it - LLMediaEvent event ( 0, urlIn ); - mMediaEventEmitter.update ( &LLMediaObserver::onLoad, event ); - - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaBase:: -unload () -{ - LLMediaEvent event ( 0, "" ); - mMediaEventEmitter.update ( &LLMediaObserver::onUnload, event ); - - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -S32 LLMediaBase::getTextureWidth() const -{ - return mTextureWidth; -} - -/////////////////////////////////////////////////////////////////////////////// -// -S32 LLMediaBase::getTextureHeight() const -{ - return mTextureHeight; -} - -/////////////////////////////////////////////////////////////////////////////// -// -S32 LLMediaBase::getTextureDepth() const -{ - return mTextureDepth; -} - -/////////////////////////////////////////////////////////////////////////////// -// -S32 LLMediaBase::getTextureFormatInternal() const -{ - return mTextureFormatInternal; -} - -/////////////////////////////////////////////////////////////////////////////// -// -S32 LLMediaBase::getTextureFormatPrimary() const -{ - return mTextureFormatPrimary; -} - -/////////////////////////////////////////////////////////////////////////////// -// -S32 LLMediaBase::getTextureFormatType() const -{ - return mTextureFormatType; -} - -/////////////////////////////////////////////////////////////////////////////// -// -S32 LLMediaBase::getTextureFormatSwapBytes() const -{ - return mTextureFormatSwapBytes; -} - -/////////////////////////////////////////////////////////////////////////////// -// -S32 LLMediaBase::getMediaWidth() const -{ - return mMediaWidth; -} - -/////////////////////////////////////////////////////////////////////////////// -// -S32 LLMediaBase::getMediaHeight() const -{ - return mMediaHeight; -} - -/////////////////////////////////////////////////////////////////////////////// -// -S32 LLMediaBase::getMediaDepthBytes() const -{ - return mMediaDepthBytes; -} - -/////////////////////////////////////////////////////////////////////////////// -// -S32 LLMediaBase::getMediaBufferSize() const -{ - if(mMediaRowbytes != 0) - { - return mMediaHeight * mMediaRowbytes; - } - - return mMediaWidth * mMediaHeight * mMediaDepthBytes; -}; - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaBase::addMediaObserver( LLMediaObserver* observerIn ) -{ - return mMediaEventEmitter.addObserver( observerIn ); -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaBase::remMediaObserver( LLMediaObserver* observerIn ) -{ - return mMediaEventEmitter.remObserver( observerIn ); -} diff --git a/linden/indra/llmedia/llmediabase.h b/linden/indra/llmedia/llmediabase.h index ae9c8ee..49c6d69 100644 --- a/linden/indra/llmedia/llmediabase.h +++ b/linden/indra/llmedia/llmediabase.h @@ -1,6 +1,8 @@ -/** +/** * @file llmediabase.h - * @brief LLMedia support - base class + * @author Callum Prentice + * @date 2007-10-22 00:00:00 + * @brief Abstract class that defines LLMedia public interface * * $LicenseInfo:firstyear=2005&license=viewergpl$ * @@ -29,112 +31,237 @@ * $/LicenseInfo$ */ -// header guard -#ifndef llmediabase_h -#define llmediabase_h +#ifndef LLMEDIABASE_H +#define LLMEDIABASE_H -#include "llstring.h" -#include "llmediaemitter.h" -#include "llmediaobservers.h" -#include "llmediaemitterevents.h" +// Per-OS feature switches. +#if LL_DARWIN + #define LL_QUICKTIME_ENABLED 1 + #define LL_LLMOZLIB_ENABLED 1 +#elif LL_WINDOWS + #define LL_QUICKTIME_ENABLED 1 + #define LL_LLMOZLIB_ENABLED 1 +#elif LL_LINUX + #define LL_QUICKTIME_ENABLED 0 + #ifndef LL_LLMOZLIB_ENABLED + #define LL_LLMOZLIB_ENABLED 1 + #endif // def LL_LLMOZLIB_ENABLED +#elif LL_SOLARIS + #define LL_QUICKTIME_ENABLED 0 + #ifndef LL_LLMOZLIB_ENABLED + #define LL_LLMOZLIB_ENABLED 0 + #endif // def LL_LLMOZLIB_ENABLED +#endif + +#if LL_LLMOZLIB_ENABLED && !defined ( MOZILLA_INTERNAL_API ) + // Without this, nsTAString.h errors out with: + // "Cannot use internal string classes without MOZILLA_INTERNAL_API defined. Use the frozen header nsStringAPI.h instead." + // It might be worth our while to figure out if we can use the frozen apis at some point... + #define MOZILLA_INTERNAL_API 1 +#endif + +#include + +class LLMediaObserver; +class LLMediaImplMakerBase; class LLMediaBase { public: - LLMediaBase (); - - // do the right thing with dtor - virtual ~LLMediaBase () - { + LLMediaBase() {}; + virtual ~LLMediaBase() {}; + + //////////////////////////////////////////////////////////////////////////////// + // housekeeping + + // local initialization, called by the media manager when creating a source + virtual bool init() = 0; + + // undoes everything init() didm called by the media manager when destroying a source + virtual bool reset() = 0; + + // accessor for MIME type + virtual bool setMimeType( const std::string mime_type ) = 0; + virtual std::string getMimeType() const = 0; + + // accessor for intial URL. Note that this may have changed under the hood + // so pass back the original URL seeded to this impl + virtual std::string getMediaURL() const = 0; + + // ask impl for version string + virtual std::string getVersion() = 0; + + // set/clear URL to visit when a 404 page is reached + virtual bool set404RedirectUrl( std::string redirect_url ) = 0; + virtual bool clr404RedirectUrl() = 0; + + // sets the background color of the browser window + virtual bool setBackgroundColor( unsigned int red, unsigned int green, unsigned int blue ) const = 0; + + // sets the color of the caret in media impls that have one + virtual bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue ) const = 0; + + //////////////////////////////////////////////////////////////////////////////// + // media management + + // needs to be called regularly to make media stream update itself + virtual bool updateMedia() = 0; + + // allows you to request a change in media width, height - may fail if media doesn't support size change + virtual bool setRequestedMediaSize( int media_width, int media_height ) = 0; + + // gets media width (may change throughout lifetime of media stream) - event emitted when media size changed too + virtual int getMediaWidth() const = 0; + + // gets media height (may change throughout lifetime of media stream) - event emitted when media size changed too + virtual int getMediaHeight() const = 0; + + // allows you to try to explicitly change media depth - may fail if media doesn't support depth change + virtual bool setMediaDepth( int media_depth ) = 0; + + // gets media depth (may change throughout lifetime of media stream) - event emitted when media depth changed too + virtual int getMediaDepth() const = 0; + + // gets size of media buffer for current frame (might NOT be the same as media width * height * depth) + virtual int getMediaBufferSize() const = 0; + + // returns pointer to raw media pixels + virtual unsigned char* getMediaData() = 0; + + // returns the size of the data, which may be different that the size of the media + virtual int getMediaDataWidth() const = 0; + virtual int getMediaDataHeight() const = 0; + + //////////////////////////////////////////////////////////////////////////////// + // texture management + + // gets internal format to use for OpenGL texture + virtual int getTextureFormatInternal() const = 0; + + // gets primary format to use for OpenGL texture + virtual int getTextureFormatPrimary() const = 0; + + // gets format type to use for OpenGL texture + virtual int getTextureFormatType() const = 0; + + + + + //////////////////////////////////////////////////////////////////////////////// + // audio + + // set/get control volume from media stream if present + virtual bool setVolume( float volume ) = 0; + virtual float getVolume() const = 0; + + + //////////////////////////////////////////////////////////////////////////////// + // transport control etc. + enum ECommand { + COMMAND_NONE = 0, + COMMAND_STOP = 1, + COMMAND_START = 2, + COMMAND_PAUSE = 4, + COMMAND_BACK = 5, + COMMAND_FORWARD = 6 + }; + enum EStatus { + STATUS_UNKNOWN = 0, + STATUS_INITIALIZING = 1, + STATUS_NAVIGATING = 2, + STATUS_STARTED = 3, + STATUS_STOPPED = 4, + STATUS_PAUSED = 6, + STATUS_RESETTING = 7 }; + virtual bool addCommand( ECommand cmd ) = 0; + virtual bool clearCommand() = 0; + virtual bool updateCommand() = 0; + virtual EStatus getStatus() = 0; + virtual bool seek( double time ) = 0; + virtual bool setLooping( bool enable) = 0; + virtual bool isLooping() = 0; - /////////////////////////////////////////////////////////////////////////////// - // public interface: + //////////////////////////////////////////////////////////////////////////////// + // scaling - /////////////////////////////////////////////////////////////////////////////// - // different types of supported media - enum MediaType { Unknown, QuickTime }; + // autoscale means try to scale media to size of texture - may fail if media doesn't support size change + virtual bool setAutoScaled( bool auto_scaled ) = 0; + virtual bool isAutoScaled() const = 0; - /////////////////////////////////////////////////////////////////////////////// - // factory method based on explicit media type - static LLMediaBase* make ( const MediaType mediaTypeIn, S32 width_pixels, S32 height_pixels ); - - // Result codes for updateMedia - enum - { - updateMediaNoChanges, - updateMediaNeedsUpdate, - updateMediaNeedsSizeChange - } updateMediaResult; + //////////////////////////////////////////////////////////////////////////////// + // mouse and keyboard interaction + virtual bool mouseDown( int x_pos, int y_pos ) = 0; + virtual bool mouseUp( int x_pos, int y_pos ) = 0; + virtual bool mouseMove( int x_pos, int y_pos ) = 0; + virtual bool keyPress( int key_code ) = 0; + virtual bool scrollByLines( int lines ) = 0; + virtual bool focus( bool focus ) = 0; + virtual bool unicodeInput( unsigned long uni_char ) = 0; + virtual bool mouseLeftDoubleClick( int x_pos, int y_pos ) = 0; - // housekeeping - virtual BOOL setBuffer ( U8* bufferIn ) = 0; - virtual bool setBufferSize(S32 width_pixels, S32 height_pixels) { return false; } - virtual BOOL init (); - virtual BOOL load ( const LLString& urlIn ); - virtual BOOL unload (); - - // media data - virtual S32 updateMedia () = 0; - virtual U8* getMediaData () = 0; - virtual S32 getTextureWidth () const; - virtual S32 getTextureHeight () const; - virtual S32 getTextureDepth () const; - virtual S32 getTextureFormatInternal () const; - virtual S32 getTextureFormatPrimary () const; - virtual S32 getTextureFormatType () const; - virtual S32 getTextureFormatSwapBytes () const; - virtual S32 getMediaWidth () const; - virtual S32 getMediaHeight () const; - virtual S32 getMediaDepthBytes () const; - virtual S32 getMediaBufferSize () const; - - // allow consumers to observe media events - virtual BOOL addMediaObserver( LLMediaObserver* observerIn ); - virtual BOOL remMediaObserver( LLMediaObserver* observerIn ); - - // MBW -- XXX -- These don't belong here! - // LLMediaEngine should really only deal with LLMediaMovieBase subclasses - virtual BOOL stop () { return TRUE; } - virtual BOOL play () { return TRUE; } - virtual BOOL loop ( S32 howMany ) { return TRUE; } - virtual BOOL pause () { return TRUE; } - virtual BOOL seek ( F64 time ) { return TRUE; } - virtual BOOL setVolume ( F32 volumeIn ) { return TRUE; } - virtual BOOL isLoaded () const { return TRUE; } - virtual BOOL isPaused () const { return FALSE; } - virtual BOOL isPlaying () const { return TRUE; } - virtual BOOL isLooping () const { return FALSE; } - virtual void setAutoScaled ( BOOL autoScaledIn ) {} - - protected: - // event emitter - LLMediaEmitter mMediaEventEmitter; - U32 mBufferChangeCount; // Incremented when the buffer changes - U32 mLastBufferChangeCount; // Set to mBufferChangeCount when the buffer is reported as changed + //////////////////////////////////////////////////////////////////////////////// + // navigation + virtual bool navigateTo( const std::string url ) = 0; + virtual bool navigateForward() = 0; + virtual bool navigateBack() = 0; + virtual bool canNavigateForward() = 0; + virtual bool canNavigateBack() = 0; - S32 mMediaWidth; - S32 mMediaHeight; - S32 mMediaDepthBytes; - S32 mMediaRowbytes; - S32 mTextureWidth; - S32 mTextureHeight; - S32 mTextureDepth; - S32 mTextureFormatInternal; - S32 mTextureFormatPrimary; - S32 mTextureFormatType; - S32 mTextureFormatSwapBytes; + //////////////////////////////////////////////////////////////////////////////// + // caching/cookies + virtual bool enableCookies( bool enable ) = 0; + virtual bool clearCache() = 0; + virtual bool clearCookies() = 0; - public: - - // Has memory buffer been updated? (page content change, scroll, movie frame drawn, etc) - void bufferChanged() { mBufferChangeCount++; } - bool getBufferChanged() const { return mBufferChangeCount != mLastBufferChangeCount; } - void resetBufferChanged() { mLastBufferChangeCount = mBufferChangeCount; } + //////////////////////////////////////////////////////////////////////////////// + // proxy + virtual bool enableProxy(bool enable, std::string proxy_host_name, int proxy_port) = 0; + + //////////////////////////////////////////////////////////////////////////////// + // observer interface + virtual bool addObserver( LLMediaObserver* subject ) = 0; + virtual bool remObserver( LLMediaObserver* subject ) = 0; + + //////////////////////////////////////////////////////////////////////////////// + // factory interface + virtual void setImplMaker(LLMediaImplMakerBase* impl_maker) = 0; + //////////////////////////////////////////////////////////////////////////////// + // type registry interface + virtual bool supportsMediaType(std::string scheme, std::string type) = 0; }; +////////////////////////////////////////////////////////////// +// media key codes - (mirroring mozilla's values) +const unsigned long LL_MEDIA_KEY_BACKSPACE = 0x08; +const unsigned long LL_MEDIA_KEY_TAB = 0x09; +const unsigned long LL_MEDIA_KEY_RETURN = 0x0D; +const unsigned long LL_MEDIA_KEY_PAD_RETURN = 0x0E; +const unsigned long LL_MEDIA_KEY_ESCAPE = 0x1B; +const unsigned long LL_MEDIA_KEY_PAGE_UP = 0x21; +const unsigned long LL_MEDIA_KEY_PAGE_DOWN = 0x22; +const unsigned long LL_MEDIA_KEY_END = 0x23; +const unsigned long LL_MEDIA_KEY_HOME = 0x24; +const unsigned long LL_MEDIA_KEY_LEFT = 0x25; +const unsigned long LL_MEDIA_KEY_UP = 0x26; +const unsigned long LL_MEDIA_KEY_RIGHT = 0x27; +const unsigned long LL_MEDIA_KEY_DOWN = 0x28; +const unsigned long LL_MEDIA_KEY_INSERT = 0x2D; +const unsigned long LL_MEDIA_KEY_DELETE = 0x2E; + +////////////////////////////////////////////////////////////// +// media frame buffer types - (mirroring GL values) +const int LL_MEDIA_UNSIGNED_BYTE = 0x1401; +const int LL_MEDIA_RGB = 0x1907; +const int LL_MEDIA_RGBA = 0x1908; +const int LL_MEDIA_RGB8 = 0x8051; +const int LL_MEDIA_UNSIGNED_INT_8_8_8_8 = 0x8035; +const int LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV = 0x8367; +const int LL_MEDIA_BGR = 0x80E0; +const int LL_MEDIA_BGRA = 0x80E1; + -#endif // llmediabase_h +#endif // LLMEDIABASE_H diff --git a/linden/indra/llmedia/llmediaemitter.h b/linden/indra/llmedia/llmediaemitter.h index 658486d..e06a5ff 100644 --- a/linden/indra/llmedia/llmediaemitter.h +++ b/linden/indra/llmedia/llmediaemitter.h @@ -1,6 +1,8 @@ -/** +/** * @file llmediaemitter.h - * @brief LLMedia support - templatized emitter class. + * @author Callum Prentice + * @date 2007-10-22 00:00:00 + * @brief Manages and emits events to observers * * $LicenseInfo:firstyear=2005&license=viewergpl$ * @@ -29,83 +31,73 @@ * $/LicenseInfo$ */ -// header guard -#ifndef llmediaemitter_h -#define llmediaemitter_h +#ifndef LLMEDIAEMITTER_H +#define LLMEDIAEMITTER_H -// standard headers +#include #include #include -#include -#include - -#include "stdtypes.h" /////////////////////////////////////////////////////////////////////////////// -// templatized emitter class -template < class T > +// +template< class T > class LLMediaEmitter { public: + LLMediaEmitter() { }; + ~LLMediaEmitter() { }; + typedef typename T::EventType EventType; typedef std::list< T* > ObserverContainer; - typedef void ( T::*observerMethod )( const EventType& ); - - protected: - ObserverContainer observers; - - public: - LLMediaEmitter() - { - }; - - ~LLMediaEmitter() - { - }; + typedef void( T::*observerMethod )( const EventType& ); /////////////////////////////////////////////////////////////////////////////// // - BOOL addObserver ( T* observerIn ) + bool addObserver( T* observer_in ) { - if ( ! observerIn ) - return FALSE; + if ( ! observer_in ) + return false; - // check if observer already exists - if ( std::find ( observers.begin (), observers.end (), observerIn ) != observers.end () ) - return FALSE; + if ( std::find( observers.begin(), observers.end(), observer_in) != observers.end() ) + return false; - // save it - observers.push_back ( observerIn ); + observers.push_back( observer_in ); return true; }; /////////////////////////////////////////////////////////////////////////////// // - BOOL remObserver ( T* observerIn ) + bool remObserver( T* observer_in ) { - if ( ! observerIn ) - return FALSE; + if ( ! observer_in ) + return false; + + observers.remove( observer_in ); + observers.remove( observer_in ); + observers.remove( observer_in ); - observers.remove ( observerIn ); - return TRUE; + + return true; }; /////////////////////////////////////////////////////////////////////////////// // - void update ( observerMethod method, const EventType& msgIn ) + void update( observerMethod method, const EventType& msgIn ) { - typename std::list< T* >::iterator iter = observers.begin (); + typename std::list< T* >::iterator iter = observers.begin(); - while ( iter != observers.end () ) + while( iter != observers.end() ) { - ( ( *iter )->*method ) ( msgIn ); + ( ( *iter )->*method )( msgIn ); ++iter; }; }; - }; + protected: + ObserverContainer observers; +}; -#endif // llmediaemitter_h +#endif // LLMEDIAEMITTER_H diff --git a/linden/indra/llmedia/llmediaemitterevents.h b/linden/indra/llmedia/llmediaemitterevents.h deleted file mode 100644 index 8a4111b..0000000 --- a/linden/indra/llmedia/llmediaemitterevents.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @file llmediaemitterevents.h - * @brief LLMedia support - events emitted by emitter to observer. - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -// header guard -#ifndef llmediaemitterevents_h -#define llmediaemitterevents_h - -#include "stdtypes.h" - - -class LLMediaEvent -{ - public: - LLMediaEvent ( S32 actionIn, const LLString& urlIn, void* data = NULL ): - action ( actionIn ), - url ( urlIn ), - mData(data) - { } - - virtual ~LLMediaEvent () { } - - S32 getAction () const { return action; } - LLString getUrl () const { return url; } - void* getData() const { return mData; } - - private: - S32 action; - std::string url; - void* mData; -}; - - -#endif // llmediaemitterevents_h diff --git a/linden/indra/llmedia/llmediaengine.cpp b/linden/indra/llmedia/llmediaengine.cpp deleted file mode 100644 index bd8acd1..0000000 --- a/linden/indra/llmedia/llmediaengine.cpp +++ /dev/null @@ -1,635 +0,0 @@ -/** - * @file llmediaengine.cpp - * @brief Top level media engine - wraps more specific functionality - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include "llmediaengine.h" -#include "llmediaimplquicktime.h" - -#include "indra_constants.h" -#include "llstring.h" - -// singleton pattern - initialization -LLMediaEngine* LLMediaEngine::sInstance = 0; - -////////////////////////////////////////////////////////////////////////////// - -//static -void LLMediaEngine::initClass() -{ - llassert(!sInstance); - sInstance = new LLMediaEngine(); -} - -//static -void LLMediaEngine::updateClass(F32 volume) -{ - llassert(sInstance); - sInstance->setVolume(volume); -} - -//static -void LLMediaEngine::cleanupClass() -{ - delete sInstance; - sInstance = NULL; -} - -////////////////////////////////////////////////////////////////////////////// -// default ctor -LLMediaEngine::LLMediaEngine() : - mAvailable( TRUE ), - mEnabled( TRUE ), - mAutoScaled( FALSE ), - mUrl( "" ), - mMediaRenderer( 0 ), - mImageUUID( LLUUID::null ), - mVolume( 0.0f ), - mProxyEnabled ( FALSE ), - mProxyAddress ( "" ), - mProxyPort ( 3128 ), - mProxySocks ( 5 ), - mProxyExlude ( "" ) -{ -} - -////////////////////////////////////////////////////////////////////////////// -// dtor -LLMediaEngine::~LLMediaEngine() -{ - unload(); - destroyImageRaw(); -} - -////////////////////////////////////////////////////////////////////////////// -// create/destroy raw image -void LLMediaEngine::createImageRaw() -{ - S32 width = getMediaRenderer()->getMediaWidth(); - S32 height = getMediaRenderer()->getMediaHeight(); - S32 depth = getMediaRenderer()->getMediaDepthBytes(); - if ((width > 0) && (height > 0) && (depth > 0)) - { - if (mImageRaw.isNull()) - { - mImageRaw = new LLImageRaw; - } - mImageRaw->resize(width, height, depth); - mImageRaw->clear(); - } - else - { - destroyImageRaw(); - } -} - -void LLMediaEngine::destroyImageRaw() -{ - mImageRaw = NULL; // deletes image -} - -////////////////////////////////////////////////////////////////////////////// -// retrieves the single instance of this class - based on singleton pattern -LLMediaEngine* LLMediaEngine::getInstance() -{ - return sInstance; -} - -////////////////////////////////////////////////////////////////////////////// -// -LLMediaBase* LLMediaEngine::getMediaRenderer() -{ - return mMediaRenderer; -} - - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::init() -{ - if( ! isAvailable() ) - return FALSE; - - return TRUE; -} - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::update() -{ - BOOL res = FALSE; - if( mMediaRenderer ) - { - S32 result = mMediaRenderer->updateMedia(); - switch(result) - { - case LLMediaBase::updateMediaNeedsSizeChange: - // Media renderer is requesting a size change. - handleSizeChangedRequest(); - res = TRUE; // Need to update size of texture - break; - - case LLMediaBase::updateMediaNeedsUpdate: - res = TRUE; - break; - - case LLMediaBase::updateMediaNoChanges: - default: - res = FALSE; - break; - } - } - return res; -} - - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::load ( const LLString& urlIn, bool web_url, const LLString& path, S32 width_pixels, S32 height_pixels ) -{ - if( ! isAvailable() ) - return FALSE; - - if( isLoaded() ) - return TRUE; - - this->unload(); - - mMediaRenderer = LLMediaBase::make( LLMediaBase::QuickTime, width_pixels, height_pixels); - - if( ! mMediaRenderer ) - return FALSE; - - if( ! mMediaRenderer->init() ) - { - delete mMediaRenderer; - mMediaRenderer = 0; - return FALSE; - } - - // do this here since there is no media renderer when we get the update so we store and use here - if( mMediaRenderer ) - mMediaRenderer->setAutoScaled( mAutoScaled ); - - if( ! mMediaRenderer->load( urlIn ) ) - { - delete mMediaRenderer; - mMediaRenderer = 0; - return FALSE; - } - - return TRUE; -} - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::isLoaded() -{ - if( ! isAvailable() ) - return FALSE; - - if( mMediaRenderer ) - return mMediaRenderer->isLoaded(); - else - return FALSE; -} - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::unload() -{ - if( ! isAvailable() ) - return FALSE; - - if( mMediaRenderer ) - { - mMediaRenderer->stop(); - mMediaRenderer->unload(); - delete mMediaRenderer; - mMediaRenderer = 0; - // Don't do this here. load() calls unload(), and things get lost. -// mUrl.clear(); -// mImageUUID = LLUUID::null; - return TRUE; - }; - - return FALSE; -}; - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::play() -{ - if( ! isAvailable() ) - return FALSE; - - // base movie volume on slider in prefs (currently prefs also sets volume directly but other controls - // may eventually control volume and updat ethis variable - this->setVolume( mVolume ); - - if( mMediaRenderer ) - if( ! mMediaRenderer->play() ) - return FALSE; - - return TRUE; -} - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::loop() -{ - if( ! isAvailable() ) - return FALSE; - - // base movie volume on slider in prefs (currently prefs also sets volume directly but other controls - // may eventually control volume and updat ethis variable - this->setVolume( mVolume ); - - if( mMediaRenderer ) - if( ! mMediaRenderer->loop( 0 ) ) - return FALSE; - - return TRUE; -} - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::pause() -{ - if( ! isAvailable() ) - return FALSE; - - if( mMediaRenderer ) - if( ! mMediaRenderer->pause() ) - return FALSE; - - return TRUE; -} - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::stop() -{ - if( ! isAvailable() ) - return FALSE; - - if( mMediaRenderer ) - if( ! mMediaRenderer->stop() ) - return FALSE; - - return TRUE; -} - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::seek (F64 time) -{ - if( ! isAvailable() ) - return FALSE; - - if( mMediaRenderer ) - if( ! mMediaRenderer->seek (time) ) - return FALSE; - - return TRUE; -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLMediaEngine::setAvailable( BOOL availableIn ) -{ - mAvailable = availableIn; -} - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::isAvailable() -{ - return mAvailable; -} - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::setVolume( F32 volumeIn ) -{ - if( ! isAvailable() ) - return FALSE; - - mVolume = volumeIn; - - if( mMediaRenderer ) - { - if( ! mMediaRenderer->setVolume( volumeIn ) ) - { - return FALSE; - }; - }; - - return TRUE; -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLMediaEngine::setEnabled( BOOL enabledIn ) -{ - if( mAvailable ) - mEnabled = enabledIn; -} - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::isEnabled() -{ - if( mAvailable ) - return mEnabled; - else - return FALSE; -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLMediaEngine::setAutoScaled( BOOL autoScaledIn ) -{ - mAutoScaled = autoScaledIn; -} - -////////////////////////////////////////////////////////////////////////////// -// -BOOL LLMediaEngine::isAutoScaled() -{ - return mAutoScaled; -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLMediaEngine::setUrl( const LLString& urlIn ) -{ - mUrl = urlIn; -}; - -////////////////////////////////////////////////////////////////////////////// -// -const LLString& LLMediaEngine::getUrl () -{ - return mUrl; -}; - -////////////////////////////////////////////////////////////////////////////// -// -void LLMediaEngine::setImageUUID( LLUUID imageUUIDIn ) -{ - mImageUUID = imageUUIDIn; -}; - -////////////////////////////////////////////////////////////////////////////// -// -LLUUID LLMediaEngine::getImageUUID() -{ - return mImageUUID; -}; - -////////////////////////////////////////////////////////////////////////////// -// -void LLMediaEngine::handleSizeChangedRequest() -{ - if( ! isAvailable() ) - return; - - // create / resize Raw image - LLMediaEngine::getInstance()->createImageRaw(); - - // tell media library to use this buffer instead of it's own - if (mImageRaw.notNull()) - { - LLMediaEngine::getInstance()->getMediaRenderer()->setBuffer( mImageRaw->getData() ); - } - -} - -////////////////////////////////////////////////////////////////////////////////////////// -// static -void LLMediaEngine::convertImageAndLoadUrl( bool enableLooping, bool web_url, const std::string& path) -{ - LLMediaEngine* engine = LLMediaEngine::getInstance(); - LLString url = engine->getUrl(); - S32 width_pixels = 512; - S32 height_pixels = 256; - if (web_url) - { - width_pixels = 512; - height_pixels = 512; - } - - bool success = false; - if (engine->load( url, web_url, path, width_pixels, height_pixels ) ) - { - // create / resize Raw image - engine->createImageRaw(); - - // tell media library to use this buffer instead of it's own - if (engine->getImageRaw()) - { - engine->getMediaRenderer()->setBuffer( engine->mImageRaw->getData() ); - engine->getMediaRenderer()->setBufferSize(width_pixels, height_pixels); - - // start it playing or looping - if( enableLooping ) - { - engine->loop(); - } - else - { - engine->play(); - } - success = true; - } - } - - if (!success) - { - llinfos << "MEDIA> unable to load " << LLMediaEngine::getInstance()->getUrl() << llendl; - //LLMediaEngine::getInstance()->setAvailable( FALSE ); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// -// static -void LLMediaEngine::process_parcel_media( LLMessageSystem *msg, void ** ) -{ - // extract the agent id - // LLUUID agent_id; - // msg->getUUID( agent_id ); - - U32 flags; - U32 command; - F32 time; - msg->getU32( "CommandBlock", "Flags", flags ); - msg->getU32( "CommandBlock", "Command", command); - msg->getF32( "CommandBlock", "Time", time ); - - if (flags &( (1<>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl; - - LLMediaEngine::getInstance()->stop(); - } - else - // pause - if( command == PARCEL_MEDIA_COMMAND_PAUSE ) - { - //llinfos << ">>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl; - - LLMediaEngine::getInstance()->pause(); - } - else - // play - if( command == PARCEL_MEDIA_COMMAND_PLAY ) - { - //llinfos << ">>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl; - - convertImageAndLoadUrl( false, false, std::string() ); - } - else - // loop - if( command == PARCEL_MEDIA_COMMAND_LOOP ) - { - //llinfos << ">>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl; - - // huh? what is play? - //convertImageAndLoadUrl( play ); - convertImageAndLoadUrl( true, false, std::string() ); - } - else - // unload - if( command == PARCEL_MEDIA_COMMAND_UNLOAD ) - { - //llinfos << ">>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl; - - if (LLMediaEngine::getInstance()->isLoaded()) - { - LLMediaEngine::getInstance()->unload(); - LLMediaEngine::getInstance()->destroyImageRaw(); - } - } - } - - if (flags & (1<seek(time); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// -// static -/* -// ParcelMediaUpdate -// Sends a parcel media update to a single user -// For global updates use the parcel manager. -{ - ParcelMediaUpdate Low NotTrusted Unencoded - { - DataBlock Single - { MediaURL Variable 1 } // string - { MediaID LLUUID } - { MediaAutoScale U8 } - } -} -*/ -void LLMediaEngine::process_parcel_media_update( LLMessageSystem *msg, void ** ) -{ - LLUUID media_uuid; - char media_url[255]; /* Flawfinder: ignore */ - U8 auto_align; - msg->getUUID( "DataBlock", "MediaID", media_uuid ); - msg->getString( "DataBlock", "MediaURL", 255, media_url ); - msg->getU8( "DataBlock", "MediaAutoScale", auto_align ); - - LLMediaEngine* media_engine = LLMediaEngine::getInstance(); - LLString url_string ( media_url ); - - auto_align = (auto_align) ? TRUE : FALSE; - - if( !( (media_engine->getUrl() == url_string) - && (media_engine->getImageUUID() == media_uuid) - && (media_engine->isAutoScaled() == auto_align ) ) ) - { - if (media_engine->isLoaded()) - { - media_engine->unload(); - media_engine->destroyImageRaw(); - } - - media_engine->setUrl(url_string); - media_engine->setImageUUID(media_uuid); - media_engine->setAutoScaled(auto_align); - } -} - -// sets proxy information for any of the media impls that may want to use it -void LLMediaEngine::setNetworkProxy ( BOOL enabledIn, const LLString& addressIn, - S32 portIn, S32 socksIn, const LLString& excludeIn ) -{ - mProxyEnabled = enabledIn; - mProxyAddress = addressIn; - mProxyPort = portIn; - mProxySocks = socksIn; - mProxyExlude = excludeIn; -} - -// gets proxy information for any of the media impls that may want to use it -void LLMediaEngine::getNetworkProxy ( BOOL& enabledOut, LLString& addressOut, - S32& portOut, S32& socksOut, LLString& excludeOut ) -{ - enabledOut = mProxyEnabled; - addressOut = mProxyAddress; - portOut = mProxyPort; - socksOut = mProxySocks; - excludeOut = mProxyExlude; -} - -// get QuickTime version (returned as a number which -// only makes sense viewed as hex -S32 LLMediaEngine::getQuickTimeVersion() -{ -#if LL_QUICKTIME_ENABLED - return LLMediaImplQuickTime::getVersion(); -#else - return -1; -#endif -} - diff --git a/linden/indra/llmedia/llmediaengine.h b/linden/indra/llmedia/llmediaengine.h deleted file mode 100644 index 4cae070..0000000 --- a/linden/indra/llmedia/llmediaengine.h +++ /dev/null @@ -1,150 +0,0 @@ -/** - * @file llmediaengine.h - * @brief Top level media engine - wraps more specific functionality. - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LLMEDIAENGINE_H -#define LLMEDIAENGINE_H - -#include "linden_common.h" -#include "lluuid.h" -#include "llimage.h" - -#include "llmediabase.h" -#include "llmediaobservers.h" - - -#include "message.h" - -// older: after a 7.3.1 update version is 120684544 (dec) and 7318000 (hex) -// older: current version on my Windows system after a 7.4 update version is 121667584 (dec) and 7408000 (hex) -// current version on my Windows system after a 7.4.1 update version is 121733120 (dec) and 7418000 (hex) - -#define LL_MIN_QUICKTIME_VERSION ( 0x7418000 ) // QT 7.4.1 - -////////////////////////////////////////////////////////////////////////////// -// media engine singleton -class LLMediaEngine -{ -public: - static void initClass(); - static void updateClass(F32 volume); - static void cleanupClass(); - -protected: - // don't let anyone else make one of these - LLMediaEngine (); - -public: - virtual ~LLMediaEngine (); - - // used to get access to single instance of the class (singleton pattern) - static LLMediaEngine* getInstance (); - - // public methods - BOOL init (); - BOOL update (); - - // Pass web_url true if it's a web page, false if it's a movie. - // path is to mozilla directory for mozilla - BOOL load( const LLString& urlIn, bool web_url, const LLString& path, S32 width_pixels, S32 height_pixels); - - BOOL isLoaded (); - BOOL unload (); - BOOL play (); - BOOL loop (); - BOOL pause (); - BOOL stop (); - BOOL seek (F64 time); - void setAvailable ( BOOL availableIn ); - BOOL isAvailable (); - void setEnabled ( BOOL enabledIn ); - BOOL isEnabled (); - void setAutoScaled ( BOOL autoScaledIn ); - BOOL isAutoScaled (); - BOOL setVolume ( F32 volumeIn ); - S32 getQuickTimeVersion(); - - void setUrl ( const LLString& urlIn ); - const LLString& getUrl (); - void setImageUUID ( LLUUID textureIdIn ); - LLUUID getImageUUID (); - - // MBW -- XXX -- This should return a LLMediaMovieBase, but the web and movie media classes still haven't been - // fully disentangled. - LLMediaBase* getMediaRenderer(); - LLImageRaw* getImageRaw() { return mImageRaw; } - void handleSizeChangedRequest(); - - ////////////////////////////////////////////////////////////////////////////////////////// - // - static void convertImageAndLoadUrl ( bool enableLooping, bool web_url, const std::string& path); - - ////////////////////////////////////////////////////////////////////////////////////////// - // - static void process_parcel_media ( LLMessageSystem *msg, void ** ); - static void process_parcel_media_update ( LLMessageSystem *msg, void ** ); - - // proxy configuration - void setNetworkProxy ( BOOL enabledIn, const LLString& addressIn, - S32 portIn, S32 socksIn, const LLString& excludeIn ); - - void getNetworkProxy ( BOOL& enabledOut, LLString& addressOut, - S32& portOut, S32& socksOut, LLString& excludeOuy ); - -private: - void createImageRaw(); - void destroyImageRaw(); - -private: - BOOL mAvailable; - BOOL mEnabled; - BOOL mAutoScaled; - LLString mUrl; - // MBW -- XXX -- This should be a LLMediaMovieBase, but the web and movie media classes still haven't been - // fully disentangled. - LLMediaBase* mMediaRenderer; - LLPointer mImageRaw; - - LLUUID mImageUUID; - F32 mVolume; - - // proxy information - BOOL mProxyEnabled; - LLString mProxyAddress; - S32 mProxyPort; - S32 mProxySocks; - LLString mProxyExlude; - -private: - static LLMediaEngine* sInstance; -}; - -#endif // LLMEDIAENGINE_H - diff --git a/linden/indra/llmedia/llmediaimplcommon.cpp b/linden/indra/llmedia/llmediaimplcommon.cpp new file mode 100644 index 0000000..a0705bb --- /dev/null +++ b/linden/indra/llmedia/llmediaimplcommon.cpp @@ -0,0 +1,540 @@ +/** + * @file llmediaimplcommon.cpp + * @brief Common impl functionality + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llmediaimplcommon.h" +#include "llmediaemitter.h" +#include "llmediaimplfactory.h" +#include "llmediaobserver.h" + +#ifdef WIN32 + // platform specific includes needed before OpenGL header + #include + #include +#elif defined(__APPLE__) + // framework-style include path when building on the Mac. + #include +#else // Assume this is linux + // Linux, MESA headers, but not necessarily assuming MESA runtime. + // quotes so we get libraries/.../GL/ version + #include "GL/gl.h" +#endif + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +LLMediaImplCommon::LLMediaImplCommon() : + mMimeType( std::string() ), + mInitialURL( std::string() ), + mAutoScaled( false ), + mMediaWidth( 0 ), + mMediaPrevWidth( 0 ), + mMediaHeight( 0 ), + mMediaPrevHeight( 0 ), + mMediaDepth( 0 ), + mMediaPrevDepth( 0 ), + mMediaRowSpan( 0 ), + mMediaRequestedWidth( 0 ), + mMediaRequestedHeight( 0 ), + mCommand( LLMediaBase::COMMAND_NONE ), + mStatus( LLMediaBase::STATUS_UNKNOWN ), + mVolume( 0 ), + mLooping( false ) +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +LLMediaImplCommon::~LLMediaImplCommon() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::init() +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::reset() +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::setMimeType( const std::string mime_type ) +{ + mMimeType = mime_type; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +std::string LLMediaImplCommon::getMimeType() const +{ + return mMimeType; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +std::string LLMediaImplCommon::getMediaURL() const +{ + return mInitialURL; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +std::string LLMediaImplCommon::getVersion() +{ + return std::string( "" ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::set404RedirectUrl( std::string redirect_url ) +{ + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::clr404RedirectUrl() +{ + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::setBackgroundColor( unsigned int red, unsigned int green, unsigned int blue ) const +{ + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::setCaretColor( unsigned int red, unsigned int green, unsigned int blue ) const +{ + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::updateMedia() +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +unsigned char* LLMediaImplCommon::getMediaData() +{ + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +int LLMediaImplCommon::getMediaDataWidth() const +{ + return getMediaWidth(); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +int LLMediaImplCommon::getMediaDataHeight() const +{ + return getMediaHeight(); +} + + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::setMediaSize( int media_width, int media_height ) +{ + // if nothing changed, don't do anything + if ( ( mMediaWidth == media_width ) && + ( mMediaHeight == media_height ) ) + return false; + + // save old values so we can tell elsewhere if media size has changed + mMediaPrevWidth = mMediaWidth; + mMediaPrevHeight = mMediaHeight; + + mMediaWidth = media_width; + mMediaHeight = media_height; + + // only fire an event if the width changed + LLMediaEvent event( this ); + mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +int LLMediaImplCommon::getMediaWidth() const +{ + return mMediaWidth; +} + + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +int LLMediaImplCommon::getMediaHeight() const +{ + return mMediaHeight; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::setRequestedMediaSize(int width, int height) +{ + mMediaRequestedWidth = width; + mMediaRequestedHeight = height; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::setMediaDepth( int media_depth ) +{ + // if nothing changed, don't do anything + if ( mMediaDepth == media_depth ) + return false; + + // save old values so we can tell elsewhere if media size has changed + mMediaPrevDepth = mMediaDepth; + mMediaDepth = media_depth; + + // update value of rowspan too since it's based on media width & depth + mMediaRowSpan = mMediaWidth * mMediaDepth; + + // only fire an event if the depth changed + //LLMediaEvent event( this ); + //mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +int LLMediaImplCommon::getMediaDepth() const +{ + return mMediaDepth; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +int LLMediaImplCommon::getMediaBufferSize() const +{ + return mMediaRowSpan * mMediaHeight; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +int LLMediaImplCommon::getTextureFormatInternal() const +{ + return LL_MEDIA_RGB; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +int LLMediaImplCommon::getTextureFormatPrimary() const +{ + return LL_MEDIA_RGB; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +int LLMediaImplCommon::getTextureFormatType() const +{ + return LL_MEDIA_UNSIGNED_BYTE; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::setVolume( float volume ) +{ + mVolume = volume; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +float LLMediaImplCommon::getVolume() const +{ + return mVolume; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::addCommand( LLMediaBase::ECommand cmd ) +{ + // eventually will be a std::queue so you can add multiple commands + mCommand = cmd; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::clearCommand() +{ + // eventually will be a std::queue so you can add multiple commands + mCommand = LLMediaBase::COMMAND_NONE; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::updateCommand() +{ + if ( nextCommand() == LLMediaBase::COMMAND_START ) + { + setStatus( LLMediaBase::STATUS_STARTED ); + clearCommand(); + }; + + if ( nextCommand() == LLMediaBase::COMMAND_STOP ) + { + setStatus( LLMediaBase::STATUS_STOPPED ); + clearCommand(); + }; + + if ( nextCommand() == LLMediaBase::COMMAND_PAUSE ) + { + setStatus( LLMediaBase::STATUS_PAUSED ); + clearCommand(); + }; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// non-virtual (only impls use this) +LLMediaBase::ECommand LLMediaImplCommon::nextCommand() +{ + return mCommand; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +LLMediaBase::EStatus LLMediaImplCommon::getStatus() +{ + return mStatus; +} + +//////////////////////////////////////////////////////////////////////////////// +// non-virtual (only impls set this) +bool LLMediaImplCommon::setStatus( LLMediaBase::EStatus status ) +{ + mStatus = status; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::seek( double time ) +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::navigateTo( const std::string url ) +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::setAutoScaled( bool auto_scaled ) +{ + mAutoScaled = auto_scaled; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::isAutoScaled() const +{ + return mAutoScaled; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::mouseDown( int x_pos, int y_pos ) +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::mouseUp( int x_pos, int y_pos ) +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::mouseMove( int x_pos, int y_pos ) +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::keyPress( int key_code ) +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::scrollByLines( int lines ) +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::focus( bool focus ) +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::unicodeInput( unsigned long uni_char ) +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::mouseLeftDoubleClick( int x_pos, int y_pos ) +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::navigateForward() +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::navigateBack() +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::canNavigateForward() +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::canNavigateBack() +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::enableCookies( bool enable ) +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::clearCache() +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::clearCookies() +{ + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual (derives from LLMediaBase) +bool LLMediaImplCommon::enableProxy(bool enable, std::string proxy_host_name, int proxy_port) +{ + return false; +} +//////////////////////////////////////////////////////////////////////////////// +// +bool LLMediaImplCommon::addObserver( LLMediaObserver* subject ) +{ + return mEventEmitter.addObserver( subject ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool LLMediaImplCommon::remObserver( LLMediaObserver* subject ) +{ + return mEventEmitter.remObserver( subject ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLMediaImplCommon::setImplMaker(LLMediaImplMakerBase* impl_maker) +{ + mImplMaker = impl_maker; +} +//////////////////////////////////////////////////////////////////////////////// +// +bool LLMediaImplCommon::supportsMediaType(std::string scheme, std::string type) +{ + int idx1 = type.find("/"); + int len = (idx1 == std::string::npos) ? 0 : idx1; + std::string category = type.substr(0,len); + + return mImplMaker->supportsScheme(scheme) || + mImplMaker->supportsMimeType(type) || + mImplMaker->supportsMimeTypeCategory(category); +} diff --git a/linden/indra/llmedia/llmediaimplcommon.h b/linden/indra/llmedia/llmediaimplcommon.h new file mode 100644 index 0000000..aa6c4d5 --- /dev/null +++ b/linden/indra/llmedia/llmediaimplcommon.h @@ -0,0 +1,161 @@ +/** + * @file llmediaimplcommon.h + * @brief Common impl functionality + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLMEDIAIMPLCOMMON_H +#define LLMEDIAIMPLCOMMON_H + +#include "llmediabase.h" +#include "llmediaemitter.h" +#include "llmediaobserver.h" + +#include + +class LLMediaImplMakerBase; + +class LLMediaImplCommon : + public LLMediaBase +{ + public: + LLMediaImplCommon(); + virtual ~LLMediaImplCommon(); + + //////////////////////////////////////////////////////////////////////////////// + // begin: default implementation of the abstract interface + // see llmediabase.h for documentation + + // housekeeping + virtual bool init(); + virtual bool reset(); + virtual bool setMimeType( const std::string url ); + virtual std::string getMimeType() const; + virtual std::string getMediaURL() const; + virtual std::string getVersion(); + virtual bool set404RedirectUrl( std::string redirect_url ); + virtual bool clr404RedirectUrl(); + virtual bool setBackgroundColor( unsigned int red, unsigned int green, unsigned int blue ) const; + virtual bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue ) const; + + // media management + virtual bool updateMedia(); + virtual bool setRequestedMediaSize( int width, int height ); + virtual int getMediaWidth() const; + virtual int getMediaHeight() const; + virtual int getMediaDepth() const; + virtual int getMediaBufferSize() const; + virtual unsigned char* getMediaData(); + virtual int getMediaDataWidth() const; + virtual int getMediaDataHeight() const; + + // texture management + virtual int getTextureFormatInternal() const; + virtual int getTextureFormatPrimary() const; + virtual int getTextureFormatType() const; + + // audio + virtual bool setVolume( float volume ); + virtual float getVolume() const; + + // transport control + virtual bool addCommand( ECommand cmd ); + virtual bool clearCommand(); + virtual bool updateCommand(); + LLMediaBase::ECommand nextCommand(); + virtual LLMediaBase::EStatus getStatus(); + bool setStatus( LLMediaBase::EStatus status ); + + virtual bool seek( double time ); + virtual bool setLooping(bool enable) { mLooping = enable; return true; } + virtual bool isLooping() { return mLooping; } + virtual bool navigateTo( const std::string url ); + + // scaling + virtual bool setAutoScaled( bool auto_scaled ); + virtual bool isAutoScaled() const; + + // mouse and keyboard interaction + virtual bool mouseDown( int x_pos, int y_pos ); + virtual bool mouseUp( int x_pos, int y_pos ); + virtual bool mouseMove( int x_pos, int y_pos ); + virtual bool keyPress( int key_code ); + virtual bool scrollByLines( int lines ); + virtual bool focus( bool focus ); + virtual bool unicodeInput( unsigned long uni_char ); + virtual bool mouseLeftDoubleClick( int x_pos, int y_pos ); + + // navigation + virtual bool navigateForward(); + virtual bool navigateBack(); + virtual bool canNavigateForward(); + virtual bool canNavigateBack(); + + // caching/cookies + virtual bool enableCookies( bool enable ); + virtual bool clearCache(); + virtual bool clearCookies(); + + virtual bool enableProxy(bool enable, std::string proxy_host_name, int proxy_port); + + // observer interface + bool addObserver( LLMediaObserver* subject ); + bool remObserver( LLMediaObserver* subject ); + + // type registry interface + void setImplMaker(LLMediaImplMakerBase* impl_maker); + bool supportsMediaType(std::string scheme, std::string type); + + protected: + virtual bool setMediaSize( int width, int height ); + virtual bool setMediaDepth( int media_depth ); + + LLMediaEmitter< LLMediaObserver > mEventEmitter; + + // Back pointer to the construction object, which is used to discover types handled + // by the Impl, and meta data associated with the Impl. + LLMediaImplMakerBase* mImplMaker; + std::string mMimeType; + std::string mInitialURL; + bool mAutoScaled; + int mMediaWidth; + int mMediaPrevWidth; + int mMediaHeight; + int mMediaPrevHeight; + int mMediaDepth; + int mMediaPrevDepth; + int mMediaRowSpan; + int mMediaRequestedWidth; + int mMediaRequestedHeight; + float mVolume; + LLMediaBase::ECommand mCommand; + LLMediaBase::EStatus mStatus; + bool mLooping; +}; + +#endif // LLMEDIAIMPLCOMMON_H diff --git a/linden/indra/llmedia/llmediaimplexample1.cpp b/linden/indra/llmedia/llmediaimplexample1.cpp new file mode 100644 index 0000000..03e8291 --- /dev/null +++ b/linden/indra/llmedia/llmediaimplexample1.cpp @@ -0,0 +1,228 @@ +/** + * @file llmediaimplexample1.cpp + * @brief Example 1 of a media impl concrete class + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llmediaimplexample1.h" +#include "llmediaimplregister.h" + +// register this impl with media manager factory +static LLMediaImplRegister sLLMediaImplExample1Reg( "LLMediaImplExample1", new LLMediaImplExample1Maker() ); + +#include + +#include + +/////////////////////////////////////////////////////////////////////////////// +// +LLMediaImplExample1Maker::LLMediaImplExample1Maker() +{ + // Register to handle the scheme + mSchema.push_back( "example1" ); +} + +/////////////////////////////////////////////////////////////////////////////// +// +LLMediaImplExample1::LLMediaImplExample1() : + mMediaPixels( 0 ) +{ + setRequestedMediaSize( 400, 200 ); + setMediaDepth( 3 ); + + srand( (unsigned int)(time( NULL )) ); +} + +//////////////////////////////////////////////////////////////////////////////// +// (static) super-initialization - called once at application startup +bool LLMediaImplExample1::startup( LLMediaManagerData* init_data ) +{ + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// (static) super-uninitialization - called once at application closedown +bool LLMediaImplExample1::closedown() +{ + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplExample1::init() +{ + int buffer_size = getMediaBufferSize(); + + mMediaPixels = new unsigned char[ buffer_size ]; + + memset( mMediaPixels, 0xAA, buffer_size ); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplExample1::navigateTo( const std::string url ) +{ + std::cout << "LLMediaImplExample1::navigateTo" << std::endl; + + setStatus( LLMediaBase::STATUS_NAVIGATING ); + + // force a size change event for new URL + LLMediaEvent event( this ); + mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +std::string LLMediaImplExample1::getVersion() +{ + std::string version_string = "[" + sLLMediaImplExample1Reg.getImplName() + "] - " + "1.0.0.0"; + + return version_string; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplExample1::updateMedia() +{ + if ( mMediaPixels && getStatus() == LLMediaBase::STATUS_STARTED ) + { + // first time - make sure it's a few seconds back so first update happens immediately + static time_t t = time( 0 ) - 4; + + // selected time period elapsed (1 second) + if ( time( 0 ) - t > 1 ) + { + // display checkerboard + const int num_squares = rand() % 20 + 4; + int sqr1_r = rand() % 0x80; + int sqr1_g = rand() % 0x80; + int sqr1_b = rand() % 0x80; + int sqr2_r = rand() % 0x80; + int sqr2_g = rand() % 0x80; + int sqr2_b = rand() % 0x80; + + for ( int y1 = 0; y1 < num_squares; ++y1 ) + { + for ( int x1 = 0; x1 < num_squares; ++x1 ) + { + int px_start = getMediaWidth() * x1 / num_squares; + int px_end = ( getMediaWidth() * ( x1 + 1 ) ) / num_squares; + int py_start = getMediaHeight() * y1 / num_squares; + int py_end = ( getMediaHeight() * ( y1 + 1 ) ) / num_squares; + + for( int y2 = py_start; y2 < py_end; ++y2 ) + { + for( int x2 = px_start; x2 < px_end; ++x2 ) + { + int rowspan = getMediaWidth() * getMediaDepth(); + + if ( ( y1 % 2 ) ^ ( x1 % 2 ) ) + { + mMediaPixels[ y2 * rowspan + x2 * getMediaDepth() + 0 ] = sqr1_r; + mMediaPixels[ y2 * rowspan + x2 * getMediaDepth() + 1 ] = sqr1_g; + mMediaPixels[ y2 * rowspan + x2 * getMediaDepth() + 2 ] = sqr1_b; + } + else + { + mMediaPixels[ y2 * rowspan + x2 * getMediaDepth() + 0 ] = sqr2_r; + mMediaPixels[ y2 * rowspan + x2 * getMediaDepth() + 1 ] = sqr2_g; + mMediaPixels[ y2 * rowspan + x2 * getMediaDepth() + 2 ] = sqr2_b; + }; + }; + }; + }; + }; + + // emit an event to say that something in the media stream changed + LLMediaEvent event( this ); + mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); + + // reset time + t = time( 0 ); + + return true; + }; + }; + + // update the command (e.g. transport controls) state + updateCommand(); + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +unsigned char* LLMediaImplExample1::getMediaData() +{ + return mMediaPixels; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplExample1::reset() +{ + if ( mMediaPixels ) + { + delete [] mMediaPixels; + }; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplExample1::mouseMove( int x_pos, int y_pos ) +{ + if ( mMediaPixels && getStatus() == LLMediaBase::STATUS_STARTED ) + { + int base_pos = x_pos * getMediaDepth() + y_pos * getMediaDepth() * getMediaWidth(); + // example: write a bright pixel to the display when we move the mouse + mMediaPixels[ base_pos + 0 ] = rand() % 0x80 + 0x80; + mMediaPixels[ base_pos + 1 ] = rand() % 0x80 + 0x80; + mMediaPixels[ base_pos + 2 ] = rand() % 0x80 + 0x80; + + // emit an event to say that something in the media stream changed + LLMediaEvent event( this ); + mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); + }; + + return true; +} + + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplExample1::setRequestedMediaSize( int width, int height ) +{ + // we accept any size: + return setMediaSize(width, height); +} diff --git a/linden/indra/llmedia/llmediaimplexample1.h b/linden/indra/llmedia/llmediaimplexample1.h new file mode 100644 index 0000000..b78a887 --- /dev/null +++ b/linden/indra/llmedia/llmediaimplexample1.h @@ -0,0 +1,72 @@ +/** + * @file llmediaimplexample1.h + * @brief Example 1 of a media impl concrete class + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLMEDIAIMPLEXAMPLE1_H +#define LLMEDIAIMPLEXAMPLE1_H + +#include "llmediaimplcommon.h" +#include "llmediaimplfactory.h" + +class LLMediaManagerData; + +class LLMediaImplExample1 : + public LLMediaImplCommon +{ + public: + LLMediaImplExample1(); + + static bool startup( LLMediaManagerData* init_data ); + static bool closedown(); + + /* virtual */ bool init(); + /* virtual */ bool navigateTo( const std::string url ); + /* virtual */ bool updateMedia(); + /* virtual */ std::string getVersion(); + /* virtual */ unsigned char* getMediaData(); + /* virtual */ bool reset(); + /* virtual */ bool mouseMove( int x_pos, int y_pos ); + /* virtual */ bool setRequestedMediaSize( int width, int height ); + + private: + unsigned char* mMediaPixels; +}; + +class LLMediaImplExample1Maker : public LLMediaImplMaker +{ + public: + LLMediaImplExample1Maker(); + LLMediaImplExample1* create() + { + return new LLMediaImplExample1(); + } +}; + +#endif // LLMEDIAIMPLEXAMPLE1_H diff --git a/linden/indra/llmedia/llmediaimplexample2.cpp b/linden/indra/llmedia/llmediaimplexample2.cpp new file mode 100644 index 0000000..dc20e03 --- /dev/null +++ b/linden/indra/llmedia/llmediaimplexample2.cpp @@ -0,0 +1,195 @@ +/** + * @file llmediaimplexample2.cpp + * @brief Example 2 of a media impl concrete class + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llmediaimplexample2.h" +#include "llmediaimplregister.h" + +// register this impl with media manager factory +static LLMediaImplRegister sLLMediaImplExample2Reg( "LLMediaImplExample2", new LLMediaImplExample2Maker() ); + +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// +LLMediaImplExample2Maker::LLMediaImplExample2Maker() +{ + // Register to handle the scheme + mSchema.push_back( "example2" ); +} + +/////////////////////////////////////////////////////////////////////////////// +// +LLMediaImplExample2::LLMediaImplExample2() : + mMediaPixels( 0 ) +{ + setRequestedMediaSize( 500, 500 ); + setMediaDepth( 3 ); + + mXpos = ( getMediaWidth() / 2 ) + rand() % ( getMediaWidth() / 16 ) - ( getMediaWidth() / 32 ); + mYpos = ( getMediaHeight() / 2 ) + rand() % ( getMediaHeight() / 16 ) - ( getMediaHeight() / 32 ); + + srand( (unsigned int)(time( NULL )) ); +} + +//////////////////////////////////////////////////////////////////////////////// +// (static) super-initialization - called once at application startup +bool LLMediaImplExample2::startup( LLMediaManagerData* init_data ) +{ + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// (static) super-uninitialization - called once at application closedown +bool LLMediaImplExample2::closedown() +{ + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplExample2::init() +{ + int buffer_size = getMediaBufferSize(); + + mMediaPixels = new unsigned char[ buffer_size ]; + + memset( mMediaPixels, 0x00, buffer_size ); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplExample2::navigateTo( const std::string url ) +{ + std::cout << "LLMediaImplExample2::navigateTo" << std::endl; + + setStatus( LLMediaBase::STATUS_NAVIGATING ); + + // force a size change event for new URL + LLMediaEvent event( this ); + mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +std::string LLMediaImplExample2::getVersion() +{ + std::string version_string = "[" + sLLMediaImplExample2Reg.getImplName() + "] - " + "1.0.0.0"; + + return version_string; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplExample2::updateMedia() +{ + if ( mMediaPixels && getStatus() == LLMediaBase::STATUS_STARTED ) + { + static int x_inc = rand() % 5 + 2; + static int y_inc = rand() % 5 + 2; + int block_size = 32; + + for( int y = 0; y < block_size; ++y ) + { + for( int x = 0; x < block_size; ++x ) + { + int rowspan = getMediaWidth() * getMediaDepth(); + mMediaPixels[ ( mXpos + x ) * getMediaDepth() + ( mYpos + y ) * rowspan + 0 ] = 0; + mMediaPixels[ ( mXpos + x ) * getMediaDepth() + ( mYpos + y ) * rowspan + 1 ] = 0; + mMediaPixels[ ( mXpos + x ) * getMediaDepth() + ( mYpos + y ) * rowspan + 2 ] = 0; + }; + }; + + if ( mXpos + x_inc < 0 || mXpos + x_inc >= getMediaWidth() - block_size ) + x_inc =- x_inc; + + if ( mYpos + y_inc < 0 || mYpos + y_inc >= getMediaHeight() - block_size ) + y_inc =- y_inc; + + mXpos += x_inc; + mYpos += y_inc; + + unsigned char col_r = rand() % 0xff; + unsigned char col_g = rand() % 0xff; + unsigned char col_b = rand() % 0xff; + + for( int y = 0; y < block_size; ++y ) + { + for( int x = 0; x < block_size; ++x ) + { + int rowspan = getMediaWidth() * getMediaDepth(); + mMediaPixels[ ( mXpos + x ) * getMediaDepth() + ( mYpos + y ) * rowspan + 0 ] = col_r; + mMediaPixels[ ( mXpos + x ) * getMediaDepth() + ( mYpos + y ) * rowspan + 1 ] = col_g; + mMediaPixels[ ( mXpos + x ) * getMediaDepth() + ( mYpos + y ) * rowspan + 2 ] = col_b; + }; + }; + + // emit an event to say that something in the media stream changed + LLMediaEvent event( this ); + mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); + }; + + // update the command (e.g. transport controls) state + updateCommand(); + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +unsigned char* LLMediaImplExample2::getMediaData() +{ + return mMediaPixels; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplExample2::reset() +{ + if ( mMediaPixels ) + { + delete [] mMediaPixels; + }; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplExample2::setRequestedMediaSize( int width, int height ) +{ + // we accept any size: + return setMediaSize(width, height); +} diff --git a/linden/indra/llmedia/llmediaimplexample2.h b/linden/indra/llmedia/llmediaimplexample2.h new file mode 100644 index 0000000..475915d --- /dev/null +++ b/linden/indra/llmedia/llmediaimplexample2.h @@ -0,0 +1,75 @@ +/** + * @file llmediaimplexample2.h + * @brief Example 2 of a media impl concrete class + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLMEDIAIMPLEXAMPLE2_H +#define LLMEDIAIMPLEXAMPLE2_H + +#include "llmediaimplcommon.h" +#include "llmediaimplfactory.h" + +class LLMediaManagerData; +class LLMediaImplMaker; + +class LLMediaImplExample2 : + public LLMediaImplCommon +{ + public: + LLMediaImplExample2(); + + static bool startup( LLMediaManagerData* init_data ); + static bool closedown(); + + /* virtual */ bool init(); + /* virtual */ bool navigateTo( const std::string url ); + /* virtual */ bool load( const std::string url ); + /* virtual */ std::string getVersion(); + /* virtual */ bool updateMedia(); + /* virtual */ unsigned char* getMediaData(); + /* virtual */ bool reset(); + /* virtual */ bool setRequestedMediaSize( int width, int height ); + + private: + unsigned char* mMediaPixels; + int mXpos; + int mYpos; +}; + +class LLMediaImplExample2Maker : public LLMediaImplMaker +{ + public: + LLMediaImplExample2Maker(); + LLMediaImplExample2* create() + { + return new LLMediaImplExample2(); + } +}; + +#endif // LLMEDIAIMPLEXAMPLE2_H diff --git a/linden/indra/llmedia/llmediaimplfactory.cpp b/linden/indra/llmedia/llmediaimplfactory.cpp new file mode 100644 index 0000000..0ca7757 --- /dev/null +++ b/linden/indra/llmedia/llmediaimplfactory.cpp @@ -0,0 +1,104 @@ +/** + * @file llmediaimplfactory.cpp + * @brief Creates media impls that have registered themselves with LLMediaRegster + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llmediaimplfactory.h" + +#include + +LLMediaImplFactory* LLMediaImplFactory::sInstance = NULL; + +/////////////////////////////////////////////////////////////////////////////// +// static +LLMediaImplFactory* LLMediaImplFactory::getInstance() +{ + if ( ! sInstance ) + sInstance = new LLMediaImplFactory(); + + return sInstance; +} + +/////////////////////////////////////////////////////////////////////////////// +// +void LLMediaImplFactory::registerImpl( const std::string& impl_name, LLMediaImplMakerBase* impl_maker ) +{ + mNameImplMakerContainer.insert( name_impl_maker_container_t::value_type( impl_name, impl_maker ) ); +} + +/////////////////////////////////////////////////////////////////////////////// +// +LLMediaImplMakerBase* LLMediaImplFactory::getImplMaker( const std::string& scheme, const std::string& type ) +{ + name_impl_maker_container_t::const_iterator iter; + name_impl_maker_container_t::const_iterator begin = mNameImplMakerContainer.begin(); + name_impl_maker_container_t::const_iterator end = mNameImplMakerContainer.end(); + + for(iter = begin; iter != end; ++iter) + { + if(( *iter->second ).supportsScheme(scheme)) + { + return ( iter->second ); + } + } + + for(iter = begin; iter != end; ++iter) + { + if(( *iter->second ).supportsMimeType(type)) + { + return ( iter->second ); + } + } + int idx1 = type.find("/"); + int len = (idx1 == std::string::npos) ? 0 : idx1; + std::string category = type.substr(0,len); + for(iter = begin; iter != end; ++iter) + { + if(( *iter->second ).supportsMimeTypeCategory(category)) + { + return ( iter->second ); + } + } + + return NULL; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +LLMediaImplMakerBase* LLMediaImplFactory::getImplMaker( const std::string& impl_name ) +{ + name_impl_maker_container_t::const_iterator found = mNameImplMakerContainer.find( impl_name ); + + if ( found == mNameImplMakerContainer.end() ) + { + return NULL; + }; + + return found->second; +} diff --git a/linden/indra/llmedia/llmediaimplfactory.h b/linden/indra/llmedia/llmediaimplfactory.h new file mode 100644 index 0000000..fb99c2f --- /dev/null +++ b/linden/indra/llmedia/llmediaimplfactory.h @@ -0,0 +1,99 @@ +/** + * @file llmediaimplfactory.h + * @brief Creates media impls that have registered themselves with LLMediaRegster + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLMEDIAIMPLFACTORY_H +#define LLMEDIAIMPLFACTORY_H + +#include +#include +#include +#include + +#include "llmediabase.h" + +/////////////////////////////////////////////////////////////////////////////// +// +class LLMediaImplMakerBase +{ + public: + virtual bool supportsScheme(std::string scheme) = 0; + virtual bool supportsMimeType(std::string type) = 0; + virtual bool supportsMimeTypeCategory(std::string category) = 0; + virtual LLMediaBase* create() = 0; + virtual ~LLMediaImplMakerBase() {}; + + protected: + typedef std::vector vector_impl_registry_t; + vector_impl_registry_t mSchema; + vector_impl_registry_t mMimeTypes; + vector_impl_registry_t mMimeTypeCategories; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +class LLMediaImplMaker : public LLMediaImplMakerBase +{ + public: + bool supportsScheme(std::string scheme) + { + vector_impl_registry_t::iterator found = std::find(mSchema.begin(), mSchema.end(), scheme); + return found != mSchema.end(); + } + bool supportsMimeType(std::string type) + { + vector_impl_registry_t::iterator found = std::find(mMimeTypes.begin(), mMimeTypes.end(), type); + return found != mMimeTypes.end(); + } + bool supportsMimeTypeCategory(std::string category) + { + vector_impl_registry_t::iterator found = std::find(mMimeTypeCategories.begin(), mMimeTypeCategories.end(), category); + return found != mMimeTypeCategories.end(); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// +class LLMediaImplFactory +{ + public: + static LLMediaImplFactory* getInstance(); + void registerImpl( const std::string& impl_name, LLMediaImplMakerBase* impl_maker ); + LLMediaImplMakerBase* getImplMaker( const std::string& scheme, const std::string& type ); + LLMediaImplMakerBase* getImplMaker( const std::string& impl_name); + + private: + typedef std::map< std::string, LLMediaImplMakerBase* > name_impl_maker_container_t; + name_impl_maker_container_t mNameImplMakerContainer; + + static LLMediaImplFactory* sInstance; +}; + +#endif // LLMEDIAIMPLFACTORY_H diff --git a/linden/indra/llmedia/llmediaimplgstreamer.cpp b/linden/indra/llmedia/llmediaimplgstreamer.cpp index 50dc052..b54d088 100644 --- a/linden/indra/llmedia/llmediaimplgstreamer.cpp +++ b/linden/indra/llmedia/llmediaimplgstreamer.cpp @@ -1,5 +1,6 @@ /** * @file llmediaimplgstreamer.cpp + * @author Tofu Linden * @brief implementation that supports various media through GStreamer. * * $LicenseInfo:firstyear=2007&license=viewergpl$ @@ -29,7 +30,7 @@ * $/LicenseInfo$ */ -#include "linden_common.h" +#include "llmediaimplgstreamer.h" #if LL_GSTREAMER_ENABLED @@ -37,7 +38,8 @@ extern "C" { #include } -#include "llmediaimplgstreamer.h" +#include "llmediamanager.h" +#include "llmediaimplregister.h" #include "llmediaimplgstreamervidplug.h" @@ -47,17 +49,28 @@ extern "C" { #include "llmediaimplgstreamer_syms.h" -#include "llgl.h" -#include "llglheaders.h" // For gl texture modes +// register this impl with media manager factory +static LLMediaImplRegister sLLMediaImplGStreamerReg( "LLMediaImplGStreamer", new LLMediaImplGStreamerMaker() ); + +LLMediaImplGStreamerMaker::LLMediaImplGStreamerMaker() +{ + // Register to handle the scheme + mSchema.push_back( "rtsp" ); + mSchema.push_back( "rtmp" ); + + // Register to handle the category + mMimeTypeCategories.push_back( "video" ); + mMimeTypeCategories.push_back( "audio" ); +} /////////////////////////////////////////////////////////////////////////////// // LLMediaImplGStreamer:: LLMediaImplGStreamer () : mediaData ( NULL ), - ownBuffer ( TRUE ), - mVolume ( 1.0f ), - currentMode ( ModeIdle ), + mMediaRowbytes ( 1 ), + mTextureFormatPrimary ( LL_MEDIA_BGRA ), + mTextureFormatType ( LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV ), mPump ( NULL ), mPlaybin ( NULL ), mVideoSink ( NULL ) @@ -65,80 +78,95 @@ LLMediaImplGStreamer () : ,mAudioSink ( NULL ) #endif // LL_GST_SOUNDSINK { - mMediaDepthBytes = 4; - mTextureDepth = 4; - mTextureFormatInternal = GL_RGB8; - mTextureFormatPrimary = GL_BGRA; - mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; + DEBUGMSG("constructing media..."); + + setMediaDepth(4); + + // Create a pumpable main-loop for this media + mPump = g_main_loop_new (NULL, FALSE); + if (!mPump) + { + return; // error + } + + // instantiate a playbin element to do the hard work + mPlaybin = llgst_element_factory_make ("playbin", "play"); + if (!mPlaybin) + { + // todo: cleanup pump + return; // error + } + + if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { + // instantiate and connect a custom video sink + mVideoSink = + GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); + if (!mVideoSink) + { + WARNMSG("Could not instantiate private-slvideo element."); + // todo: cleanup. + return; // error + } + + g_object_set(mPlaybin, "video-sink", mVideoSink, NULL); + +#ifdef LL_GST_SOUNDSINK + // instantiate and connect a custom audio sink + mAudioSink = + GST_SLSOUND(llgst_element_factory_make ("private-slsound", "slsound")); + if (!mAudioSink) + { + WARNMSG("Could not instantiate private-slsound element."); + // todo: cleanup. + return; // error + } + + g_object_set(mPlaybin, "audio-sink", mAudioSink, NULL); +#endif + } } -/////////////////////////////////////////////////////////////////////////////// -// -LLMediaImplGStreamer:: -~LLMediaImplGStreamer () +// virtual +int LLMediaImplGStreamer::getTextureFormatPrimary() const { - unload(); + return mTextureFormatPrimary; } -void UnloadGStreamer() +// virtual +int LLMediaImplGStreamer::getTextureFormatType() const { - ungrab_gst_syms(); + return mTextureFormatType; } +// virtual +int LLMediaImplGStreamer::getTextureFormatInternal() const +{ + return LL_MEDIA_RGB8; +} /////////////////////////////////////////////////////////////////////////////// // -BOOL LLMediaImplGStreamer:: -setBuffer ( U8* bufferIn ) +~LLMediaImplGStreamer () { - // Since we've pointed GStreamer at the old media data buffer - // directly, we need to be somewhat careful deleting it... - U8* oldMediaData = mediaData; - BOOL ownedMediaData = ownBuffer; - - if(bufferIn == NULL) - { - // Passing NULL to this function requests that the object - // allocate its own buffer. - mediaData = new unsigned char[ mMediaHeight * mMediaRowbytes ]; - ownBuffer = TRUE; - } - else - { - // Use the supplied buffer. - mediaData = bufferIn; - ownBuffer = FALSE; - } - - if(mediaData == NULL) - { - // This is bad - probably out of memory. - llerrs << "LLMediaImplGStreamer::setBuffer: mediaData is NULL" << llendl; - // NOTE: This case doesn't clean up properly. This assert is fatal, so this isn't a huge problem, - // but if this assert is ever removed the code should be fixed to clean up correctly. - return FALSE; - } - - // [..] + DEBUGMSG("dtor of media..."); + unload(); +} - // Delete the old media data buffer iff we owned it. - if ( ownedMediaData ) - { - if ( oldMediaData ) - { - delete [] oldMediaData; - } - } - - return TRUE; +//////////////////////////////////////////////////////////////////////////////// +// virtual +std::string LLMediaImplGStreamer::getVersion() +{ + std::string rtn; + rtn = "[" + sLLMediaImplGStreamerReg.getImplName() + "] - GStreamer 0.10.x"; + return rtn; } /////////////////////////////////////////////////////////////////////////////// -// -BOOL +// (static) super-initialization - called once at application startup +bool LLMediaImplGStreamer:: -init () +startup ( LLMediaManagerData* init_data ) { static bool done_init = false; if (!done_init) @@ -148,19 +176,19 @@ init () "libgstvideo-0.10.so.0", "libgstaudio-0.10.so.0") ) { - llwarns << "Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled." << llendl; - return FALSE; + WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); + return false; } if (llgst_segtrap_set_enabled) llgst_segtrap_set_enabled(FALSE); else - llwarns << "gst_segtrap_set_enabled() is not available; Second Life automated crash-reporter may cease to function until next restart." << llendl; + WARNMSG("gst_segtrap_set_enabled() is not available; Automated crash-reporter may cease to function until next restart."); if (0 == llgst_init_check(NULL, NULL, NULL)) { - llwarns << "GST init failed for unspecified reason." << llendl; - return FALSE; + WARNMSG("GST init failed for unspecified reason."); + return false; } // Init our custom plugins - only really need do this once. @@ -172,52 +200,16 @@ init () done_init = true; } - // Create a pumpable main-loop for this media - mPump = g_main_loop_new (NULL, FALSE); - if (!mPump) - { - return FALSE; - } - - // instantiate a playbin element to do the hard work - mPlaybin = llgst_element_factory_make ("playbin", "play"); - if (!mPlaybin) - { - // todo: cleanup pump - return FALSE; - } - - if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { - // instantiate and connect a custom video sink - mVideoSink = - GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); - if (!mVideoSink) - { - llwarns << "Could not instantiate private-slvideo element." - << llendl; - // todo: cleanup. - return FALSE; - } - - g_object_set(mPlaybin, "video-sink", mVideoSink, NULL); + return true; +} -#ifdef LL_GST_SOUNDSINK - // instantiate and connect a custom audio sink - mAudioSink = - GST_SLSOUND(llgst_element_factory_make ("private-slsound", "slsound")); - if (!mAudioSink) - { - llwarns << "Could not instantiate private-slsound element." - << llendl; - // todo: cleanup. - return FALSE; - } - g_object_set(mPlaybin, "audio-sink", mAudioSink, NULL); -#endif - } +bool LLMediaImplGStreamer:: +closedown() +{ + ungrab_gst_syms(); - return LLMediaMovieBase::init(); + return true; } @@ -239,22 +231,20 @@ static char* get_gst_state_name(GstState state) #endif // LL_GST_REPORT_STATE_CHANGES static gboolean -my_bus_callback (GstBus *bus, - GstMessage *message, - gpointer data) +bus_callback (GstBus *bus, + GstMessage *message, + gpointer data) { if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) { - llinfos << "Got GST message type: " - << LLGST_MESSAGE_TYPE_NAME (message) - << llendl; + DEBUGMSG("Got GST message type: %s", + LLGST_MESSAGE_TYPE_NAME (message)); } else { - lldebugs << "Got GST message type: " - << LLGST_MESSAGE_TYPE_NAME (message) - << llendl; + DEBUGMSG("Got GST message type: %s", + LLGST_MESSAGE_TYPE_NAME (message)); } LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data; @@ -266,11 +256,10 @@ my_bus_callback (GstBus *bus, { gint percent = 0; llgst_message_parse_buffering(message, &percent); - llinfos << "GST buffering: " << percent - << "%" << llendl; - // ModeBuffering seems to do nothing except make - // the UI worse - /*if (percent < 100) impl->setCurrentMode(LLMediaImplGStreamer::ModeBuffering);*/ + DEBUGMSG("GST buffering: %d%%", percent); + LLMediaEvent event( impl, percent ); + impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); + } break; } @@ -284,66 +273,63 @@ my_bus_callback (GstBus *bus, &pending_state); #ifdef LL_GST_REPORT_STATE_CHANGES // not generally very useful, and rather spammy. - llinfos << "state change (old,,pending): " - << get_gst_state_name(old_state) << ", <" - << get_gst_state_name(new_state) << ">, " - << get_gst_state_name(pending_state) << - llendl; + DEBUGMSG("state change (old,,pending): %s,<%s>,%s", + get_gst_state_name(old_state), + get_gst_state_name(new_state), + get_gst_state_name(pending_state)); #endif // LL_GST_REPORT_STATE_CHANGES switch (new_state) { case GST_STATE_VOID_PENDING: - impl->setCurrentMode(LLMediaImplGStreamer::ModeNone); break; case GST_STATE_NULL: - impl->setCurrentMode(LLMediaImplGStreamer::ModeNone); break; case GST_STATE_READY: - impl->setCurrentMode(LLMediaImplGStreamer::ModeStopped); break; case GST_STATE_PAUSED: - impl->setCurrentMode(LLMediaImplGStreamer::ModePaused); break; case GST_STATE_PLAYING: - impl->setCurrentMode(LLMediaImplGStreamer::ModePlaying); + LLMediaEvent event( impl, 100 ); + impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); + // emit an event to say that a media source was loaded + LLMediaEvent event2( impl ); + impl->getEventEmitter().update( &LLMediaObserver::onMediaLoaded, event2 ); break; } break; } case GST_MESSAGE_ERROR: { - GError *err; - gchar *debug; + GError *err = NULL; + gchar *debug = NULL; llgst_message_parse_error (message, &err, &debug); - llinfos << "GST error: " << err->message << llendl; + WARNMSG("GST error: %s", err->message); g_error_free (err); g_free (debug); - impl->setCurrentMode(LLMediaImplGStreamer::ModeError); - - impl->stop(); + impl->addCommand(LLMediaBase::COMMAND_STOP); break; } case GST_MESSAGE_INFO: { if (llgst_message_parse_info) { - GError *err; - gchar *debug; + GError *err = NULL; + gchar *debug = NULL; llgst_message_parse_info (message, &err, &debug); - llinfos << "GST info: " << err->message << llendl; + INFOMSG("GST info: %s", err->message); g_error_free (err); g_free (debug); } break; } case GST_MESSAGE_WARNING: { - GError *err; - gchar *debug; + GError *err = NULL; + gchar *debug = NULL; llgst_message_parse_warning (message, &err, &debug); - llinfos << "GST warning: " << err->message << llendl; + WARNMSG("GST warning: %s", err->message); g_error_free (err); g_free (debug); @@ -351,9 +337,18 @@ my_bus_callback (GstBus *bus, } case GST_MESSAGE_EOS: /* end-of-stream */ - llinfos << "GST EOS." << llendl; - impl->setCurrentMode(LLMediaImplGStreamer::ModeStopped);//? - impl->stop(); + DEBUGMSG("GST end-of-stream."); + if (impl->isLooping()) + { + DEBUGMSG("looping media..."); + impl->stop(); + impl->play(); + } + else + { + // inject a COMMAND_STOP + impl->addCommand(LLMediaBase::COMMAND_STOP); + } break; default: /* unhandled message */ @@ -361,52 +356,57 @@ my_bus_callback (GstBus *bus, } /* we want to be notified again the next time there is a message - * on the bus, so returning TRUE (FALSE means we want to stop watching + * on the bus, so return true (false means we want to stop watching * for messages on the bus and our callback should not be called again) */ return TRUE; } -BOOL +/////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplGStreamer:: -load ( const LLString& urlIn ) +navigateTo ( const std::string urlIn ) { - llinfos << "Setting media URI: " << urlIn << llendl; + DEBUGMSG("Setting media URI: %s", urlIn.c_str()); + + if (NULL == mPump +#ifdef LL_GST_SOUNDSINK + || NULL == mAudioSink +#endif + || NULL == mPlaybin) + { + return false; + } + + setStatus( LLMediaBase::STATUS_NAVIGATING ); // set URI g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL); - // get playbin's bus - perhaps this can/should be done at init() + // get playbin's bus - perhaps this can/should be done in ctor GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); if (!bus) { - return FALSE; + return false; } - llgst_bus_add_watch (bus, my_bus_callback, this); + llgst_bus_add_watch (bus, bus_callback, this); llgst_object_unref (bus); - if (true) // dummy values - { - const int fixedsize = 2; - mMediaRowbytes = mMediaDepthBytes * fixedsize; - mMediaWidth = fixedsize; - mMediaHeight = fixedsize; - mTextureWidth = fixedsize; - mTextureHeight = fixedsize; - } + // navigateTo implicitly plays, too. + play(); - BOOL rtn = LLMediaMovieBase::load(urlIn); - llinfos << "load returns " << int(rtn) << llendl; - return rtn; + return true; } /////////////////////////////////////////////////////////////////////////////// // -BOOL +bool LLMediaImplGStreamer:: unload () { + DEBUGMSG("unloading media..."); if (mPlaybin) { llgst_element_set_state (mPlaybin, GST_STATE_NULL); @@ -422,25 +422,75 @@ unload () if (mediaData) { - if (ownBuffer) - { - delete mediaData; - mediaData = NULL; - } + delete mediaData; + mediaData = NULL; } mVideoSink = NULL; - return TRUE; + return true; } /////////////////////////////////////////////////////////////////////////////// -// -S32 +// virtual +bool LLMediaImplGStreamer:: updateMedia () { - //llinfos << "updating media..." << llendl; + DEBUGMSG("updating media..."); + + // sanity check + if (NULL == mPump +#ifdef LL_GST_SOUNDSINK + || NULL == mAudioSink +#endif + || NULL == mPlaybin) + { + DEBUGMSG("dead media..."); + return false; + } + + // process next outstanding command + switch (nextCommand()) + { + case LLMediaBase::COMMAND_START: + DEBUGMSG("COMMAND_START"); + if (getStatus() == LLMediaBase::STATUS_PAUSED || + getStatus() == LLMediaBase::STATUS_NAVIGATING || + getStatus() == LLMediaBase::STATUS_STOPPED) + { + DEBUGMSG("doing COMMAND_START"); + play(); + setStatus(LLMediaBase::STATUS_STARTED); + clearCommand(); + } + break; + case LLMediaBase::COMMAND_STOP: + DEBUGMSG("COMMAND_STOP"); + DEBUGMSG("doing COMMAND_STOP"); + stop(); + setStatus(LLMediaBase::STATUS_STOPPED); + clearCommand(); + break; + case LLMediaBase::COMMAND_PAUSE: + DEBUGMSG("COMMAND_PAUSE"); + if (getStatus() == LLMediaBase::STATUS_STARTED) + { + DEBUGMSG("doing COMMAND_PAUSE"); + pause(); + setStatus(LLMediaBase::STATUS_PAUSED); + clearCommand(); + } + break; + default: + DEBUGMSG("COMMAND_?"); + clearCommand(); + break; + case LLMediaBase::COMMAND_NONE: + break; + } + + // deal with results if (g_main_context_pending(g_main_loop_get_context(mPump))) { g_main_context_iteration(g_main_loop_get_context(mPump), FALSE); @@ -451,269 +501,121 @@ updateMedia () GST_OBJECT_LOCK(mVideoSink); if (mVideoSink->retained_frame_ready) { - //llinfos << "NEW FRAME " << llendl; - if (mVideoSink->retained_frame_width != mMediaWidth || - mVideoSink->retained_frame_height != mMediaHeight) + DEBUGMSG("NEW FRAME "); + if (mVideoSink->retained_frame_width != getMediaWidth() || + mVideoSink->retained_frame_height != getMediaHeight()) // *TODO: also check for change in format { - // just resize container - mMediaWidth = mVideoSink->retained_frame_width; - mMediaHeight = mVideoSink->retained_frame_height; - mTextureWidth = mMediaWidth; - mTextureHeight = mMediaHeight; - mMediaDepthBytes = mTextureDepth = - SLVPixelFormatBytes[mVideoSink->retained_frame_format]; + // just resize containe + int neww = mVideoSink->retained_frame_width; + int newh = mVideoSink->retained_frame_height; + int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format]; if (SLV_PF_RGBX == mVideoSink->retained_frame_format) { - mTextureFormatPrimary = GL_RGBA; - mTextureFormatType=GL_UNSIGNED_INT_8_8_8_8_REV; + mTextureFormatPrimary = LL_MEDIA_RGBA; + mTextureFormatType = LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV; } else { - mTextureFormatPrimary = GL_BGRA; - mTextureFormatType=GL_UNSIGNED_INT_8_8_8_8_REV; + mTextureFormatPrimary = LL_MEDIA_BGRA; + mTextureFormatType = LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV; } - mMediaRowbytes = mMediaWidth * mMediaDepthBytes; - llinfos << "video container resized to " << - mMediaWidth << "x" << mMediaHeight << llendl; + mMediaRowbytes = neww * newd; + DEBUGMSG("video container resized to %dx%d", + neww, newh); - if (ownBuffer) - { - // we manage the buffer, so we need to realloc - delete[] mediaData; - mediaData = new U8[mMediaRowbytes * - mMediaHeight]; - } + delete[] mediaData; + mediaData = new unsigned char[mMediaRowbytes * + newh]; GST_OBJECT_UNLOCK(mVideoSink); - return updateMediaNeedsSizeChange; + + setMediaDepth(newd); + setMediaSize(neww, newh); + return true; } // we're gonna totally consume this frame - reset 'ready' flag mVideoSink->retained_frame_ready = FALSE; memcpy(mediaData, mVideoSink->retained_frame_data, - mMediaRowbytes * mMediaHeight); + mMediaRowbytes * getMediaHeight()); GST_OBJECT_UNLOCK(mVideoSink); - return updateMediaNeedsUpdate; + LLMediaEvent event( this ); + mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); + return true; } else { // nothing to do yet. GST_OBJECT_UNLOCK(mVideoSink); - return updateMediaNoChanges; + return true; } } - return updateMediaNoChanges; -} - -/////////////////////////////////////////////////////////////////////////////// -// -void -LLMediaImplGStreamer:: -setAutoScaled ( BOOL autoScaledIn ) -{ - autoScaled = autoScaledIn; + return true; } /////////////////////////////////////////////////////////////////////////////// // -BOOL +bool LLMediaImplGStreamer:: stop () { - llinfos << "stopping media..." << llendl; + DEBUGMSG("stopping media..."); // todo: error-check this? llgst_element_set_state(mPlaybin, GST_STATE_READY); - - BOOL rtn = LLMediaMovieBase::stop(); - setCurrentMode(LLMediaImplGStreamer::ModeStopped);//? - return rtn; + return true; } /////////////////////////////////////////////////////////////////////////////// // -BOOL +bool LLMediaImplGStreamer:: play () { - llinfos << "playing media..." << llendl; + DEBUGMSG("playing media..."); // todo: error-check this? llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); - - return LLMediaMovieBase::play(); + return true; } /////////////////////////////////////////////////////////////////////////////// // -BOOL -LLMediaImplGStreamer:: -loop ( S32 howMany ) -{ - llinfos << "looping media... " << howMany << llendl; - // todo: implement this - if (!play()) - return FALSE; - - return LLMediaMovieBase::loop(howMany); -}; - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL +bool LLMediaImplGStreamer:: pause () { - llinfos << "pausing media..." << llendl; + DEBUGMSG("pausing media..."); // todo: error-check this? llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); - - return LLMediaMovieBase::pause(); + return true; }; -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplGStreamer:: -setVolume ( F32 volumeIn ) -{ - mVolume = volumeIn; - g_object_set(mPlaybin, "volume", mVolume, NULL); - return TRUE; -} /////////////////////////////////////////////////////////////////////////////// -// -F32 -LLMediaImplGStreamer:: -getVolume () -{ - return mVolume; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplGStreamer:: -isIdle () const -{ - // todo: probably semantically decouple from currentMode - return currentMode == ModeIdle; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplGStreamer:: -isError () const -{ - // todo: probably semantically decouple from currentMode - return currentMode == ModeError; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplGStreamer:: -isBuffering () const -{ - // todo: probably semantically decouple from currentMode - return currentMode == ModeBuffering; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplGStreamer:: -isLoaded () const -{ - // todo: probably semantically decouple from currentMode - //return currentMode == ModeLoaded; - return (mPump != NULL); -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplGStreamer:: -isPlaying () const -{ - // todo: probably semantically decouple from currentMode - return currentMode == ModePlaying; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplGStreamer:: -isLooping () const -{ - // todo: probably semantically decouple from currentMode - return currentMode == ModeLooping; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplGStreamer:: -isPaused () const -{ - // todo: probably semantically decouple from currentMode - return currentMode == ModePaused; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplGStreamer:: -isStopped () const -{ - // todo: probably semantically decouple from currentMode - return currentMode == ModeStopped; -} - -/////////////////////////////////////////////////////////////////////////////// -// -U8* +// virtual +unsigned char* LLMediaImplGStreamer:: getMediaData () { return mediaData; } -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplGStreamer:: -seek ( F64 time ) -{ - // todo: implement this - llinfos << "Tried to seek to time " << time - << " - faking it" << llendl; - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -F64 -LLMediaImplGStreamer:: -getTime () const -{ - // todo: implement this - F64 result = 0; - return result; -} /////////////////////////////////////////////////////////////////////////////// -// -F64 +// virtual +bool LLMediaImplGStreamer:: -getMediaDuration () const +setVolume(float volume) { - // todo: implement this - F64 result = 0; - return result; + mVolume = volume; + if (mPlaybin) + { + g_object_set(mPlaybin, "volume", mVolume, NULL); + return true; + } + return false; } #endif // LL_GSTREAMER_ENABLED diff --git a/linden/indra/llmedia/llmediaimplgstreamer.h b/linden/indra/llmedia/llmediaimplgstreamer.h index f1a7956..944db59 100644 --- a/linden/indra/llmedia/llmediaimplgstreamer.h +++ b/linden/indra/llmedia/llmediaimplgstreamer.h @@ -1,5 +1,6 @@ /** * @file llmediaimplgstreamer.h + * @author Tofu Linden * @brief implementation that supports media playback via GStreamer. * * $LicenseInfo:firstyear=2007&license=viewergpl$ @@ -33,27 +34,30 @@ #ifndef llmediaimplgstreamer_h #define llmediaimplgstreamer_h +#include "llmediaimplcommon.h" +#include "llmediaimplfactory.h" + #if LL_GSTREAMER_ENABLED extern "C" { +#include #include #include #include } -#include "stdtypes.h" - -#include "llmediamoviebase.h" - #include "llmediaimplgstreamervidplug.h" #ifdef LL_GST_SOUNDSINK #include "llmediaimplgstreamersndplug.h" #endif // LL_GST_SOUNDSINK +class LLMediaManagerData; +class LLMediaImplMaker; + /////////////////////////////////////////////////////////////////////////// class LLMediaImplGStreamer: - public LLMediaMovieBase + public LLMediaImplCommon { public: LLMediaImplGStreamer (); @@ -62,54 +66,31 @@ class LLMediaImplGStreamer: //////////////////////////////////////////////////////// // implementation of the media public interface - // housekeeping - virtual BOOL setBuffer ( U8* bufferIn ); - virtual BOOL init (); - virtual BOOL load ( const LLString& urlIn ); - virtual BOOL unload (); - - // transport controls - virtual BOOL stop (); - virtual BOOL play (); - virtual BOOL loop ( S32 howMany ); - virtual BOOL pause (); - virtual BOOL seek ( F64 time ); - - // audio levels - virtual BOOL setVolume ( F32 volumeIn ); - virtual F32 getVolume (); - - // status - virtual BOOL isIdle () const; - virtual BOOL isBuffering () const; - virtual BOOL isError () const; - virtual BOOL isLoaded () const; - virtual BOOL isStopped () const; - virtual BOOL isPaused () const; - virtual BOOL isPlaying () const; - virtual BOOL isLooping () const; - virtual F64 getTime () const; - - // media data - virtual S32 updateMedia (); - virtual void setAutoScaled ( BOOL autoScaledIn ); - virtual U8* getMediaData (); - virtual F64 getMediaDuration () const; - - // class-specific - GMainLoop *getPump() {return mPump;}; - typedef enum { ModeNone, ModeIdle, ModeError, ModeBuffering, ModeStopped, ModePaused, ModePlaying, ModeLooping } llGstMode; - llGstMode getCurrentMode() {return currentMode;}; - void setCurrentMode(llGstMode mode) {currentMode = mode;}; + static bool startup( LLMediaManagerData* init_data ); + static bool closedown(); + + /* virtual */ std::string getVersion(); + /* virtual */ bool navigateTo( const std::string url ); + /* virtual */ bool updateMedia(); + /* virtual */ unsigned char* getMediaData(); + /* virtual */ int getTextureFormatPrimary() const; + /* virtual */ int getTextureFormatType() const; + /* virtual */ int getTextureFormatInternal() const; + /* virtual */ bool setVolume( float volume ); + + bool stop(); + bool play(); + LLMediaEmitter< LLMediaObserver > getEventEmitter() const {return mEventEmitter;}; private: - // misc - U8* mediaData; - BOOL ownBuffer; - BOOL autoScaled; - F32 mVolume; + // misc + bool unload(); + bool pause(); + unsigned char* mediaData; + int mMediaRowbytes; - llGstMode currentMode; + int mTextureFormatPrimary; + int mTextureFormatType; // GStreamer-specific GMainLoop *mPump; // event pump for this media @@ -120,9 +101,29 @@ class LLMediaImplGStreamer: #endif // LL_GST_SOUNDSINK }; -// called during shutdown when no instances may exist -void UnloadGStreamer(); +class LLMediaImplGStreamerMaker : public LLMediaImplMaker +{ +public: + LLMediaImplGStreamerMaker(); + LLMediaImplGStreamer* create() + { + return new LLMediaImplGStreamer(); + } +}; +///////////////////////////////////////////////////////////////////////// +// Debug/Info/Warning macros. +#define STDERRMSG(...) do{\ + fprintf(stderr, "%s:%d: ", __FUNCTION__, __LINE__);\ + fprintf(stderr, __VA_ARGS__);\ + fputc('\n',stderr);\ + }while(0) +#define NULLMSG(...) do{}while(0) + +#define DEBUGMSG NULLMSG +#define INFOMSG STDERRMSG +#define WARNMSG STDERRMSG +///////////////////////////////////////////////////////////////////////// #endif // LL_GSTREAMER_ENABLED diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp b/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp index 5d54689..bba3ef5 100644 --- a/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp +++ b/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp @@ -29,8 +29,6 @@ * $/LicenseInfo$ */ -#include "linden_common.h" - #if LL_GSTREAMER_ENABLED extern "C" { @@ -71,7 +69,7 @@ bool grab_gst_syms(std::string gst_dso_name, apr_status_t rv; apr_dso_handle_t *sSymGSTDSOHandle = NULL; -#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {llwarns << "Failed to grab symbol: " << #GSTSYM << llendl; if (REQ) sym_error = true;} else llinfos << "grabbed symbol: " << #GSTSYM << " from " << (void*)ll##GSTSYM << llendl;}while(0) +#define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #GSTSYM); if (REQ) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #GSTSYM, (void*)ll##GSTSYM);}while(0) //attempt to load the shared libraries apr_pool_create(&sSymGSTDSOMemoryPool, NULL); @@ -80,7 +78,7 @@ bool grab_gst_syms(std::string gst_dso_name, gst_dso_name.c_str(), sSymGSTDSOMemoryPool) )) { - llinfos << "Found DSO: " << gst_dso_name << llendl; + INFOMSG("Found DSO: %s", gst_dso_name.c_str()); #include "llmediaimplgstreamer_syms_raw.inc" if ( sSymGSTDSOHandle ) @@ -93,7 +91,7 @@ bool grab_gst_syms(std::string gst_dso_name, gst_dso_name_aud.c_str(), sSymGSTDSOMemoryPool) )) { - llinfos << "Found DSO: " << gst_dso_name_aud << llendl; + INFOMSG("Found DSO: %s", gst_dso_name_aud.c_str()); #include "llmediaimplgstreamer_syms_rawa.inc" if ( sSymGSTDSOHandle ) @@ -107,20 +105,18 @@ bool grab_gst_syms(std::string gst_dso_name, gst_dso_name_vid.c_str(), sSymGSTDSOMemoryPool) )) { - llinfos << "Found DSO: " << gst_dso_name_vid << llendl; + INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str()); #include "llmediaimplgstreamer_syms_rawv.inc" } else { - llwarns << "Couldn't load DSO: " - << gst_dso_name_vid << llendl; + INFOMSG("Couldn't load DSO: %s", gst_dso_name_vid.c_str()); rtn = false; // failure } } else { - llwarns << "Couldn't load DSO: " - << gst_dso_name_aud << llendl; + INFOMSG("Couldn't load DSO: %s", gst_dso_name_aud.c_str()); rtn = false; // failure } @@ -128,13 +124,13 @@ bool grab_gst_syms(std::string gst_dso_name, } else { - llwarns << "Couldn't load DSO: " << gst_dso_name << llendl; + INFOMSG("Couldn't load DSO: ", gst_dso_name.c_str()); rtn = false; // failure } if (sym_error) { - llwarns << "Failed to find necessary symbols in GStreamer libraries." << llendl; + WARNMSG("Failed to find necessary symbols in GStreamer libraries."); } if ( sSymGSTDSOHandle ) diff --git a/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp b/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp index 7c59caf..f9c2f89 100644 --- a/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp +++ b/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp @@ -137,7 +137,7 @@ gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) if (needbytes != slvideo->retained_frame_allocbytes) { delete[] slvideo->retained_frame_data; - slvideo->retained_frame_data = new U8[needbytes]; + slvideo->retained_frame_data = new unsigned char[needbytes]; slvideo->retained_frame_allocbytes = needbytes; } @@ -146,7 +146,7 @@ gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) for (int ypos=0; yposheight; ++ypos) { memcpy(&slvideo->retained_frame_data[(slvideo->height-1-ypos)*rowbytes], - &(((U8*)GST_BUFFER_DATA(buf))[ypos*rowbytes]), + &(((unsigned char*)GST_BUFFER_DATA(buf))[ypos*rowbytes]), rowbytes); } // done with the shared data diff --git a/linden/indra/llmedia/llmediaimplgstreamervidplug.h b/linden/indra/llmedia/llmediaimplgstreamervidplug.h index a15798e..27957db 100644 --- a/linden/indra/llmedia/llmediaimplgstreamervidplug.h +++ b/linden/indra/llmedia/llmediaimplgstreamervidplug.h @@ -82,7 +82,7 @@ struct _GstSLVideo // (i.e. all written at once to reflect the current retained frame info // when the retained frame is updated.) bool retained_frame_ready; // new frame ready since flag last reset. (*TODO: could get the writer to wait on a semaphore instead of having the reader poll, potentially making dropped frames somewhat cheaper.) - U8* retained_frame_data; + unsigned char* retained_frame_data; int retained_frame_allocbytes; int retained_frame_width, retained_frame_height; SLVPixelFormat retained_frame_format; @@ -90,7 +90,7 @@ struct _GstSLVideo struct _GstSLVideoClass { - GstVideoSink parent_class; + GstVideoSinkClass parent_class; }; GType gst_slvideo_get_type (void); diff --git a/linden/indra/llmedia/llmediaimplllmozlib.cpp b/linden/indra/llmedia/llmediaimplllmozlib.cpp new file mode 100644 index 0000000..06250f7 --- /dev/null +++ b/linden/indra/llmedia/llmediaimplllmozlib.cpp @@ -0,0 +1,590 @@ +/** + * @file llmediaimplllmozlib.cpp + * @brief Example 2 of a media impl concrete class + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llmediaimplllmozlib.h" + +#if LL_LLMOZLIB_ENABLED + +#include "llmediaimplregister.h" +#include "llmediamanager.h" + +#ifdef WIN32 + // platform specific includes needed before OpenGL header + #include + #include +#elif defined(__APPLE__) + // framework-style include path when building on the Mac. + #include +#else // Assume this is linux + // Linux, MESA headers, but not necessarily assuming MESA runtime. + // quotes so we get libraries/.../GL/ version + #include "GL/gl.h" +#endif + +#include + +// register this impl with media manager factory +static LLMediaImplRegister sLLMediaImplLLMozLibReg( "LLMediaImplLLMozLib", new LLMediaImplLLMozLibMaker() ); + +/////////////////////////////////////////////////////////////////////////////// +// +LLMediaImplLLMozLibMaker::LLMediaImplLLMozLibMaker() +{ + // Register to handle the scheme + mMimeTypeCategories.push_back( "text" ); +#if !LL_QUICKTIME_ENABLED + mMimeTypeCategories.push_back( "image" ); +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +// +LLMediaImplLLMozLib::LLMediaImplLLMozLib() : + mBrowserWindowWidth( 800 ), + mBrowserWindowHeight( 600 ), + mMediaDataWidth( 0 ), + mMediaDataHeight( 0 ), + mWindowId( 0 ), + mNeedsUpdate( false ) +{ + setRequestedMediaSize( mBrowserWindowWidth, mBrowserWindowHeight ); + + setMediaDepth( 4 ); +} + +//////////////////////////////////////////////////////////////////////////////// +// (static) super-initialization - called once at application startup +bool LLMediaImplLLMozLib::startup( LLMediaManagerData* init_data ) +{ + bool result = LLMozLib::getInstance()->init( init_data->getBrowserApplicationDir(), + init_data->getBrowserComponentDir(), + init_data->getBrowserProfileDir(), + init_data->getBrowserParentWindow() ); + + // append special string to the embedded browser user agent string + LLMozLib::getInstance()->setBrowserAgentId( init_data->getBrowserUserAgentId() ); + + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +// (static) super-uninitialization - called once at application closedown +bool LLMediaImplLLMozLib::closedown() +{ + // name discrepancy - this reset actually shuts down LLMozLib + LLMozLib::getInstance()->reset(); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::init() +{ + // if mWindowId is non-0, it's we already called init() and shouldn't call it again + // (::reset() will zero this value) + if ( mWindowId ) + return false; + + mWindowId = LLMozLib::getInstance()->createBrowserWindow( mBrowserWindowWidth, mBrowserWindowHeight ); + + LLMozLib::getInstance()->setSize( mWindowId, mBrowserWindowWidth, mBrowserWindowHeight ); + + LLMozLib::getInstance()->setBackgroundColor( mWindowId, 0x00, 0x00, 0x00 ); + + LLMozLib::getInstance()->addObserver( mWindowId, this ); + + // plugins only work with some client-side hackery and they cause + // exception handling issues (DEV-10020) so we turn them off + LLMozLib::getInstance()->enablePlugins( false ); + + // second life client needs the bitmap flipped + LLMozLib::getInstance()->flipWindow( mWindowId, true ); + + // set media depth now we have created a browser window and know what it is + setMediaDepth( LLMozLib::getInstance()->getBrowserDepth( mWindowId ) ); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +std::string LLMediaImplLLMozLib::getVersion() +{ + std::string version_string = "[" + sLLMediaImplLLMozLibReg.getImplName() + "] - " + LLMozLib::getInstance()->getVersion(); + + return version_string; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::set404RedirectUrl( std::string redirect_url ) +{ + return LLMozLib::getInstance()->set404RedirectUrl( mWindowId, redirect_url ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual + +bool LLMediaImplLLMozLib::clr404RedirectUrl() +{ + return LLMozLib::getInstance()->clr404RedirectUrl( mWindowId ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::setBackgroundColor( unsigned int red, unsigned int green, unsigned int blue ) const +{ + return LLMozLib::getInstance()->setBackgroundColor( mWindowId, red, green, blue ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::setCaretColor( unsigned int red, unsigned int green, unsigned int blue ) const +{ + return LLMozLib::getInstance()->setCaretColor( mWindowId, red, green, blue ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::navigateTo( const std::string url ) +{ + // pass url to llmozlib + LLMozLib::getInstance()->navigateTo( mWindowId, url ); + + // emit event with size change to kick things off + LLMediaEvent event( this ); + mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); + + // not that useful right now but maybe later + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::updateMedia() +{ + if ( getStatus() == LLMediaBase::STATUS_STARTED ) + { + // if flag set, the page changed and we need to update + if ( mNeedsUpdate ) + { + // snap browser pixels + LLMozLib::getInstance()->grabBrowserWindow( mWindowId ); + + // update media width - rendering the page can change it + mMediaDataWidth = LLMozLib::getInstance()->getBrowserRowSpan( mWindowId ) / getMediaDepth(); + mMediaDataHeight = LLMozLib::getInstance()->getBrowserHeight( mWindowId ); + + // emit an event to say that something in the media stream changed + LLMediaEvent event( this ); + mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); + + // flag that we've done the update and one isn't needed next frame + mNeedsUpdate = false; + }; + }; + + // update the state (e.g. transport controls) state + updateState(); + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool LLMediaImplLLMozLib::updateState() +{ + if ( nextCommand() == LLMediaBase::COMMAND_START ) + { + setStatus( LLMediaBase::STATUS_STARTED ); + clearCommand(); + }; + + if ( nextCommand() == LLMediaBase::COMMAND_STOP ) + { + setStatus( LLMediaBase::STATUS_STOPPED ); + clearCommand(); + }; + + if ( nextCommand() == LLMediaBase::COMMAND_BACK ) + { + setStatus( LLMediaBase::STATUS_STARTED ); + LLMozLib::getInstance()->navigateBack( mWindowId ); + clearCommand(); + }; + + if ( nextCommand() == LLMediaBase::COMMAND_FORWARD ) + { + setStatus( LLMediaBase::STATUS_STARTED ); + LLMozLib::getInstance()->navigateForward( mWindowId ); + clearCommand(); + }; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void LLMediaImplLLMozLib::onPageChanged( const EventType& eventIn ) +{ + // force an update when the contents of the page changes + mNeedsUpdate = true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void LLMediaImplLLMozLib::onClickLinkHref( const EventType& eventIn ) +{ + LLMediaEvent event( this, eventIn.getStringValue() ); + mEventEmitter.update( &LLMediaObserver::onClickLinkHref, event ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void LLMediaImplLLMozLib::onClickLinkNoFollow( const EventType& eventIn ) +{ + LLMediaEvent event( this, eventIn.getStringValue() ); + mEventEmitter.update( &LLMediaObserver::onClickLinkNoFollow, event ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void LLMediaImplLLMozLib::onUpdateProgress( const EventType& eventIn ) +{ + LLMediaEvent event( this, eventIn.getIntValue() ); + mEventEmitter.update( &LLMediaObserver::onUpdateProgress, event ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void LLMediaImplLLMozLib::onStatusTextChange( const EventType& eventIn ) +{ + LLMediaEvent event( this, eventIn.getStringValue() ); + mEventEmitter.update( &LLMediaObserver::onStatusTextChange, event ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void LLMediaImplLLMozLib::onLocationChange( const EventType& eventIn ) +{ + LLMediaEvent event( this, eventIn.getEventUri() ); + mEventEmitter.update( &LLMediaObserver::onLocationChange, event ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void LLMediaImplLLMozLib::onNavigateBegin( const EventType& eventIn ) +{ + LLMediaEvent event( this, eventIn.getEventUri() ); + mEventEmitter.update( &LLMediaObserver::onNavigateBegin, event ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void LLMediaImplLLMozLib::onNavigateComplete( const EventType& eventIn ) +{ + // force an update when the page is finished + mNeedsUpdate = true; + + // pass in url and HTML response code (200/404 etc.) + LLMediaEvent event( this, eventIn.getEventUri(), eventIn.getIntValue() ); + mEventEmitter.update( &LLMediaObserver::onNavigateComplete, event ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +unsigned char* LLMediaImplLLMozLib::getMediaData() +{ + return (unsigned char*)LLMozLib::getInstance()->getBrowserWindowPixels( mWindowId ); +} + +// helper func to compute size of media data +bool LLMediaImplLLMozLib::recomputeSizes() +{ + int new_width = mMediaRequestedWidth; + int new_height = mMediaRequestedHeight; + + if (new_width < 0) + new_width = 512; + + if (new_height < 0) + new_height = 512; + + if (mAutoScaled) + { + new_width = LLMediaManager::textureWidthFromMediaWidth( new_width ); + new_height = LLMediaManager::textureHeightFromMediaHeight( new_height ); + } + + bool status = LLMozLib::getInstance()->setSize( mWindowId, new_width, new_height ); + + if (status) + setMediaSize(new_width, new_height); + + return status; +} + + +//////////////////////////////////////////////////////////////////////////////// +// virtual +int LLMediaImplLLMozLib::getMediaDataWidth() const +{ + return mMediaDataWidth; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +int LLMediaImplLLMozLib::getMediaDataHeight() const +{ + return mMediaDataHeight; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::setRequestedMediaSize(int width, int height) +{ + LLMediaImplCommon::setRequestedMediaSize(width, height); + + return recomputeSizes(); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::setAutoScaled( bool auto_scaled ) +{ + LLMediaImplCommon::setAutoScaled(auto_scaled); + + return recomputeSizes(); +} + + +//////////////////////////////////////////////////////////////////////////////// +// virtual +int LLMediaImplLLMozLib::getTextureFormatPrimary() const +{ +#if defined(__APPLE__) || defined(MACOSX) + return GL_BGRA_EXT; +#else + return LLMozLib::getInstance()->getBrowserDepth( mWindowId ) == 3 ? GL_BGR_EXT : GL_BGRA_EXT; +#endif +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +int LLMediaImplLLMozLib::getTextureFormatType() const +{ +#if defined(__APPLE__) || defined(MACOSX) + #ifdef __BIG_ENDIAN__ + return GL_UNSIGNED_INT_8_8_8_8_REV; + #else + return GL_UNSIGNED_INT_8_8_8_8; + #endif +#else + return GL_UNSIGNED_BYTE; +#endif +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::mouseDown( int x_pos, int y_pos ) +{ + return LLMozLib::getInstance()->mouseDown( mWindowId, x_pos, y_pos ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::mouseUp( int x_pos, int y_pos ) +{ + LLMozLib::getInstance()->mouseUp( mWindowId, x_pos, y_pos ); + + // this seems better than sending focus on mouse down (still need to improve this) + LLMozLib::getInstance()->focusBrowser( mWindowId, true ); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::mouseMove( int x_pos, int y_pos ) +{ + return LLMozLib::getInstance()->mouseMove( mWindowId, x_pos, y_pos ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::keyPress( int key_code ) +{ + // We don't have to deal with printable characters here - they should + // go through handleUnicodeChar(). This table could be more complete + // than it is, but I think this covers all of the important + // non-printables. + + unsigned long moz_key; + + switch(key_code) + { + case LL_MEDIA_KEY_BACKSPACE: + moz_key = LL_DOM_VK_BACK_SPACE; break; + case LL_MEDIA_KEY_TAB: + moz_key = LL_DOM_VK_TAB; break; + case LL_MEDIA_KEY_RETURN: + moz_key = LL_DOM_VK_RETURN; break; + case LL_MEDIA_KEY_PAD_RETURN: + moz_key = LL_DOM_VK_ENTER; break; + case LL_MEDIA_KEY_ESCAPE: + moz_key = LL_DOM_VK_ESCAPE; break; + case LL_MEDIA_KEY_PAGE_UP: + moz_key = LL_DOM_VK_PAGE_UP; break; + case LL_MEDIA_KEY_PAGE_DOWN: + moz_key = LL_DOM_VK_PAGE_DOWN; break; + case LL_MEDIA_KEY_END: + moz_key = LL_DOM_VK_END; break; + case LL_MEDIA_KEY_HOME: + moz_key = LL_DOM_VK_HOME; break; + case LL_MEDIA_KEY_LEFT: + moz_key = LL_DOM_VK_LEFT; break; + case LL_MEDIA_KEY_UP: + moz_key = LL_DOM_VK_UP; break; + case LL_MEDIA_KEY_RIGHT: + moz_key = LL_DOM_VK_RIGHT; break; + case LL_MEDIA_KEY_DOWN: + moz_key = LL_DOM_VK_DOWN; break; + case LL_MEDIA_KEY_INSERT: + moz_key = LL_DOM_VK_INSERT; break; + case LL_MEDIA_KEY_DELETE: + moz_key = LL_DOM_VK_DELETE; break; + + default: + return false; // don't know how to map this key. + } + + return LLMozLib::getInstance()->keyPress( mWindowId, moz_key ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::scrollByLines( int lines ) +{ + return LLMozLib::getInstance()->scrollByLines(mWindowId, lines); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::focus( bool focus ) +{ + return LLMozLib::getInstance()->focusBrowser(mWindowId, focus); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::unicodeInput( unsigned long uni_char ) +{ + return LLMozLib::getInstance()->unicodeInput(mWindowId, uni_char); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::mouseLeftDoubleClick( int x_pos, int y_pos ) +{ + return LLMozLib::getInstance()->mouseLeftDoubleClick( mWindowId, x_pos, y_pos ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::navigateForward() +{ + return LLMozLib::getInstance()->navigateForward(mWindowId); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::navigateBack() +{ + return LLMozLib::getInstance()->navigateBack(mWindowId); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::canNavigateForward() +{ + return LLMozLib::getInstance()->canNavigateForward(mWindowId); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::canNavigateBack() +{ + return LLMozLib::getInstance()->canNavigateBack(mWindowId); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::enableCookies(bool enable) +{ + return LLMozLib::getInstance()->enableCookies(enable); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::enableProxy(bool enable, std::string proxy_host_name, int proxy_port) +{ + return LLMozLib::getInstance()->enableProxy(enable, proxy_host_name, proxy_port); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::clearCache() +{ + return LLMozLib::getInstance()->clearCache(); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::clearCookies() +{ + return LLMozLib::getInstance()->clearAllCookies(); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplLLMozLib::reset() +{ + LLMozLib::getInstance()->remObserver( mWindowId, this ); + + LLMozLib::getInstance()->destroyBrowserWindow( mWindowId ); + + mWindowId = 0; + + return true; +} + +#endif // LL_LLMOZLIB_ENABLED diff --git a/linden/indra/llmedia/llmediaimplllmozlib.h b/linden/indra/llmedia/llmediaimplllmozlib.h new file mode 100644 index 0000000..fc5d4e5 --- /dev/null +++ b/linden/indra/llmedia/llmediaimplllmozlib.h @@ -0,0 +1,120 @@ +/** + * @file llmediaimplllmozlib.cpp + * @brief Example 2 of a media impl concrete class + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLMEDIAIMPLLLMOZLIB_H +#define LLMEDIAIMPLLLMOZLIB_H + +#include "llmediaimplcommon.h" +#include "llmediaimplfactory.h" + +#if LL_LLMOZLIB_ENABLED + +#include "llmozlib2.h" + +class LLMediaManagerData; + +class LLMediaImplLLMozLib : + public LLMediaImplCommon, + public LLEmbeddedBrowserWindowObserver +{ + public: + LLMediaImplLLMozLib(); + + static bool startup( LLMediaManagerData* init_data ); + static bool closedown(); + + /* virtual */ bool init(); + /* virtual */ std::string getVersion(); + /* virtual */ bool set404RedirectUrl( std::string redirect_url ); + /* virtual */ bool clr404RedirectUrl(); + /* virtual */ bool setBackgroundColor( unsigned int red, unsigned int green, unsigned int blue ) const; + /* virtual */ bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue ) const; + /* virtual */ bool navigateTo( const std::string url ); + /* virtual */ bool updateMedia(); + /* virtual */ unsigned char* getMediaData(); + /* virtual */ int getMediaDataWidth() const; + /* virtual */ int getMediaDataHeight() const; + /* virtual */ bool setRequestedMediaSize(int width, int height); + /* virtual */ bool setAutoScaled( bool auto_scaled ); + /* virtual */ int getTextureFormatPrimary() const; + /* virtual */ int getTextureFormatType() const; + /* virtual */ bool mouseDown( int x_pos, int y_pos ); + /* virtual */ bool mouseUp( int x_pos, int y_pos ); + /* virtual */ bool mouseMove( int x_pos, int y_pos ); + /* virtual */ bool keyPress( int key_code ); + /* virtual */ bool scrollByLines( int lines ); + /* virtual */ bool focus( bool focus ); + /* virtual */ bool unicodeInput( unsigned long uni_char ); + /* virtual */ bool mouseLeftDoubleClick( int x_pos, int y_pos ); + /* virtual */ bool navigateForward(); + /* virtual */ bool navigateBack(); + /* virtual */ bool canNavigateForward(); + /* virtual */ bool canNavigateBack(); + /* virtual */ bool enableCookies(bool enable); + /* virtual */ bool enableProxy(bool enable, std::string proxy_host_name, int proxy_port); + /* virtual */ bool clearCache(); + /* virtual */ bool clearCookies(); + /* virtual */ bool reset(); + + // LLMozLib observerables + virtual void onNavigateBegin( const EventType& eventIn ); + virtual void onNavigateComplete( const EventType& eventIn ); + virtual void onUpdateProgress( const EventType& eventIn ); + virtual void onPageChanged( const EventType& eventIn ); + virtual void onStatusTextChange( const EventType& eventIn ); + virtual void onLocationChange( const EventType& eventIn ); + virtual void onClickLinkHref( const EventType& eventIn ); + virtual void onClickLinkNoFollow( const EventType& eventIn ); + + private: + bool recomputeSizes(); + int mWindowId; + int mBrowserWindowWidth; + int mBrowserWindowHeight; + int mMediaDataWidth; + int mMediaDataHeight; + bool mNeedsUpdate; + bool updateState(); +}; + +// The maker class +class LLMediaImplLLMozLibMaker : public LLMediaImplMaker +{ + public: + LLMediaImplLLMozLibMaker(); + LLMediaImplLLMozLib* create() + { + return new LLMediaImplLLMozLib(); + } +}; +#endif // LL_LLMOZLIB_ENABLED + +#endif // LLMEDIAIMPLLLMOZLIB_H diff --git a/linden/indra/llmedia/llmediaimplquicktime.cpp b/linden/indra/llmedia/llmediaimplquicktime.cpp index 8fcd7bf..f9a3b05 100644 --- a/linden/indra/llmedia/llmediaimplquicktime.cpp +++ b/linden/indra/llmedia/llmediaimplquicktime.cpp @@ -1,10 +1,10 @@ -/** +/** * @file llmediaimplquicktime.cpp - * @brief implementation that supports Apple QuickTime media. + * @brief QuickTime media impl concrete class * - * $LicenseInfo:firstyear=2005&license=viewergpl$ + * $LicenseInfo:firstyear=2007&license=viewergpl$ * - * Copyright (c) 2005-2008, Linden Research, Inc. + * Copyright (c) 2007-2008, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -29,382 +29,269 @@ * $/LicenseInfo$ */ -#include "linden_common.h" +#include "llmediaimplquicktime.h" #if LL_QUICKTIME_ENABLED -#include +#include "llmediamanager.h" +#include "llmediaimplregister.h" -#include "llmediaimplquicktime.h" +#if LL_WINDOWS +#include +#endif + +#include +#include -#include "llgl.h" -#include "llglheaders.h" // For gl texture modes +// register this impl with media manager factory +static LLMediaImplRegister sLLMediaImplQuickTimeReg( "LLMediaImplQuickTime", new LLMediaImplQuickTimeMaker() ); /////////////////////////////////////////////////////////////////////////////// // -LLMediaImplQuickTime:: -LLMediaImplQuickTime () : - theController ( NULL ), - currentMode ( ModeIdle ), - theGWorld ( 0 ), - theMovie ( 0 ), - mediaData ( 0 ), - loopsLeft ( 0 ), - ownBuffer ( TRUE ), - curVolume ( 0 ), - sizeChangeInProgress ( FALSE ), - initialStartDone ( FALSE ), - autoScaled ( FALSE ) +LLMediaImplQuickTimeMaker::LLMediaImplQuickTimeMaker() { -// These should probably be in the initializer list above, but that seemed uglier... -#if LL_DARWIN - // Mac OS -- gworld will be xRGB (4 byte pixels, like ARGB, but QuickDraw doesn't actually do alpha...) - mMediaDepthBytes = 4; - mTextureDepth = 4; - mTextureFormatInternal = GL_RGB8; - mTextureFormatPrimary = GL_BGRA; -#ifdef LL_BIG_ENDIAN - mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; -#else - mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8; -#endif + // Register to handle the scheme + mSchema.push_back( "rtsp" ); -#else - // Windows -- GWorld will be RGB (3 byte pixels) - mMediaDepthBytes = 3; - mTextureDepth = 3; - mTextureFormatInternal = GL_RGB8; - mTextureFormatPrimary = GL_RGB; - mTextureFormatType = GL_UNSIGNED_BYTE; -#endif -}; + // Register to handle the category + mMimeTypeCategories.push_back( "video" ); + mMimeTypeCategories.push_back( "audio" ); + mMimeTypeCategories.push_back( "image" ); +} /////////////////////////////////////////////////////////////////////////////// // -LLMediaImplQuickTime:: -~LLMediaImplQuickTime () +LLMediaImplQuickTime::LLMediaImplQuickTime() : + mMovieHandle( 0 ), + mGWorldHandle( 0 ), + mMovieController( 0 ), + mMinWidth( 32 ), + mMaxWidth( 2048 ), + mMinHeight( 32 ), + mMaxHeight( 2048 ), + mCurVolume( 0 ) { - unload(); } /////////////////////////////////////////////////////////////////////////////// // -BOOL -LLMediaImplQuickTime:: -setBuffer ( U8* bufferIn ) +LLMediaImplQuickTime::~LLMediaImplQuickTime() { - OSErr err = noErr; - - // If we're waiting for a size change, we just got one. - sizeChangeInProgress = FALSE; - - // Since we've pointed QuickTime at the old media data buffer directly, we need to be somewhat careful deleting it... - U8* oldMediaData = mediaData; - BOOL ownedMediaData = ownBuffer; -#if LL_DARWIN - GWorldPtr oldGWorld = theGWorld; -#endif - - if(bufferIn == NULL) - { - // Passing NULL to this function requests that the object allocate its own buffer. - mediaData = new unsigned char [ mMediaHeight * mMediaRowbytes ]; - ownBuffer = TRUE; - } - else - { - // Use the supplied buffer. - mediaData = bufferIn; - ownBuffer = FALSE; - } - - if(mediaData == NULL) - { - // This is bad. - llerrs << "LLMediaImplQuickTime::setBuffer: mediaData is NULL" << llendl; - // NOTE: This case doesn't clean up properly. This assert is fatal, so this isn't a huge problem, - // but if this assert is ever removed the code should be fixed to clean up correctly. - return FALSE; - } - - err = NewGWorldFromPtr ( &theGWorld, mMediaDepthBytes * 8, &movieRect, NULL, NULL, 0, (Ptr)mediaData, mMediaRowbytes); - if(err == noErr) - { - if(theMovie) - { - // tell the movie about it - SetMovieGWorld ( theMovie, theGWorld, GetGWorldDevice ( theGWorld ) ); - } - - if(theController) - { - // and tell the movie controller about it. - MCSetControllerPort(theController, theGWorld); - } + unload(); +} -#if LL_DARWIN -// NOTE: (CP) This call ultimately leads to a crash in NewGWorldFromPtr on Windows (only) -// Not calling DisposeGWorld doesn't appear to leak anything significant and stops the crash occuring. -// This will eventually be fixed but for now, leaking slightly is better than crashing. - if ( oldGWorld != NULL ) - { - // Delete the old GWorld - DisposeGWorld ( oldGWorld ); - oldGWorld = NULL; - } -#endif - } - else - { - // Hmm... this may be bad. Assert here? - llerrs << "LLMediaImplQuickTime::setBuffer: NewGWorldFromPtr failed" << llendl; - theGWorld = NULL; - return FALSE; - } - - // Delete the old media data buffer iff we owned it. - if ( ownedMediaData ) +//////////////////////////////////////////////////////////////////////////////// +// (static) super-initialization - called once at application startup +bool LLMediaImplQuickTime::startup( LLMediaManagerData* init_data ) +{ +#ifdef WIN32 + if ( InitializeQTML( 0L ) != noErr ) { - if ( oldMediaData ) - { - delete [] oldMediaData; - } - } + return false; + }; +#endif + + EnterMovies(); - // build event and emit it - - return TRUE; + return true; } -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -init () +//////////////////////////////////////////////////////////////////////////////// +// (static) super-uninitialization - called once at application closedown +bool LLMediaImplQuickTime::closedown() { - // movied to main application initialization for now because it's non-trivial and only needs to be done once - // (even though it goes against the media framework design) - //if ( InitializeQTML ( 0L ) != 0 ) - //{ - // return FALSE; - //}; - - //if ( EnterMovies () != 0 ) - //{ - // return FALSE; - //}; - - return LLMediaMovieBase::init(); + ExitMovies(); + +#ifdef WIN32 + TerminateQTML(); +#endif + + return true; } -/////////////////////////////////////////////////////////////////////////////// -// -void -LLMediaImplQuickTime:: -updateMediaSize() +//////////////////////////////////////////////////////////////////////////////// +// private +bool LLMediaImplQuickTime::load( const std::string url ) { - if((theController == NULL) && (!isQTLoaded())) - { - // The movie's not loaded enough to get info about it yet. - // Set up a dummy buffer. - movieRect.left = movieRect.top = 0; - movieRect.right = movieRect.bottom = 64; - mMediaRowbytes = mMediaDepthBytes * 64; - mMediaWidth = 64; - mMediaHeight = 64; - mTextureWidth = 64; - mTextureHeight = 64; - - return; - } - - // pick up the size of the movie - GetMovieBox ( theMovie, &movieRect ); - - // save the size of the media so consumer of media class can use it - mMediaWidth = movieRect.right - movieRect.left; - mMediaHeight = movieRect.bottom - movieRect.top; - - // Giant media could make us try to use textures bigger than the opengl implementation can handle. - // Pin the maximum X or Y dimension to 1024. - // NOTE: 1024x1024 may still hurt a lot, but it shouldn't cause opengl to flame out. - if(mMediaWidth > 1024) - { - mMediaWidth = 1024; - } - if(mMediaHeight > 1024) - { - mMediaHeight = 1024; - } - - // calculate the texture size required to hold media of this size (next power of 2 bigger) - for ( mTextureWidth = 1; mTextureWidth < mMediaWidth; mTextureWidth <<= 1 ) - { - }; + if ( url.empty() ) + return false; - for ( mTextureHeight = 1; mTextureHeight < mMediaHeight; mTextureHeight <<= 1 ) - { - }; + Handle handle = NewHandleClear( ( Size )( url.length() + 1 ) ); + if ( NULL == handle ) + return false; -// llinfos << "Media texture size will be " << mTextureWidth << " x " << mTextureHeight << llendl; - - // if autoscale is on we simply make the media & texture sizes the same and quicktime does all the hard work - if ( autoScaled ) - { - // Stretch the movie to fill the texture. - mMediaWidth = mTextureWidth; - mMediaHeight = mTextureHeight; - - // scale movie using high quality but slow algorithm. - // NOTE: this results in close to same quality as texture scaling option but with (perhaps) significant - // loss of performance (e.g. my machine, release build, frame rate goes from 92 -> 82 fps - // To revert to original behaviour, just remove the line below. - - // MBW -- There seems to be serious drop in performance above a particular size, on both low and high end machines. - // 512x256 is fine, while 512x512 is unusable. I theorize that this is due to CPU cache getting broken around that size. - if((mTextureWidth * mTextureHeight) <= (512 * 256)) - { -// llinfos << "Setting high-quality hint." << llendl; - SetMoviePlayHints ( theMovie, hintsHighQuality, hintsHighQuality ); - } - }; - - // always flip movie using quicktime (little performance impact and no loss in quality) - if ( TRUE ) - { - // Invert the movie in the Y directon to match the expected orientation of GL textures. - MatrixRecord transform; - GetMovieMatrix ( theMovie, &transform ); - - double centerX = mMediaWidth / 2.0; - double centerY = mMediaHeight / 2.0; - ScaleMatrix ( &transform, X2Fix ( 1.0 ), X2Fix ( -1.0 ), X2Fix ( centerX ), X2Fix ( centerY ) ); - - SetMovieMatrix ( theMovie, &transform ); - }; + BlockMove( url.c_str(), *handle, ( Size )( url.length() + 1 ) ); - movieRect.left = 0; - movieRect.top = 0; - movieRect.right = mMediaWidth; - movieRect.bottom = mMediaHeight; + //std::cout << "LLMediaImplQuickTime::load( " << url << " )" << std::endl; - // Calculate the rowbytes of the texture - mMediaRowbytes = mMediaWidth * mMediaDepthBytes; - - SetMovieBox(theMovie, &movieRect); + // TODO: supposed to use NewMovieFromDataParams now + OSErr err = NewMovieFromDataRef( &mMovieHandle, newMovieActive | newMovieDontInteractWithUser | newMovieAsyncOK | newMovieIdleImportOK, nil, handle, URLDataHandlerSubType ); + DisposeHandle( handle ); + if ( noErr != err ) + return false; - if(theController == NULL) - { - SetGWorld(theGWorld, NULL); - - // Create a movie controller for the movie - theController = NewMovieController(theMovie, &movieRect, mcNotVisible|mcTopLeftMovie); - - MCSetActionFilterWithRefCon(theController, myMCActionFilterProc, (long)this); - - // Allow the movie to dynamically resize (may be necessary for streaming movies to work right...) - SetMoviePlayHints(theMovie, hintsAllowDynamicResize, hintsAllowDynamicResize); - } - else - { - MCPositionController(theController, &movieRect, &movieRect, mcTopLeftMovie|mcPositionDontInvalidate); - } + // do pre-roll actions (typically fired for streaming movies but not always) + PrePrerollMovie( mMovieHandle, 0, GetMoviePreferredRate( mMovieHandle ), moviePrePrerollCompleteCallback, ( void * )this ); + + // get movie rect (and check for min/max) + Rect movie_rect; + setMovieBoxEnhanced( &movie_rect ); + + // make a new movie controller + mMovieController = NewMovieController( mMovieHandle, &movie_rect, mcNotVisible | mcTopLeftMovie ); + +#if defined(__APPLE__) || defined(MACOSX) + setMediaDepth( 4 ); +#else + setMediaDepth( 3 ); +#endif + + // tell manager about the media size + setMediaSize( movie_rect.right - movie_rect.left, movie_rect.bottom - movie_rect.top); + + // movie controller + MCSetActionFilterWithRefCon( mMovieController, mcActionFilterCallBack, ( long )this ); + + SetMoviePlayHints( mMovieHandle, hintsAllowDynamicResize, hintsAllowDynamicResize ); + + // function that gets called when a frame is drawn + SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, movieDrawingCompleteCallback, ( long )this ); + + // emit an event to say that a media source was loaded + LLMediaEvent event( this ); + mEventEmitter.update( &LLMediaObserver::onMediaLoaded, event ); + + // set up inital state + sizeChanged(); + + return true; } -/////////////////////////////////////////////////////////////////////////////// -// -void -LLMediaImplQuickTime:: -setupDummyBuffer() +//////////////////////////////////////////////////////////////////////////////// +// virtual +std::string LLMediaImplQuickTime::getVersion() { - // Used when the movie can't be drawn for some reason. This sets up a buffer that keeps callers from getting annoyed. - movieRect.left = movieRect.top = 0; - movieRect.right = movieRect.bottom = 64; - mMediaRowbytes = mMediaDepthBytes * 64; - mMediaWidth = 64; - mMediaHeight = 64; - mTextureWidth = 64; - mTextureHeight = 64; - - setBuffer ( NULL ); - - memset(mediaData, 0, mMediaRowbytes * mMediaHeight ); + long version; + Gestalt( gestaltQuickTimeVersion, &version ); + + std::ostringstream codec( "" ); + codec << "["; + codec << sLLMediaImplQuickTimeReg.getImplName(); + codec << "] - "; + codec << "QuickTime: " << std::hex << version; + + return codec.str(); } -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -load ( const LLString& urlIn ) +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplQuickTime::navigateTo( const std::string url ) { - // The movie may do things to the current port when it's created. Make sure we have a valid port set. - setupDummyBuffer(); - SetGWorld(theGWorld, NULL); - - Size mySize = ( Size ) urlIn.length () + 1; - if ( mySize == 0 ) - return FALSE; - - Handle myHandle = NewHandleClear ( mySize ); - if ( myHandle == NULL ) - return FALSE; - - BlockMove ( urlIn.c_str (), *myHandle, mySize ); - - // Might be able to make this asynchronous with (newMovieActive|newMovieAsyncOK|newMovieIdleImportOK)? - OSErr err = NewMovieFromDataRef ( &theMovie, newMovieActive|newMovieDontInteractWithUser|newMovieAsyncOK|newMovieIdleImportOK, NULL, myHandle, URLDataHandlerSubType ); - - if ( err != noErr ) - return false; + // tell engine what we're doing + setStatus( LLMediaBase::STATUS_NAVIGATING ); - // function that gets called when a frame is drawn - SetMovieDrawingCompleteProc ( theMovie, movieDrawingCallWhenChanged, myFrameDrawnCallback, ( long ) this ); - - if(isQTLoaded()) - { - updateMediaSize(); - setBuffer(NULL); - } - - // Tell the controller to play the movie. This also deals with the movie still loading. - //play(); - - return LLMediaMovieBase::load(urlIn); + // remove the movie we were looking at + unload(); + + // load the new one (no real 'go to this url' function in QT) + load( url ); + + return true; } -/////////////////////////////////////////////////////////////////////////////// -// -OSErr -LLMediaImplQuickTime:: -myFrameDrawnCallback ( Movie callbackMovie, long refCon ) +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplQuickTime::sizeChanged() { - LLMediaImplQuickTime* myQtRenderer = ( LLMediaImplQuickTime* ) refCon; - - // The gworld quicktime is playing back into is now wrapped around myQtRenderer->mediaData, - // so there's no need to copy any data here. -#if 0 - Ptr pixels = GetPixBaseAddr ( myQtRenderer->pixmapHandle ); + if ( ! mMovieHandle ) + return false; - LockPixels ( myQtRenderer->pixmapHandle ); + // sanitize size of movie + Rect movie_rect; + setMovieBoxEnhanced( &movie_rect ); - memcpy ( ( U8* ) myQtRenderer->mediaData, pixels, myQtRenderer->getMediaBufferSize () ); /* Flawfinder: ignore */ + // we need this later + int width = ( movie_rect.right - movie_rect.left ); + int height = ( movie_rect.bottom - movie_rect.top ); - UnlockPixels ( myQtRenderer->pixmapHandle ); -#endif + std::cout << "LLMEDIA> size changed to " << width << " x " << height << std::endl; + + setMediaSize( width, height ); + + // media depth won't change + int depth_bits = getMediaDepth() * 8; - myQtRenderer->bufferChanged(); + GWorldPtr old_gworld_handle = mGWorldHandle; - return 0; + if (old_gworld_handle) + { + GWorldFlags result = UpdateGWorld( &mGWorldHandle, depth_bits, &movie_rect, NULL, NULL, 0 ); + if ( gwFlagErr == result ) + { + // TODO: unrecoverable?? throw exception? return something? + return false; + } + } + else + { + OSErr result = NewGWorld( &mGWorldHandle, depth_bits, &movie_rect, NULL, NULL, keepLocal | pixelsLocked ); + if ( noErr != result ) + { + // ATODO: unrecoverable?? throw exception? return something? + return false; + } + + // clear memory in GWorld to avoid random screen visual fuzz from uninitialized texture data + if ( mGWorldHandle ) + { + PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); + unsigned char* ptr = ( unsigned char* )GetPixBaseAddr( pix_map_handle ); + memset( ptr, 0x00, height * QTGetPixMapHandleRowBytes( pix_map_handle ) ); + } + } + + // point movie at GWorld if it's new + if ( mMovieHandle && ! old_gworld_handle ) + { + SetMovieGWorld( mMovieHandle, mGWorldHandle, GetGWorldDevice ( mGWorldHandle ) ); + } + + // flip movie to match the way the client expects textures (sigh!) + MatrixRecord transform; + SetIdentityMatrix( &transform ); // transforms are additive so start from identify matrix + double scaleX = 1.0 / (double)LLMediaManager::textureWidthFromMediaWidth( width ); + double scaleY = -1.0 / (double)LLMediaManager::textureHeightFromMediaHeight( height ); + double centerX = width / 2.0; + double centerY = height / 2.0; + ScaleMatrix( &transform, X2Fix ( scaleX ), X2Fix ( scaleY ), X2Fix ( centerX ), X2Fix ( centerY ) ); + SetMovieMatrix( mMovieHandle, &transform ); + std::cout << "LLMEDIA> Flipping stream to match expected OpenGL orientation size=" << width << " x " << height << std::endl; + + // update movie controller + if ( mMovieController ) + { + MCSetControllerPort( mMovieController, mGWorldHandle ); + MCPositionController( mMovieController, &movie_rect, &movie_rect, + mcTopLeftMovie | mcPositionDontInvalidate ); + MCMovieChanged( mMovieController, mMovieHandle ); + } + + // Emit event with size change so the calling app knows about it too + LLMediaEvent event( this ); + mEventEmitter.update( &LLMediaObserver::onMediaSizeChange, event ); + + return true; } -/////////////////////////////////////////////////////////////////////////////// -Boolean -LLMediaImplQuickTime::myMCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon) +//////////////////////////////////////////////////////////////////////////////// +// static +Boolean LLMediaImplQuickTime::mcActionFilterCallBack( MovieController mc, short action, void *params, long ref ) { Boolean result = false; - LLMediaImplQuickTime *self = (LLMediaImplQuickTime*)theRefCon; - switch ( theAction ) + LLMediaImplQuickTime* self = ( LLMediaImplQuickTime* )ref; + + switch( action ) { // handle window resizing case mcActionControllerSizeChanged: @@ -423,502 +310,336 @@ LLMediaImplQuickTime::myMCActionFilterProc (MovieController theMC, short theActi break; }; - return ( result ); + return result; } -/////////////////////////////////////////////////////////////////////////////// -// -void -LLMediaImplQuickTime::rewind() +//////////////////////////////////////////////////////////////////////////////// +// private +bool LLMediaImplQuickTime::unload() { - // MBW -- XXX -- I don't see an easy way to do this via the movie controller. - GoToBeginningOfMovie ( theMovie ); - - // Call this afterwards so the movie controller can sync itself with the movie. - MCMovieChanged(theController, theMovie); - -#if 0 - // Maybe something like this? - TimeRecord when; - when.value.hi = 0; - when.value.lo = 0; - when.scale = GetMovieTimeScale(theMovie); - - // This seems like the obvious thing, but a tech note (http://developer.apple.com/technotes/qt/qt_510.html) says otherwise... -// when.base = GetMovieTimeBase(theMovie); - when.base = 0; - - MCDoAction(theController, mcActionGoToTime, &when); -#endif + if ( mMovieHandle ) + { + StopMovie( mMovieHandle ); + if ( mMovieController ) + { + MCMovieChanged( mMovieController, mMovieHandle ); + }; + }; + + if ( mMovieController ) + { + MCSetActionFilterWithRefCon( mMovieController, NULL, (long)this ); + DisposeMovieController( mMovieController ); + mMovieController = NULL; + }; + + if ( mMovieHandle ) + { + SetMovieDrawingCompleteProc( mMovieHandle, movieDrawingCallWhenChanged, nil, ( long )this ); + DisposeMovie ( mMovieHandle ); + mMovieHandle = NULL; + }; + + if ( mGWorldHandle ) + { + DisposeGWorld( mGWorldHandle ); + mGWorldHandle = NULL; + }; + + return true; } -/////////////////////////////////////////////////////////////////////////////// -// -void -LLMediaImplQuickTime::sizeChanged() +//////////////////////////////////////////////////////////////////////////////// +// static +OSErr LLMediaImplQuickTime::movieDrawingCompleteCallback( Movie call_back_movie, long ref ) { - // Set the movie to render (well, actually NOT render) to an internal buffer until the size change can be handled. - setupDummyBuffer(); - - // Make the next call to updateMedia request a size change. - sizeChangeInProgress = true; - - // Recalculate the values that depend on the movie rect. - updateMediaSize(); + LLMediaImplQuickTime* self = ( LLMediaImplQuickTime* )ref; + + // IMPORTANT: typically, a consumer who is observing this event will set a flag + // when this event is fired then render later. Be aware that the media stream + // can change during this period - dimensions, depth, format etc. + LLMediaEvent event( self ); + self->mEventEmitter.update( &LLMediaObserver::onMediaContentsChange, event ); + + return noErr; } -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -isQTLoaded() +//////////////////////////////////////////////////////////////////////////////// +// static +void LLMediaImplQuickTime::moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *ref ) { - BOOL result = false; - - if(theMovie) - { - if(GetMovieLoadState(theMovie) >= kMovieLoadStateLoaded) - { - result = true; - } - } - - return result; + LLMediaImplQuickTime* self = ( LLMediaImplQuickTime* )ref; + + LLMediaEvent event( self ); + self->mEventEmitter.update( &LLMediaObserver::onMediaPreroll, event ); } /////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -isQTPlaythroughOK() +// used for stop / loop +void LLMediaImplQuickTime::rewind() { - BOOL result = false; - - if(theMovie) - { - if(GetMovieLoadState(theMovie) >= kMovieLoadStatePlaythroughOK) - { - result = true; - } - } - - return result; + GoToBeginningOfMovie ( mMovieHandle ); + + MCMovieChanged( mMovieController, mMovieHandle ); } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // -BOOL -LLMediaImplQuickTime:: -unload () +bool LLMediaImplQuickTime::processState() { - - if( theController ) + // start stream + if ( nextCommand() == LLMediaBase::COMMAND_START ) { - // Slight paranoia... - MCSetActionFilterWithRefCon(theController, NULL, (long)this); + // valid when we are in these states + if ( getStatus() == LLMediaBase::STATUS_NAVIGATING|| getStatus() == LLMediaBase::STATUS_STOPPED || getStatus() == LLMediaBase::STATUS_PAUSED ) + { + // it appears that the movie must be in a loaded state before we do this command + if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) + { + MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate( mMovieHandle ) ); - DisposeMovieController( theController ); - theController = NULL; - }; - - if ( theMovie ) - { - // Slight paranoia... - SetMovieDrawingCompleteProc ( theMovie, movieDrawingCallWhenChanged, nil, ( long ) this ); + MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); - DisposeMovie ( theMovie ); - theMovie = NULL; - }; + setStatus( LLMediaBase::STATUS_STARTED ); - if ( theGWorld ) - { - DisposeGWorld ( theGWorld ); - theGWorld = NULL; - }; - - if ( mediaData ) + clearCommand(); + } + } + } + else + if ( nextCommand() == LLMediaBase::COMMAND_STOP ) { - if ( ownBuffer ) + // valid when we are in these states + if ( getStatus() == LLMediaBase::STATUS_NAVIGATING || getStatus() == LLMediaBase::STATUS_STARTED || getStatus() == LLMediaBase::STATUS_PAUSED ) { - delete mediaData; - mediaData = NULL; - }; - }; + // it appears that the movie must be in a loaded state before we do this command + if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) + { + // stop playing + Fixed rate = X2Fix( 0.0 ); + MCDoAction( mMovieController, mcActionPlay, (void*)rate ); - return TRUE; -} + // go back to start + rewind(); -/////////////////////////////////////////////////////////////////////////////// -// -S32 -LLMediaImplQuickTime:: -updateMedia () -{ - if(!theController) - { - if(isQTLoaded()) - { - // Movie has finished loading. Request a size change to update buffers, etc. - // We MUST update the media size here, so it will be correct before the size change request. - updateMediaSize(); - return updateMediaNeedsSizeChange; - } - else - { - // Movie is still loading. - MoviesTask ( theMovie, 0 ); - } + setStatus( LLMediaBase::STATUS_STOPPED ); + clearCommand(); + }; + }; } - - if(theController) + else + if ( nextCommand() == LLMediaBase::COMMAND_PAUSE ) { - switch(currentMode) + // valid when we are in these states + if ( getStatus() == LLMediaBase::STATUS_NAVIGATING || getStatus() == LLMediaBase::STATUS_STARTED || getStatus() == LLMediaBase::STATUS_STOPPED ) { - case ModePlaying: - case ModeLooping: - if(!initialStartDone) + // it appears that the movie must be in a loaded state before we do this command + if ( GetMovieLoadState( mMovieHandle ) >= kMovieLoadStatePlaythroughOK ) { - if(isQTPlaythroughOK()) - { - // The movie is loaded enough to start playing. Start it now. - MCDoAction(theController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate(theMovie)); + // stop playing + Fixed rate = X2Fix( 0.0 ); + MCDoAction( mMovieController, mcActionPlay, (void*)rate ); - MCDoAction(theController, mcActionSetVolume, (void*)curVolume ); + setStatus( LLMediaBase::STATUS_PAUSED ); + clearCommand(); + }; + }; + }; - initialStartDone = TRUE; - } - } - break; - } + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplQuickTime::setMovieBoxEnhanced( Rect* rect ) +{ + // get movie rect + GetMovieBox( mMovieHandle, rect ); + int width = ( rect->right - rect->left ); + int height = ( rect->bottom - rect->top ); -// // This function may copy decompressed movie frames into our media data pointer. JC -// if (!mediaData) -// { -// llwarns << "LLMediaImplQuickTime::updateMedia() about to update with null media pointer" << llendl; -// } -// else -// { -// // try writing to the pointer to see if it's valid -// *mediaData = 0; -// } - - MCIdle(theController); + // if the user has requested a specific size, use it: + if ((mMediaRequestedWidth != 0) && (mMediaRequestedHeight != 0)) + { + width = mMediaRequestedWidth; + height = mMediaRequestedHeight; } - // If we need a size change, that takes precedence. - if(sizeChangeInProgress) + // if the user has requested, resize media to exactly fit texture + if (mAutoScaled) { - return updateMediaNeedsSizeChange; + width = LLMediaManager::textureWidthFromMediaWidth( width ); + height = LLMediaManager::textureHeightFromMediaHeight( height ); } - BOOL updated = getBufferChanged(); + // make sure it falls in valid range + if ( width < mMinWidth ) + width = mMinWidth; - resetBufferChanged(); - - if(updated) - return updateMediaNeedsUpdate; + if ( width > mMaxWidth ) + width = mMaxWidth; - // don't use movie controller for looping - appears to be broken on PCs (volume issue) - if ( currentMode == ModeLooping ) - if ( IsMovieDone ( theMovie ) ) - loop ( 0 ); + if ( height < mMinHeight ) + height = mMinHeight; - return updateMediaNoChanges; -} + if ( height > mMaxHeight ) + height = mMaxHeight; -/////////////////////////////////////////////////////////////////////////////// -// -void -LLMediaImplQuickTime:: -setAutoScaled ( BOOL autoScaledIn ) -{ - autoScaled = autoScaledIn; + // tell quicktime about new size + rect->right = width; + rect->bottom = height; + rect->left = 0; + rect->top = 0; + SetMovieBox( mMovieHandle, rect ); + + return true; } -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -stop () +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplQuickTime::updateMedia() { - currentMode = ModeStopped; + if ( ! mMovieHandle ) + return false; - if(theController) - { - Fixed rate = X2Fix(0.0); - MCDoAction(theController, mcActionPlay, (void*)rate); - - rewind(); - } - - return LLMediaMovieBase::stop(); -}; + if ( ! mMovieController ) + return false; -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -play () -{ - currentMode = ModePlaying; - - if(theController) - { - if ( IsMovieDone ( theMovie ) ) - { - rewind(); - }; + if ( ! mGWorldHandle ) + return false; - MCDoAction(theController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate(theMovie)); + // service QuickTime + MoviesTask( mMovieHandle, 0 ); + MCIdle( mMovieController ); - MCDoAction(theController, mcActionSetVolume, (void*)curVolume ); - } - - return LLMediaMovieBase::play(); -}; + // update state machine (deals with transport controls for example) + processState(); -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -loop ( S32 howMany ) -{ - currentMode = ModeLooping; - - // MBW -- XXX -- This may be harder to do with a movie controller... -// loopsLeft = howMany; + // special code for looping - need to rewind at the end of the movie - if ( theController ) + if ( isLooping() ) { - // Movie is loaded and set up. - if ( IsMovieDone ( theMovie ) ) + // QT call to see if we are at the end - can't do with controller + if ( IsMovieDone( mMovieHandle ) ) { + // go back to start rewind(); - }; - - MCDoAction(theController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate(theMovie)); - - MCDoAction(theController, mcActionSetVolume, (void*)curVolume ); - } - - return LLMediaMovieBase::loop(howMany); -}; - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -pause () -{ - currentMode = ModePaused; - - if(theController) - { - // Movie is loaded and set up. - Fixed rate = X2Fix(0.0); - MCDoAction(theController, mcActionPlay, (void*)rate); - } - return LLMediaMovieBase::pause(); -}; + // kick off new play + MCDoAction( mMovieController, mcActionPrerollAndPlay, (void*)GetMoviePreferredRate( mMovieHandle ) ); -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -setVolume ( F32 volumeIn ) -{ - // Fixed point signed short, 8.8 - curVolume = (short)(volumeIn * ( F32 ) 0x100); - - if(theController != NULL) - { - MCDoAction(theController, mcActionSetVolume, (void*)curVolume); + // set the volume + MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); + } } - - return TRUE; -} -/////////////////////////////////////////////////////////////////////////////// -// -F32 -LLMediaImplQuickTime:: -getVolume () -{ - return ( ( F32 ) curVolume ) / ( F32 ) 0x100; + return true; } -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -isIdle () const +//////////////////////////////////////////////////////////////////////////////// +// virtual +unsigned char* LLMediaImplQuickTime::getMediaData() { - return ( currentMode == ModeIdle ); -}; + unsigned char* ptr = NULL; -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -isError () const -{ - return ( currentMode == ModeError ); -}; + if ( mGWorldHandle ) + { + PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -isBuffering () const -{ - return ( currentMode == ModeBuffering ); -}; + ptr = ( unsigned char* )GetPixBaseAddr( pix_map_handle ); + }; -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -isLoaded () const -{ - // Only tell the caller the movie is loaded if we've had a chance to set up the movie controller. - - return (theController != NULL); -}; + return ptr; +} -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -isPlaying () const +//////////////////////////////////////////////////////////////////////////////// +// virtual +int LLMediaImplQuickTime::getMediaDataWidth() const { - return ( currentMode == ModePlaying ); -}; + if ( mGWorldHandle ) + { + int depth = getMediaDepth(); -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -isLooping () const -{ - return ( currentMode == ModeLooping ); -}; + if (depth < 1) + depth = 1; -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -isPaused () const -{ - return ( currentMode == ModePaused ); -}; + // ALWAYS use the row bytes from the PixMap if we have a GWorld because + // sometimes it's not the same as mMediaDepth * mMediaWidth ! + PixMapHandle pix_map_handle = GetGWorldPixMap( mGWorldHandle ); + return QTGetPixMapHandleRowBytes( pix_map_handle ) / depth; + } + else + { + return LLMediaImplCommon::getMediaDataWidth(); + } +} -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -isStopped () const +//////////////////////////////////////////////////////////////////////////////// +// virtual +int LLMediaImplQuickTime::getTextureFormatPrimary() const { - return ( currentMode == ModeStopped ); -}; +#if defined(__APPLE__) || defined(MACOSX) + return LL_MEDIA_BGRA; +#else + return LL_MEDIA_RGB; +#endif +} -/////////////////////////////////////////////////////////////////////////////// -// -U8* -LLMediaImplQuickTime:: -getMediaData () +//////////////////////////////////////////////////////////////////////////////// +// virtual +int LLMediaImplQuickTime::getTextureFormatType() const { - return mediaData; +#if defined(__APPLE__) || defined(MACOSX) + #ifdef __BIG_ENDIAN__ + return LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV; + #else + return LL_MEDIA_UNSIGNED_INT_8_8_8_8; + #endif +#else + return LL_MEDIA_UNSIGNED_BYTE; +#endif } -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaImplQuickTime:: -seek ( F64 time ) +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplQuickTime::seek( double time ) { - // MBW -- XXX -- This should stash the time if theController is NULL, and seek to there when the movie's loaded. - // Do this later. - if(theController != NULL) + if ( mMovieController ) { TimeRecord when; - when.scale = GetMovieTimeScale(theMovie); + when.scale = GetMovieTimeScale( mMovieHandle ); when.base = 0; // 'time' is in (floating point) seconds. The timebase time will be in 'units', where // there are 'scale' units per second. - S64 rawTime = (S64)(time * (F64)(when.scale)); - - when.value.hi = ( SInt32 ) ( rawTime >> 32 ); - when.value.lo = ( SInt32 ) ( ( rawTime & 0x00000000FFFFFFFF ) ); - - MCDoAction(theController, mcActionGoToTime, &when); - } - - return TRUE; -} + SInt64 raw_time = ( SInt64 )( time * (double)( when.scale ) ); -/////////////////////////////////////////////////////////////////////////////// -// -F64 -LLMediaImplQuickTime:: -getTime () const -{ - F64 result = 0; - - if(theController != NULL) - { - TimeValue time; - TimeScale scale = 0; + when.value.hi = ( SInt32 )( raw_time >> 32 ); + when.value.lo = ( SInt32 )( ( raw_time & 0x00000000FFFFFFFF ) ); - time = MCGetCurrentTime(theController, &scale); - if(scale != 0) - { - result = ((F64)time) / ((F64)scale); - } + MCDoAction( mMovieController, mcActionGoToTime, &when ); + + return true; } - - return result; + + return false; } -/////////////////////////////////////////////////////////////////////////////// -// -F64 -LLMediaImplQuickTime:: -getMediaDuration () const +//////////////////////////////////////////////////////////////////////////////// +// virtual +bool LLMediaImplQuickTime::setVolume( float volume ) { - F64 result = 0; - TimeScale scale = GetMovieTimeScale(theMovie); - TimeValue duration = GetMovieDuration(theMovie); - - if(duration == kQTSUnknownDuration) - { - // Hmph. - // Return 0 in this case. - } - else if(duration == kQTSInfiniteDuration) - { - // This is the magic number for "indefinite duration", i.e. a live stream. - // Note that the docs claim this value is 0x7FFFFFF, while the symbolic constant is 0x7FFFFFFF. Go figure. - // Return 0 in this case. - } - else if(scale != 0) + mCurVolume = (short)(volume * ( double ) 0x100 ); + + if ( mMovieController ) { - // Timescale is a useful number. Convert to seconds. - result = (F64)duration; - result /= (F64)scale; - } - - return result; -} + MCDoAction( mMovieController, mcActionSetVolume, (void*)mCurVolume ); -// static since we need this before an impl is created by media manager -S32 LLMediaImplQuickTime::getVersion() -{ - S32 version; - Gestalt( gestaltQuickTimeVersion, (long*)&version ); + return true; + } - return version; + return false; } -#endif +#endif // _3DNOW_InstructionExtensions/ LL_QUICKTIME_ENABLED + diff --git a/linden/indra/llmedia/llmediaimplquicktime.h b/linden/indra/llmedia/llmediaimplquicktime.h index b170a06..de8e9e2 100644 --- a/linden/indra/llmedia/llmediaimplquicktime.h +++ b/linden/indra/llmedia/llmediaimplquicktime.h @@ -1,10 +1,10 @@ -/** +/** * @file llmediaimplquicktime.h - * @brief implementation that supports Apple QuickTime media. + * @brief QuickTime media impl concrete class * - * $LicenseInfo:firstyear=2005&license=viewergpl$ + * $LicenseInfo:firstyear=2007&license=viewergpl$ * - * Copyright (c) 2005-2008, Linden Research, Inc. + * Copyright (c) 2007-2008, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -29,111 +29,83 @@ * $/LicenseInfo$ */ -#if LL_QUICKTIME_ENABLED - -// header guard -#ifndef llmediaimplquicktime_h -#define llmediaimplquicktime_h +#ifndef LLMEDIAIMPLQUICKTIME_H +#define LLMEDIAIMPLQUICKTIME_H -#include "stdtypes.h" - -#include "llmediamoviebase.h" +#include "llmediaimplcommon.h" +#include "llmediaimplfactory.h" #if LL_QUICKTIME_ENABLED -#if LL_DARWIN -#include -#else -#include "MacTypes.h" -#include "QTML.h" -#include "Movies.h" -#include "FixMath.h" -#include "Gestalt.h" -#include "QuickTimeStreaming.h" -#endif + +#include + +// QuickTime includes +#if defined(__APPLE__) + #include +#elif defined(WIN32) + #include "MacTypes.h" + #include "QTML.h" + #include "Movies.h" + #include "QDoffscreen.h" + #include "FixMath.h" #endif +class LLMediaManagerData; -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -class LLMediaImplQuickTime: - public LLMediaMovieBase +class LLMediaImplQuickTime : + public LLMediaImplCommon { public: - LLMediaImplQuickTime (); - virtual ~LLMediaImplQuickTime (); - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // implementation of the media public interface - - // housekeeping - virtual BOOL setBuffer ( U8* bufferIn ); - virtual BOOL init (); - virtual BOOL load ( const LLString& urlIn ); - virtual BOOL unload (); - - // transport controls - virtual BOOL stop (); - virtual BOOL play (); - virtual BOOL loop ( S32 howMany ); - virtual BOOL pause (); - virtual BOOL seek ( F64 time ); - - // audio levels - virtual BOOL setVolume ( F32 volumeIn ); - virtual F32 getVolume (); - - // status - virtual BOOL isIdle () const; - virtual BOOL isBuffering () const; - virtual BOOL isError () const; - virtual BOOL isLoaded () const; - virtual BOOL isStopped () const; - virtual BOOL isPaused () const; - virtual BOOL isPlaying () const; - virtual BOOL isLooping () const; - virtual F64 getTime () const; - - // media data - virtual S32 updateMedia (); - virtual void setAutoScaled ( BOOL autoScaledIn ); - virtual U8* getMediaData (); - virtual F64 getMediaDuration () const; - - // static since we need this before an impl is created by media manager - static S32 getVersion(); + LLMediaImplQuickTime(); + virtual ~LLMediaImplQuickTime(); + + static bool startup( LLMediaManagerData* init_data ); + static bool closedown(); + + /* virtual */ std::string getVersion(); + /* virtual */ bool navigateTo( const std::string url ); + /* virtual */ bool updateMedia(); + /* virtual */ unsigned char* getMediaData(); + /* virtual */ int getMediaDataWidth() const; + /* virtual */ int getTextureFormatPrimary() const; + /* virtual */ int getTextureFormatType() const; + /* virtual */ bool seek( double time ); + /* virtual */ bool setVolume( float volume ); + + bool sizeChanged(); private: - // quicktime specific - Movie theMovie; - ComponentInstance theController; - PixMapHandle pixmapHandle; - GWorldPtr theGWorld; - Rect movieRect; - U8* mediaData; - BOOL movieLoaded; - BOOL ownBuffer; - short curVolume; - S32 loopsLeft; - - BOOL autoScaled; - BOOL sizeChangeInProgress; - BOOL initialStartDone; - BOOL isQTLoaded (); - BOOL isQTPlaythroughOK (); - void setupDummyBuffer (); - - static OSErr myFrameDrawnCallback ( Movie callbackMovie, long refCon ); - static Boolean myMCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon); - + static OSErr movieDrawingCompleteCallback( Movie call_back_movie, long ref ); + static Boolean mcActionFilterCallBack( MovieController mc, short action, void *params, long ref ); + static void moviePrePrerollCompleteCallback( Movie movie, OSErr preroll_err, void *refcon ); + + bool load( const std::string url ); + bool unload(); void rewind(); - void sizeChanged(); - void updateMediaSize(); - - enum { ModeNone, ModeIdle, ModeError, ModeBuffering, ModeLoaded, ModeStopped, ModePaused, ModePlaying, ModeLooping } currentMode; + bool processState(); + bool setMovieBoxEnhanced( Rect* rect ); + + Movie mMovieHandle; + GWorldPtr mGWorldHandle; + ComponentInstance mMovieController; + const int mMinWidth; + const int mMaxWidth; + const int mMinHeight; + const int mMaxHeight; + int mCurVolume; }; +// The maker class +class LLMediaImplQuickTimeMaker : public LLMediaImplMaker +{ + public: + LLMediaImplQuickTimeMaker(); + LLMediaImplQuickTime* create() + { + return new LLMediaImplQuickTime(); + } +}; -#endif // llmediaimplquicktime_h +#endif // LL_QUICKTIME_ENABLED -#endif +#endif // LLMEDIAIMPLQUICKTIME_H diff --git a/linden/indra/llmedia/llmediaimplregister.h b/linden/indra/llmedia/llmediaimplregister.h new file mode 100644 index 0000000..a4b802f --- /dev/null +++ b/linden/indra/llmedia/llmediaimplregister.h @@ -0,0 +1,59 @@ +/** + * @file llmediaimplregister.h + * @brief Allow impls to register themselves with the impl factory + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLIMEDIAIMPLREGISTER_H +#define LLIMEDIAIMPLREGISTER_H + +#include + +#include "llmediaimplfactory.h" + +/////////////////////////////////////////////////////////////////////////////// +// +class LLMediaImplRegister +{ + public: + LLMediaImplRegister( std::string impl_name, LLMediaImplMaker* impl_maker ) : + mImplName( impl_name ) + { + LLMediaImplFactory::getInstance()->registerImpl( impl_name, impl_maker ); + }; + + std::string getImplName() + { + return mImplName; + }; + + private: + std::string mImplName; +}; + +#endif // LLIMEDIAIMPLREGISTER_H diff --git a/linden/indra/llmedia/llmediamanager.cpp b/linden/indra/llmedia/llmediamanager.cpp new file mode 100644 index 0000000..c9b673d --- /dev/null +++ b/linden/indra/llmedia/llmediamanager.cpp @@ -0,0 +1,255 @@ +/** + * @file llmediamanager.cpp + * @brief Manages instances of media impls + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llmediamanager.h" +#include "llmediaimplfactory.h" + +#include "llmediaimplexample1.h" +#include "llmediaimplexample2.h" +#include "llmediaimplquicktime.h" +#include "llmediaimplgstreamer.h" +#include "llmediaimplllmozlib.h" + +LLMediaManager* LLMediaManager::sInstance = 0; + +//////////////////////////////////////////////////////////////////////////////// +// (private) +LLMediaManager::LLMediaManager() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +LLMediaManager::~LLMediaManager() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// (static) +void LLMediaManager::initClass( LLMediaManagerData* init_data ) +{ + if ( ! sInstance ) + sInstance = new LLMediaManager(); + + // Initialize impl classes here - this breaks the encapsulation model + // but some of the initialization takes a long time and we only want to + // do it once at app startup before any of the impls have been created + // Each impl provides a static startup method that does any initialization + // which takes a significant amount of time. + LLMediaImplExample1::startup( init_data ); + LLMediaImplExample2::startup( init_data ); + +#if LL_QUICKTIME_ENABLED + LLMediaImplQuickTime::startup( init_data ); +#endif // LL_QUICKTIME_ENABLED + +#if LL_GSTREAMER_ENABLED + LLMediaImplGStreamer::startup( init_data ); +#endif // LL_GSTREAMER_ENABLED + +#if LL_LLMOZLIB_ENABLED + LLMediaImplLLMozLib::startup( init_data ); +#endif // LL_LLMOZLIB_ENABLED +} + +//////////////////////////////////////////////////////////////////////////////// +// (static) +void LLMediaManager::updateClass() +{ + if (!sInstance) return; + + media_impl_container_t::iterator it + = sInstance->mMediaImplContainer.begin(); + media_impl_container_t::iterator end + = sInstance->mMediaImplContainer.end(); + for ( ; it != end; ++it ) + { + LLMediaBase* impl = *it; + impl->updateMedia(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// (static) +void LLMediaManager::cleanupClass() +{ + // Uninitialize impl classes here - this breaks the encapsulation model + // but some of the uninitialization takes a long time and we only want to + // do it once at app startup before any of the impls have been created. + // Each impl provides a static closedown method that does any uninitialization + // which takes a significant amount of time. + LLMediaImplExample1::closedown(); + LLMediaImplExample2::closedown(); + +#if LL_LLMOZLIB_ENABLED + LLMediaImplLLMozLib::closedown(); +#endif // LL_LLMOZLIB_ENABLED + +#if LL_QUICKTIME_ENABLED + LLMediaImplQuickTime::closedown(); +#endif // LL_QUICKTIME_ENABLED + +#if LL_GSTREAMER_ENABLED + LLMediaImplGStreamer::closedown(); +#endif // LL_QUICKTIME_ENABLED + + if ( sInstance ) + delete sInstance; + + sInstance = 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// (static) +LLMediaManager* LLMediaManager::getInstance() +{ + return sInstance; +} + +//////////////////////////////////////////////////////////////////////////////// +// +LLMediaBase* LLMediaManager::createSourceFromMimeType( std::string scheme, std::string mime_type ) +{ + + LLMediaImplMakerBase* impl_maker = LLMediaImplFactory::getInstance()->getImplMaker( scheme, mime_type ); + + // If an impl maker is return it means this media type is supported + if ( impl_maker ) + { + LLMediaBase* media_impl = impl_maker->create(); + if( media_impl ) + { + media_impl->setImplMaker( impl_maker ); + std::pair< media_impl_container_t::iterator, bool > result = + mMediaImplContainer.insert( media_impl ); + + if ( result.second ) + { + media_impl->setMimeType( mime_type ); + + media_impl->init(); + + return media_impl; + }; + }; + }; + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool LLMediaManager::destroySource( LLMediaBase* media_impl ) +{ + media_impl_container_t::iterator iter = + mMediaImplContainer.find( media_impl ); + + if ( iter != mMediaImplContainer.end() ) + { + if ( *iter ) + { + ( *iter)->reset(); + + delete ( *iter ); + + mMediaImplContainer.erase( iter ); + + return true; + }; + }; + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool LLMediaManager::addMimeTypeImplNameMap( std::string mime_type, std::string impl_name ) +{ + std::pair< mime_type_impl_name_container_t::iterator, bool > result = + mMimeTypeImplNameContainer.insert( std::make_pair( mime_type, impl_name ) ); + + return result.second; +} + +//////////////////////////////////////////////////////////////////////////////// +// +std::string LLMediaManager::getImplNameFromMimeType( std::string mime_type ) +{ + mime_type_impl_name_container_t::iterator iter = + mMimeTypeImplNameContainer.find( mime_type ); + + if ( iter != mMimeTypeImplNameContainer.end() ) + { + return ( *iter ).second; + } + else + { + return std::string( "" ); + }; +} +//////////////////////////////////////////////////////////////////////////////// +// +bool LLMediaManager::supportsMediaType( const std::string& impl_name, const std::string& scheme, const std::string& mime_type ) +{ + LLMediaImplMakerBase* impl_maker = LLMediaImplFactory::getInstance()->getImplMaker( impl_name ); + if( impl_maker ) + { + int idx1 = mime_type.find("/"); + int len = (idx1 == std::string::npos) ? 0 : idx1; + std::string category = mime_type.substr(0,len); + + return impl_maker->supportsScheme(scheme) || + impl_maker->supportsMimeType(mime_type) || + impl_maker->supportsMimeTypeCategory(category); + } + return false; +} + +// static +int LLMediaManager::textureWidthFromMediaWidth( int media_width ) +{ + int texture_width = 1; + while ( texture_width < media_width ) + { + texture_width <<= 1; + }; + return texture_width; +} + +// static +int LLMediaManager::textureHeightFromMediaHeight( int media_height ) +{ + int texture_height = 1; + while ( texture_height < media_height ) + { + texture_height <<= 1; + }; + return texture_height; +} diff --git a/linden/indra/llmedia/llmediamanager.h b/linden/indra/llmedia/llmediamanager.h new file mode 100644 index 0000000..7a2c868 --- /dev/null +++ b/linden/indra/llmedia/llmediamanager.h @@ -0,0 +1,120 @@ +/** + * @file llmediamanager.h + * @brief Manages instances of media impls + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLMEDIAMANAGER_H +#define LLMEDIAMANAGER_H + +#include +#include + +#include "llmediaimplcommon.h" + +//////////////////////////////////////////////////////////////////////////////// +// +class LLMediaManagerData +{ + public: + LLMediaManagerData() : + mBrowserParentWindow( 0 ), + mBrowserProfileDir( "" ), + mBrowserProfileName ( "" ), + mBrowserUserAgentId( "" ) + { }; + + void setBrowserApplicationDir( const std::string& browser_application_dir ) { mBrowserApplicationDir = browser_application_dir; }; + std::string& getBrowserApplicationDir() { return mBrowserApplicationDir; }; + + void setBrowserComponentDir( const std::string& browser_component_dir ) { mBrowserComponentDir = browser_component_dir; }; + std::string& getBrowserComponentDir() { return mBrowserComponentDir; }; + + void setBrowserParentWindow( void* browser_parent_window ) { mBrowserParentWindow = browser_parent_window; }; + void* getBrowserParentWindow() { return mBrowserParentWindow; }; + + void setBrowserProfileDir( const std::string& browser_profile_dir ) { mBrowserProfileDir = browser_profile_dir; }; + std::string& getBrowserProfileDir() { return mBrowserProfileDir; }; + + void setBrowserProfileName( const std::string& browser_profile_name ) { mBrowserProfileName = browser_profile_name; }; + std::string& getBrowserProfileName() { return mBrowserProfileName; }; + + void setBrowserUserAgentId( const std::string& browser_user_agent_id ) { mBrowserUserAgentId = browser_user_agent_id; }; + std::string& getBrowserUserAgentId() { return mBrowserUserAgentId; }; + + private: + void* mBrowserParentWindow; + std::string mBrowserProfileDir; + std::string mBrowserProfileName; + std::string mBrowserApplicationDir; + std::string mBrowserComponentDir; + std::string mBrowserUserAgentId; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +class LLMediaManager +{ + public: + virtual ~LLMediaManager(); + + static void initClass( LLMediaManagerData* init_data ); + static void cleanupClass(); + static LLMediaManager* getInstance(); + + // Calls update on all media sources + static void updateClass(); + + // Given an URL and mime_type, construct/destroy a playback engine for + // it (a "media impl"). + LLMediaBase* createSourceFromMimeType( std::string scheme, std::string mime_type ); + bool destroySource( LLMediaBase* media_impl ); + + // mime type to impl mapping functions + bool addMimeTypeImplNameMap( std::string mime_type, std::string impl_name ); + std::string getImplNameFromMimeType( std::string mime_type ); + + // Name accessor for querying type support + bool supportsMediaType( const std::string& impl_name, const std::string& scheme, const std::string& mime_type ); + + // convenience functions for getting suggested texture sizes to hold various size media + static int textureWidthFromMediaWidth( int media_width ); + static int textureHeightFromMediaHeight( int media_height ); + + private: + LLMediaManager(); + static LLMediaManager* sInstance; + + typedef std::set< LLMediaBase* > media_impl_container_t; + media_impl_container_t mMediaImplContainer; + + typedef std::map< std::string, std::string > mime_type_impl_name_container_t; + mime_type_impl_name_container_t mMimeTypeImplNameContainer; +}; + +#endif // LLMEDIAMANAGER_H diff --git a/linden/indra/llmedia/llmediamoviebase.cpp b/linden/indra/llmedia/llmediamoviebase.cpp deleted file mode 100644 index 87b84b9..0000000 --- a/linden/indra/llmedia/llmediamoviebase.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/** - * @file llmediamoviebase.cpp - * @brief LLMedia support - base class. - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llmediamoviebase.h" -#include "llmediaimplquicktime.h" -#include "llmediaimplgstreamer.h" - -LLMediaMovieBase::LLMediaMovieBase() -{ - -} - -/////////////////////////////////////////////////////////////////////////////// -// factory method based on explicit media type -LLMediaMovieBase* LLMediaMovieBase::make( const MediaType mediaTypeIn, S32 width_pixels, S32 height_pixels ) -{ -#if LL_QUICKTIME_ENABLED - if ( mediaTypeIn == QuickTime ) - { - return new LLMediaImplQuickTime (); - } - else -#endif -#if LL_GSTREAMER_ENABLED - if ( mediaTypeIn == QuickTime ) - { - return new LLMediaImplGStreamer (); - } - else -#endif - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -play () -{ - // build event and emit it - LLMediaEvent event ( 0, "" ); - mMediaEventEmitter.update ( &LLMediaObserver::onPlay, event ); - - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -pause () -{ - LLMediaEvent event ( 0, "" ); - mMediaEventEmitter.update ( &LLMediaObserver::onPause, event ); - - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -stop () -{ - LLMediaEvent event ( 0, "" ); - mMediaEventEmitter.update ( &LLMediaObserver::onStop, event ); - - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -loop ( S32 howMany ) -{ - return TRUE; -}; - -/////////////////////////////////////////////////////////////////////////////// -// -void LLMediaMovieBase::setAutoScaled ( BOOL autoScaledIn ) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -setVolume ( F32 volumeIn ) -{ - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -F32 -LLMediaMovieBase:: -getVolume () -{ - return ( F32 ) 0.0f; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -isIdle () const -{ - return FALSE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -isBuffering () const -{ - return FALSE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -isError () const -{ - return FALSE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -isLoaded () const -{ - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -isStopped () const -{ - return FALSE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -isPaused () const -{ - return FALSE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -isPlaying () const -{ - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -isLooping () const -{ - return FALSE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -BOOL -LLMediaMovieBase:: -seek ( F64 time ) -{ - return TRUE; -} - -/////////////////////////////////////////////////////////////////////////////// -// -F64 -LLMediaMovieBase:: -getTime () const -{ - F64 result = 0; - return result; -} - -/////////////////////////////////////////////////////////////////////////////// -// -F64 -LLMediaMovieBase:: -getMediaDuration () const -{ - F64 result = 0; - return result; -} diff --git a/linden/indra/llmedia/llmediamoviebase.h b/linden/indra/llmedia/llmediamoviebase.h deleted file mode 100644 index d763b28..0000000 --- a/linden/indra/llmedia/llmediamoviebase.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file llmediamoviebase.h - * @brief LLMedia support - intermediate base class, for media types - * that want movie-style controls (i.e play/pause and volume) - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -// header guard -#ifndef llmediamoviebase_h -#define llmediamoviebase_h - -#include "llmediabase.h" - -class LLMediaMovieBase : public LLMediaBase -{ - public: - LLMediaMovieBase (); - - // do the right thing with dtor - virtual ~LLMediaMovieBase () - { - }; - - /////////////////////////////////////////////////////////////////////////////// - // factory method based on explicit media type - static LLMediaMovieBase* make ( const MediaType mediaTypeIn, S32 width_pixels, S32 height_pixels ); - - /////////////////////////////////////////////////////////////////////////////// - // public interface: - - // transport controls - virtual BOOL stop (); - virtual BOOL play (); - virtual BOOL loop ( S32 howMany ); - virtual BOOL pause (); - virtual BOOL seek ( F64 time ); - - // audio levels - virtual BOOL setVolume ( F32 volumeIn ); - virtual F32 getVolume (); - - // status - virtual BOOL isIdle () const; - virtual BOOL isBuffering () const; - virtual BOOL isError () const; - virtual BOOL isLoaded () const; - virtual BOOL isStopped () const; - virtual BOOL isPaused () const; - virtual BOOL isPlaying () const; - virtual BOOL isLooping () const; - virtual F64 getTime () const; - - // media data - virtual void setAutoScaled ( BOOL autoScaledIn ); - virtual F64 getMediaDuration () const; -}; - - -#endif // llmediamoviebase_h diff --git a/linden/indra/llmedia/llmediaobserver.h b/linden/indra/llmedia/llmediaobserver.h new file mode 100644 index 0000000..aeb2c39 --- /dev/null +++ b/linden/indra/llmedia/llmediaobserver.h @@ -0,0 +1,103 @@ +/** + * @file llmediaobserver.h + * @brief Derrive from this class and override methods to observe events from emitter class + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLMEDIAEOBSERVER_H +#define LLMEDIAEOBSERVER_H + +class LLMediaBase; + +class LLMediaEvent +{ + public: + LLMediaEvent( LLMediaBase* subject ) : + mSubject( subject ) + { + }; + + LLMediaEvent( LLMediaBase* subject, std::string in ) : + mSubject( subject ), mStringValue(in) + { + }; + + LLMediaEvent( LLMediaBase* subject, std::string string_in, int int_in ) : + mSubject( subject ), mStringValue(string_in), mIntValue(int_in) + { + }; + + LLMediaEvent( LLMediaBase* subject, int in ) : + mSubject( subject ), mIntValue(in) + { + }; + + virtual ~LLMediaEvent() { } + + LLMediaBase* getSubject() const + { + return mSubject; + }; + + int getIntValue() const + { + return mIntValue; + } + + std::string getStringValue() const + { + return mStringValue; + } + + private: + LLMediaBase* mSubject; + int mIntValue; + std::string mStringValue; +}; + +class LLMediaObserver +{ + public: + virtual ~LLMediaObserver() {} + + typedef LLMediaEvent EventType; + virtual void onMediaPreroll( const EventType& event_in ) { } + virtual void onMediaLoaded( const EventType& event_in ) { } + virtual void onMediaSizeChange( const EventType& event_in ) { } + virtual void onMediaContentsChange( const EventType& event_in ) { } + virtual void onMediaStatusTextChange( const EventType& event_in ) { } + virtual void onNavigateBegin( const EventType& event_in ) { } + virtual void onNavigateComplete( const EventType& event_in ) { } + virtual void onUpdateProgress( const EventType& event_in ) { } + virtual void onStatusTextChange( const EventType& event_in ) { } + virtual void onLocationChange( const EventType& event_in ) { } + virtual void onClickLinkHref( const EventType& event_in ) { } + virtual void onClickLinkNoFollow( const EventType& event_in ) { } +}; + +#endif // LLMEDIAEOBSERVER_H diff --git a/linden/indra/llmedia/llmediaobservers.h b/linden/indra/llmedia/llmediaobservers.h deleted file mode 100644 index 09dd3b8..0000000 --- a/linden/indra/llmedia/llmediaobservers.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file llmediaobservers.h - * @brief LLMedia support - observer classes to be overridden. - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -// header guard -#ifndef llmediaobservers_h -#define llmediaobservers_h - -#include "llmediaemitterevents.h" - -class LLMediaObserver -{ - public: - typedef LLMediaEvent EventType; - virtual ~LLMediaObserver() {} - virtual void onInit ( const EventType& eventIn ) { } - virtual void onSetUrl ( const EventType& eventIn ) { } - virtual void onLoad ( const EventType& eventIn ) { } - virtual void onPlay ( const EventType& eventIn ) { } - virtual void onPause ( const EventType& eventIn ) { } - virtual void onStop ( const EventType& eventIn ) { } - virtual void onUnload ( const EventType& eventIn ) { } - virtual void onPopupMessage ( const EventType& eventIn ) { } -}; - - -#endif // llmediaobservers_h diff --git a/linden/indra/llmessage/llassetstorage.cpp b/linden/indra/llmessage/llassetstorage.cpp index 74b55d9..13b1525 100644 --- a/linden/indra/llmessage/llassetstorage.cpp +++ b/linden/indra/llmessage/llassetstorage.cpp @@ -53,7 +53,10 @@ #include "lltransfersourceasset.h" #include "lltransfertargetvfile.h" // For debugging +#include "llmetrics.h" + LLAssetStorage *gAssetStorage = NULL; +LLMetrics *LLAssetStorage::metric_recipient = NULL; const LLUUID CATEGORIZE_LOST_AND_FOUND_ID("00000000-0000-0000-0000-000000000010"); @@ -1279,6 +1282,8 @@ void LLAssetStorage::storeAssetData( F64 timeout) { llwarns << "storeAssetData: wrong version called" << llendl; + // LLAssetStorage metric: Virtual base call + reportMetric( LLUUID::null, asset_type, NULL, LLUUID::null, 0, MR_BAD_FUNCTION, __FILE__, __LINE__, "Illegal call to base: LLAssetStorage::storeAssetData 1" ); } // virtual @@ -1296,6 +1301,8 @@ void LLAssetStorage::storeAssetData( F64 timeout) { llwarns << "storeAssetData: wrong version called" << llendl; + // LLAssetStorage metric: Virtual base call + reportMetric( asset_id, asset_type, NULL, requesting_agent_id, 0, MR_BAD_FUNCTION, __FILE__, __LINE__, "Illegal call to base: LLAssetStorage::storeAssetData 2" ); } // virtual @@ -1312,6 +1319,8 @@ void LLAssetStorage::storeAssetData( F64 timeout) { llwarns << "storeAssetData: wrong version called" << llendl; + // LLAssetStorage metric: Virtual base call + reportMetric( asset_id, asset_type, NULL, LLUUID::null, 0, MR_BAD_FUNCTION, __FILE__, __LINE__, "Illegal call to base: LLAssetStorage::storeAssetData 3" ); } // virtual @@ -1328,6 +1337,8 @@ void LLAssetStorage::storeAssetData( F64 timeout) { llwarns << "storeAssetData: wrong version called" << llendl; + // LLAssetStorage metric: Virtual base call + reportMetric( LLUUID::null, asset_type, NULL, LLUUID::null, 0, MR_BAD_FUNCTION, __FILE__, __LINE__, "Illegal call to base: LLAssetStorage::storeAssetData 4" ); } // static @@ -1372,3 +1383,51 @@ void LLAssetStorage::dumpTempAssetData(const LLUUID& avatar_id) const // virtual void LLAssetStorage::clearTempAssetData() { } + +// static +void LLAssetStorage::reportMetric( const LLUUID& asset_id, const LLAssetType::EType asset_type, const char *filename, + const LLUUID& agent_id, S32 asset_size, EMetricResult result, + const char *file, const S32 line, const char *message ) +{ + if( !metric_recipient ) + { + llinfos << "Couldn't store LLAssetStoreage::reportMetric - no metrics_recipient" << llendl; + return; + } + + filename = filename ? filename : ""; + file = file ? file : ""; + + // Create revised message - message = "message :: file:line" + std::string new_message; //( message ); + new_message = message; // << " " << file << " " << line; + new_message += " :: "; + new_message += filename; + char line_string[16]; + sprintf( line_string, ":%d", line ); + new_message += line_string; + message = new_message.c_str(); + + // Change always_report to true if debugging... do not check it in this way + static bool always_report = false; + const char *metric_name = "LLAssetStorage::Metrics"; + + bool success = result == MR_OKAY; + + if( (!success) || always_report ) + { + LLSD stats; + stats["asset_id"] = asset_id; + stats["asset_type"] = asset_type; + stats["filename"] = filename? filename : ""; + stats["agent_id"] = agent_id; + stats["asset_size"] = (S32)asset_size; + stats["result"] = (S32)result; + + metric_recipient->recordEventDetails( metric_name, message, success, stats); + } + else + { + metric_recipient->recordEvent(metric_name, message, success); + } +} diff --git a/linden/indra/llmessage/llassetstorage.h b/linden/indra/llmessage/llassetstorage.h index b7da197..739242a 100644 --- a/linden/indra/llmessage/llassetstorage.h +++ b/linden/indra/llmessage/llassetstorage.h @@ -420,6 +420,32 @@ private: LLXferManager *xfer, LLVFS *vfs, const LLHost &upstream_host); + +protected: + enum EMetricResult + { + // Static valued enums for #dw readability - please copy this + // declaration to them on updates -- source in llassetstorage.h + MR_INVALID = -1, // Makes no sense + MR_OKAY = 0, // Success - no metric normally + MR_ZERO_SIZE = 1, // Zero size asset + MR_BAD_FUNCTION = 2, // Tried to use a virtual base (PROGRAMMER ERROR) + MR_FILE_NONEXIST = 3, // Old format store call - source file does not exist + MR_NO_FILENAME = 4, // Old format store call - source filename is NULL/0-length + MR_NO_UPSTREAM = 5, // Upstream provider is missing + MR_VFS_CORRUPTION = 6 // VFS is corrupt - too-large or mismatched stated/returned sizes + }; + + static class LLMetrics *metric_recipient; + + static void reportMetric( const LLUUID& asset_id, const LLAssetType::EType asset_type, const char *filename, + const LLUUID& agent_id, S32 asset_size, EMetricResult result, + const char *file, const S32 line, const char *message ); +public: + static void setMetricRecipient( LLMetrics *recip ) + { + metric_recipient = recip; + } }; //////////////////////////////////////////////////////////////////////// diff --git a/linden/indra/llmessage/llbuffer.h b/linden/indra/llmessage/llbuffer.h index 4089a55..34d05ae 100644 --- a/linden/indra/llmessage/llbuffer.h +++ b/linden/indra/llmessage/llbuffer.h @@ -411,6 +411,18 @@ public: S32 countAfter(S32 channel, U8* start) const; /** + * @brief Count all bytes on channel. + * + * Helper method which just calls countAfter(). + * @param channel The channel to count. + * @return Returns the number of bytes in the channel. + */ + S32 count(S32 channel) const + { + return countAfter(channel, NULL); + } + + /** * @brief Read bytes in the buffer array on the specified channel * * You should prefer iterating over segments is possible since diff --git a/linden/indra/llmessage/llcachename.cpp b/linden/indra/llmessage/llcachename.cpp index fb6ca5b..6075958 100644 --- a/linden/indra/llmessage/llcachename.cpp +++ b/linden/indra/llmessage/llcachename.cpp @@ -34,19 +34,26 @@ #include "llcachename.h" // linden library includes -#include "message.h" -#include "llrand.h" #include "lldbstrings.h" #include "llframetimer.h" #include "llhost.h" +#include "llrand.h" +#include "llsdserialize.h" #include "lluuid.h" +#include "message.h" // Constants const char* CN_WAITING = "(waiting)"; const char* CN_NOBODY = "(nobody)"; const char* CN_NONE = "(none)"; -const char* CN_HIPPOS = "(hippos)"; -const F32 HIPPO_PROBABILITY = 0.01f; + +// llsd serialization constants +static const std::string AGENTS("agents"); +static const std::string GROUPS("groups"); +static const std::string CTIME("ctime"); +static const std::string FIRST("first"); +static const std::string LAST("last"); +static const std::string NAME("name"); // We track name requests in flight for up to this long. // We won't re-request a name during this time @@ -392,73 +399,123 @@ void LLCacheName::importFile(FILE* fp) llinfos << "LLCacheName loaded " << count << " names" << llendl; } - -void LLCacheName::exportFile(FILE* fp) +bool LLCacheName::importFile(std::istream& istr) { - fprintf(fp, "version\t%d\n", CN_FILE_VERSION); + LLSD data; + if(LLSDSerialize::fromXML(data, istr) < 1) + return false; - for (Cache::iterator iter = impl.mCache.begin(), - end = impl.mCache.end(); - iter != end; iter++) + // We'll expire entries more than a week old + U32 now = (U32)time(NULL); + const U32 SECS_PER_DAY = 60 * 60 * 24; + U32 delete_before_time = now - (7 * SECS_PER_DAY); + + // iterate over the agents + S32 count = 0; + LLSD agents = data[AGENTS]; + LLSD::map_iterator iter = agents.beginMap(); + LLSD::map_iterator end = agents.endMap(); + for( ; iter != end; ++iter) { - LLCacheNameEntry* entry = iter->second; - // Only write entries for which we have valid data. - // HACK: Only write agent names. This makes the reader easier. - if ( entry->mFirstName[0] - && entry->mLastName[0]) - { - LLUUID id = iter->first; + LLUUID id((*iter).first); + LLSD agent = (*iter).second; + U32 ctime = (U32)agent[CTIME].asInteger(); + if(ctime < delete_before_time) continue; - // Trivial XOR encoding - S32 i; - for (i = 0; i < UUID_BYTES; i++) - { - id.mData[i] ^= 0x33; - } + LLCacheNameEntry* entry = new LLCacheNameEntry(); + entry->mIsGroup = false; + entry->mCreateTime = ctime; + std::string first = agent[FIRST].asString(); + first.copy(entry->mFirstName, DB_FIRST_NAME_BUF_SIZE, 0); + entry->mFirstName[llmin(first.size(),(std::string::size_type)DB_FIRST_NAME_BUF_SIZE-1)] = '\0'; + std::string last = agent[LAST].asString(); + last.copy(entry->mLastName, DB_LAST_NAME_BUF_SIZE, 0); + entry->mLastName[llmin(last.size(),(std::string::size_type)DB_LAST_NAME_BUF_SIZE-1)] = '\0'; + impl.mCache[id] = entry; + ++count; + } + llinfos << "LLCacheName loaded " << count << " agent names" << llendl; - char id_string[UUID_STR_SIZE]; /*Flawfinder:ignore*/ - id.toString(id_string); + count = 0; + LLSD groups = data[GROUPS]; + iter = groups.beginMap(); + end = groups.endMap(); + for( ; iter != end; ++iter) + { + LLUUID id((*iter).first); + LLSD group = (*iter).second; + U32 ctime = (U32)group[CTIME].asInteger(); + if(ctime < delete_before_time) continue; - // ...not a group name - fprintf(fp, "%s\t%u\t%s\t%s\n", - id_string, - entry->mCreateTime, - entry->mFirstName, - entry->mLastName); + LLCacheNameEntry* entry = new LLCacheNameEntry(); + entry->mIsGroup = true; + entry->mCreateTime = ctime; + std::string name = group[NAME].asString(); + name.copy(entry->mGroupName, DB_GROUP_NAME_BUF_SIZE, 0); + entry->mGroupName[llmin(name.size(), (std::string::size_type)DB_GROUP_NAME_BUF_SIZE-1)] = '\0'; + impl.mCache[id] = entry; + ++count; + } + llinfos << "LLCacheName loaded " << count << " group names" << llendl; + return true; +} + +void LLCacheName::exportFile(std::ostream& ostr) +{ + LLSD data; + Cache::iterator iter = impl.mCache.begin(); + Cache::iterator end = impl.mCache.end(); + for( ; iter != end; ++iter) + { + // Only write entries for which we have valid data. + LLCacheNameEntry* entry = iter->second; + if(!entry + || (NULL != strchr(entry->mFirstName, '?')) + || (NULL != strchr(entry->mGroupName, '?'))) + { + continue; + } + + // store it + LLUUID id = iter->first; + std::string id_str = id.asString(); + if(entry->mFirstName[0] && entry->mLastName[0]) + { + data[AGENTS][id_str][FIRST] = entry->mFirstName; + data[AGENTS][id_str][LAST] = entry->mLastName; + data[AGENTS][id_str][CTIME] = (S32)entry->mCreateTime; + } + else if(entry->mIsGroup && entry->mGroupName[0]) + { + data[GROUPS][id_str][NAME] = entry->mGroupName; + data[GROUPS][id_str][CTIME] = (S32)entry->mCreateTime; } } + + LLSDSerialize::toPrettyXML(data, ostr); } -BOOL LLCacheName::getName(const LLUUID& id, char* first, char* last) +BOOL LLCacheName::getName(const LLUUID& id, std::string& first, std::string& last) { if(id.isNull()) { - // The function signature needs to change to pass in the - // length of first and last. - strcpy(first, CN_NOBODY); /*Flawfinder: ignore*/ - last[0] = '\0'; + first = CN_NOBODY; + last.clear(); return FALSE; } LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache, id ); if (entry) { - // The function signature needs to change to pass in the - // length of first and last. - strcpy(first, entry->mFirstName); /*Flawfinder: ignore*/ - strcpy(last, entry->mLastName); /*Flawfinder: ignore*/ + first = entry->mFirstName; + last = entry->mLastName; return TRUE; } else { - //The function signature needs to change to pass in the - //length of first and last. - strcpy(first,(ll_frand() < HIPPO_PROBABILITY) - ? CN_HIPPOS - : CN_WAITING); - strcpy(last, ""); /*Flawfinder: ignore*/ - + first = CN_WAITING; + last.clear(); if (!impl.isRequestPending(id)) { impl.mAskNameQueue.insert(id); @@ -468,15 +525,29 @@ BOOL LLCacheName::getName(const LLUUID& id, char* first, char* last) } +BOOL LLCacheName::getFullName(const LLUUID& id, std::string& fullname) +{ + std::string first_name, last_name; + BOOL res = getName(id, first_name, last_name); + fullname = first_name + " " + last_name; + return res; +} +// *TODO: Deprecate +BOOL LLCacheName::getName(const LLUUID& id, char* first, char* last) +{ + std::string first_name, last_name; + BOOL res = getName(id, first_name, last_name); + strcpy(first, first_name.c_str()); + strcpy(last, last_name.c_str()); + return res; +} -BOOL LLCacheName::getGroupName(const LLUUID& id, char* group) +BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group) { if(id.isNull()) { - // The function signature needs to change to pass in the - // length of first and last. - strcpy(group, CN_NONE); /*Flawfinder: ignore*/ + group = CN_NONE; return FALSE; } @@ -492,16 +563,12 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, char* group) if (entry) { - // The function signature needs to change to pass in the length - // of group. - strcpy(group, entry->mGroupName); /*Flawfinder: ignore*/ + group = entry->mGroupName; return TRUE; } else { - // The function signature needs to change to pass in the length - // of first and last. - strcpy(group, CN_WAITING); /*Flawfinder: ignore*/ + group = CN_WAITING; if (!impl.isRequestPending(id)) { impl.mAskGroupQueue.insert(id); @@ -510,6 +577,16 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, char* group) } } +// *TODO: Deprecate +BOOL LLCacheName::getGroupName(const LLUUID& id, char* group) +{ + std::string group_name; + BOOL res = getGroupName(id, group_name); + strcpy(group, group_name.c_str()); + return res; +} + + // TODO: Make the cache name callback take a SINGLE std::string, // not a separate first and last name. void LLCacheName::get(const LLUUID& id, BOOL is_group, LLCacheNameCallback callback, void* user_data) @@ -884,6 +961,3 @@ void LLCacheName::Impl::handleUUIDGroupNameReply(LLMessageSystem* msg, void** us ((LLCacheName::Impl*)userData)->processUUIDReply(msg, true); } - - - diff --git a/linden/indra/llmessage/llcachename.h b/linden/indra/llmessage/llcachename.h index 5a0a0d7..26a873f 100644 --- a/linden/indra/llmessage/llcachename.h +++ b/linden/indra/llmessage/llcachename.h @@ -63,9 +63,12 @@ public: void cancelCallback(const LLUUID& id, LLCacheNameCallback callback, void* user_data = NULL); - // storing cache on disk; for viewer, in name.cache + // janky old format. Remove after a while. Phoenix. 2008-01-30 void importFile(FILE* fp); - void exportFile(FILE* fp); + + // storing cache on disk; for viewer, in name.cache + bool importFile(std::istream& istr); + void exportFile(std::ostream& ostr); // If available, copies the first and last name into the strings provided. // first must be at least DB_FIRST_NAME_BUF_SIZE characters. @@ -73,12 +76,15 @@ public: // If not available, copies the string "waiting". // Returns TRUE iff available. BOOL getName(const LLUUID& id, char* first, char* last); + BOOL getName(const LLUUID& id, std::string& first, std::string& last); + BOOL getFullName(const LLUUID& id, std::string& fullname); // If available, this method copies the group name into the string // provided. The caller must allocate at least // DB_GROUP_NAME_BUF_SIZE characters. If not available, this // method copies the string "waiting". Returns TRUE iff available. BOOL getGroupName(const LLUUID& id, char* group); + BOOL getGroupName(const LLUUID& id, std::string& group); // Call the callback with the group or avatar name. // If the data is currently available, may call the callback immediatly @@ -104,6 +110,7 @@ public: static LLString getDefaultName(); private: + class Impl; Impl& impl; }; diff --git a/linden/indra/llmessage/llcallbacklisth.h b/linden/indra/llmessage/llcallbacklisth.h deleted file mode 100644 index 9b1e403..0000000 --- a/linden/indra/llmessage/llcallbacklisth.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file llcallbacklisth.h - * @brief Like LLCallbackList but uses handles instead of pointers for - * user data - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLCALLBACKLISTH_H -#define LL_LLCALLBACKLISTH_H - -#include "doublelinkedlist.h" - -typedef void(*LLHandleCallback)(void** handle ); - -class LLCallbackNodeH; - -class LLCallbackListH -{ -protected: - class LLCallbackNodeH - { - public: - LLCallbackNodeH( LLHandleCallback cb, void** h ) : mCallback(cb), mHandle(h) {} - void call() { (*mCallback)(mHandle); } - - public: - LLHandleCallback mCallback; - void** mHandle; - }; - -public: - ~LLCallbackListH() - { mCallbackList.deleteAllData(); } - - void addFunction( LLHandleCallback func, void** handle = NULL ) // register a callback, which will be called as func(data) - { mCallbackList.addDataAtEnd( new LLCallbackNodeH( func, handle ) ); } - - BOOL containsFunction( LLHandleCallback func, void** handle = NULL ) // true if list already contains the function/data pair - { - for( LLCallbackNodeH *p = mCallbackList.getFirstData(); p; p = mCallbackList.getNextData() ) - { - if( p->mCallback == func && p->mHandle == handle) - { - return TRUE; - } - } - return FALSE; - } - - BOOL deleteFunction( LLHandleCallback func, void** handle = NULL ) // removes the first instance of this function/data pair from the list, false if not found - { - for( LLCallbackNodeH *p = mCallbackList.getFirstData(); p; p = mCallbackList.getNextData() ) - { - if( p->mCallback == func && p->mHandle == handle) - { - mCallbackList.deleteCurrentData(); - return TRUE; - } - } - return FALSE; - } - - void callFunctions() // calls all functions - { - for( LLCallbackNodeH *p = mCallbackList.getFirstData(); p; p = mCallbackList.getNextData() ) - { - p->call(); - } - } - - void deleteAllFunctions() - { mCallbackList.deleteAllData(); } - -protected: - LLDoubleLinkedList mCallbackList; -}; - -#endif // LL_LLCALLBACKLISTH_H diff --git a/linden/indra/llmessage/llcircuit.h b/linden/indra/llmessage/llcircuit.h index 3f1a46a..552b50f 100644 --- a/linden/indra/llmessage/llcircuit.h +++ b/linden/indra/llmessage/llcircuit.h @@ -37,7 +37,6 @@ #include #include "llerror.h" -#include "linked_lists.h" #include "lltimer.h" #include "timing.h" diff --git a/linden/indra/llmessage/llcurl.cpp b/linden/indra/llmessage/llcurl.cpp index 3969d18..badda64 100644 --- a/linden/indra/llmessage/llcurl.cpp +++ b/linden/indra/llmessage/llcurl.cpp @@ -2,7 +2,7 @@ * @file llcurl.h * @author Zero / Donovan * @date 2006-10-15 - * @brief Curl wrapper + * @brief Implementation of wrapper around libcurl. * * $LicenseInfo:firstyear=2006&license=viewergpl$ * @@ -31,13 +31,29 @@ * $/LicenseInfo$ */ +#if LL_WINDOWS +#define SAFE_SSL 1 +#elif LL_DARWIN +#define SAFE_SSL 1 +#else +#define SAFE_SSL 1 +#endif + #include "linden_common.h" #include "llcurl.h" +#include #include +#include +#if SAFE_SSL +#include +#endif +#include "llbufferstream.h" +#include "llstl.h" #include "llsdserialize.h" +#include "llthread.h" ////////////////////////////////////////////////////////////////////////////// /* @@ -55,40 +71,112 @@ do this. */ -using namespace std; - +////////////////////////////////////////////////////////////////////////////// + +static const S32 EASY_HANDLE_POOL_SIZE = 5; +static const S32 MULTI_PERFORM_CALL_REPEAT = 5; +static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds +static const S32 MAX_ACTIVE_REQUEST_COUNT = 100; + +// DEBUG // +S32 gCurlEasyCount = 0; +S32 gCurlMultiCount = 0; + +////////////////////////////////////////////////////////////////////////////// + +//static +std::vector LLCurl::sSSLMutex; +std::string LLCurl::sCAPath; +std::string LLCurl::sCAFile; + +//static +void LLCurl::setCAPath(const std::string& path) +{ + sCAPath = path; +} + +//static +void LLCurl::setCAFile(const std::string& file) +{ + sCAFile = file; +} + +////////////////////////////////////////////////////////////////////////////// + LLCurl::Responder::Responder() : mReferenceCount(0) { } + LLCurl::Responder::~Responder() { } // virtual -void LLCurl::Responder::error(U32 status, const std::stringstream& content) +void LLCurl::Responder::error(U32 status, const std::string& reason) { - llinfos << "LLCurl::Responder::error " << status << ": " << content.str() << llendl; + llinfos << status << ": " << reason << llendl; } // virtual -void LLCurl::Responder::result(const std::stringstream& content) +void LLCurl::Responder::result(const LLSD& content) { + llwarns << "Virtual Function not implemented" << llendl; } // virtual -void LLCurl::Responder::completed(U32 status, const std::stringstream& content) +void LLCurl::Responder::completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) { - if (200 <= status && status < 300) + if (isGoodStatus(status)) + { + LLSD content; + LLBufferStream istr(channels, buffer.get()); + LLSDSerialize::fromXML(content, istr); +/* + const S32 parseError = -1; + if(LLSDSerialize::fromXML(content, istr) == parseError) + { + mStatus = 498; + mReason = "Client Parse Error"; + } +*/ + completed(status, reason, content); + } + else if (status == 400) + { + // Get reason from buffer + char tbuf[4096]; + S32 len = 4096; + buffer->readAfter(channels.in(), NULL, (U8*)tbuf, len); + tbuf[len] = 0; + completed(status, std::string(tbuf), LLSD()); + } + else + { + completed(status, reason, LLSD()); + } +} + +// virtual +void LLCurl::Responder::completed(U32 status, const std::string& reason, const LLSD& content) +{ + if (isGoodStatus(status)) { result(content); } else { - error(status, content); + error(status, reason); } } +//virtual +void LLCurl::Responder::completedHeader(U32 status, const std::string& reason, const LLSD& content) +{ + +} namespace boost { @@ -106,226 +194,456 @@ namespace boost } }; + ////////////////////////////////////////////////////////////////////////////// -size_t -curlOutputCallback(void* data, size_t size, size_t nmemb, void* user_data) + +class LLCurl::Easy { - stringstream& output = *(stringstream*)user_data; + LOG_CLASS(Easy); + +private: + Easy(); - size_t n = size * nmemb; - output.write((const char*)data, n); - if (!((istream&)output).good()) { - std::cerr << "WHAT!?!?!? istream side bad" << std::endl; - } - if (!((ostream&)output).good()) { - std::cerr << "WHAT!?!?!? ostream side bad" << std::endl; - } +public: + static Easy* getEasy(); + ~Easy(); - return n; -} + CURL* getCurlHandle() const { return mCurlEasyHandle; } -// Only used if request contained a body (post or put), Not currently implemented. -// size_t -// curlRequestCallback(void* data, size_t size, size_t nmemb, void* user_data) -// { -// stringstream& request = *(stringstream*)user_data; + void setErrorBuffer(); + void setCA(); -// size_t n = size * nmemb; -// request.read((char*)data, n); -// return request.gcount(); -// } - + void setopt(CURLoption option, S32 value); + // These assume the setter does not free value! + void setopt(CURLoption option, void* value); + void setopt(CURLoption option, char* value); + // Copies the string so that it is gauranteed to stick around + void setoptString(CURLoption option, const std::string& value); + + void slist_append(const char* str); + void setHeaders(); + + U32 report(CURLcode); + void getTransferInfo(LLCurl::TransferInfo* info); + void prepRequest(const std::string& url, ResponderPtr, bool post = false); + + const char* getErrorBuffer(); + std::stringstream& getInput() { return mInput; } + std::stringstream& getHeaderOutput() { return mHeaderOutput; } + LLIOPipe::buffer_ptr_t& getOutput() { return mOutput; } + const LLChannelDescriptors& getChannels() { return mChannels; } + + void resetState(); +private: + CURL* mCurlEasyHandle; + struct curl_slist* mHeaders; + + std::stringstream mRequest; + LLChannelDescriptors mChannels; + LLIOPipe::buffer_ptr_t mOutput; + std::stringstream mInput; + std::stringstream mHeaderOutput; + char mErrorBuffer[CURL_ERROR_SIZE]; + + // Note: char*'s not strings since we pass pointers to curl + std::vector mStrings; + + ResponderPtr mResponder; +}; LLCurl::Easy::Easy() + : mHeaders(NULL), + mCurlEasyHandle(NULL) { - mHeaders = 0; - mHeaders = curl_slist_append(mHeaders, "Connection: keep-alive"); - mHeaders = curl_slist_append(mHeaders, "Keep-alive: 300"); - mHeaders = curl_slist_append(mHeaders, "Content-Type: application/xml"); - // FIXME: shouldn't be there for GET/DELETE - // FIXME: should have ACCEPT headers - - mHandle = curl_easy_init(); + mErrorBuffer[0] = 0; +} + +LLCurl::Easy* LLCurl::Easy::getEasy() +{ + Easy* easy = new Easy(); + easy->mCurlEasyHandle = curl_easy_init(); + if (!easy->mCurlEasyHandle) + { + // this can happen if we have too many open files (fails in c-ares/ares_init.c) + llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl; + delete easy; + return NULL; + } + ++gCurlEasyCount; + return easy; } LLCurl::Easy::~Easy() { - curl_easy_cleanup(mHandle); + curl_easy_cleanup(mCurlEasyHandle); + --gCurlEasyCount; curl_slist_free_all(mHeaders); + for_each(mStrings.begin(), mStrings.end(), DeletePointer()); } -void -LLCurl::Easy::get(const string& url, ResponderPtr responder) +void LLCurl::Easy::resetState() { - prep(url, responder); - curl_easy_setopt(mHandle, CURLOPT_HTTPGET, 1); + curl_easy_reset(mCurlEasyHandle); + + if (mHeaders) + { + curl_slist_free_all(mHeaders); + mHeaders = NULL; + } + + mRequest.str(""); + mRequest.clear(); + + mOutput.reset(); + + mInput.str(""); + mInput.clear(); + + mErrorBuffer[0] = 0; + + mHeaderOutput.str(""); + mHeaderOutput.clear(); } -void -LLCurl::Easy::getByteRange(const string& url, S32 offset, S32 length, ResponderPtr responder) +void LLCurl::Easy::setErrorBuffer() { - mRange = llformat("Range: bytes=%d-%d", offset,offset+length-1); - mHeaders = curl_slist_append(mHeaders, mRange.c_str()); - prep(url, responder); - curl_easy_setopt(mHandle, CURLOPT_HTTPGET, 1); + setopt(CURLOPT_ERRORBUFFER, &mErrorBuffer); } -void -LLCurl::Easy::perform() +const char* LLCurl::Easy::getErrorBuffer() { - report(curl_easy_perform(mHandle)); + return mErrorBuffer; } -void -LLCurl::Easy::prep(const std::string& url, ResponderPtr responder) +void LLCurl::Easy::setCA() { -#if !LL_DARWIN - curl_easy_reset(mHandle); // SJB: doesn't exisit on OSX 10.3.9 -#else - // SJB: equivalent? fast? - curl_easy_cleanup(mHandle); - mHandle = curl_easy_init(); -#endif - - curl_easy_setopt(mHandle, CURLOPT_PRIVATE, this); - -// curl_easy_setopt(mHandle, CURLOPT_VERBOSE, 1); // usefull for debugging - curl_easy_setopt(mHandle, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(mHandle, CURLOPT_WRITEFUNCTION, &curlOutputCallback); - curl_easy_setopt(mHandle, CURLOPT_WRITEDATA, &mOutput); -#if 1 // For debug - curl_easy_setopt(mHandle, CURLOPT_HEADERFUNCTION, &curlOutputCallback); - curl_easy_setopt(mHandle, CURLOPT_HEADERDATA, &mHeaderOutput); -#endif - curl_easy_setopt(mHandle, CURLOPT_ERRORBUFFER, &mErrorBuffer); - curl_easy_setopt(mHandle, CURLOPT_ENCODING, ""); - curl_easy_setopt(mHandle, CURLOPT_SSL_VERIFYPEER, false); - curl_easy_setopt(mHandle, CURLOPT_HTTPHEADER, mHeaders); - - mOutput.str(""); - if (!((istream&)mOutput).good()) { - std::cerr << "WHAT!?!?!? istream side bad" << std::endl; + if(!sCAPath.empty()) + { + setoptString(CURLOPT_CAPATH, sCAPath); } - if (!((ostream&)mOutput).good()) { - std::cerr << "WHAT!?!?!? ostream side bad" << std::endl; + if(!sCAFile.empty()) + { + setoptString(CURLOPT_CAINFO, sCAFile); } +} - mURL = url; - curl_easy_setopt(mHandle, CURLOPT_URL, mURL.c_str()); +void LLCurl::Easy::setHeaders() +{ + setopt(CURLOPT_HTTPHEADER, mHeaders); +} - mResponder = responder; +void LLCurl::Easy::getTransferInfo(LLCurl::TransferInfo* info) +{ + curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SIZE_DOWNLOAD, &info->mSizeDownload); + curl_easy_getinfo(mCurlEasyHandle, CURLINFO_TOTAL_TIME, &info->mTotalTime); + curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SPEED_DOWNLOAD, &info->mSpeedDownload); } -void -LLCurl::Easy::report(CURLcode code) +U32 LLCurl::Easy::report(CURLcode code) { - if (!mResponder) return; - - long responseCode; + U32 responseCode = 0; + std::string responseReason; if (code == CURLE_OK) { - curl_easy_getinfo(mHandle, CURLINFO_RESPONSE_CODE, &responseCode); + curl_easy_getinfo(mCurlEasyHandle, CURLINFO_RESPONSE_CODE, &responseCode); + //*TODO: get reason from first line of mHeaderOutput } else { responseCode = 499; + responseReason = strerror(code) + " : " + mErrorBuffer; + } + + if (mResponder) + { + mResponder->completedRaw(responseCode, responseReason, mChannels, mOutput); + mResponder = NULL; } - mResponder->completed(responseCode, mOutput); - mResponder = NULL; + resetState(); + return responseCode; } +// Note: these all assume the caller tracks the value (i.e. keeps it persistant) +void LLCurl::Easy::setopt(CURLoption option, S32 value) +{ + curl_easy_setopt(mCurlEasyHandle, option, value); +} +void LLCurl::Easy::setopt(CURLoption option, void* value) +{ + curl_easy_setopt(mCurlEasyHandle, option, value); +} +void LLCurl::Easy::setopt(CURLoption option, char* value) +{ + curl_easy_setopt(mCurlEasyHandle, option, value); +} +// Note: this copies the string so that the caller does not have to keep it around +void LLCurl::Easy::setoptString(CURLoption option, const std::string& value) +{ + char* tstring = new char[value.length()+1]; + strcpy(tstring, value.c_str()); + mStrings.push_back(tstring); + curl_easy_setopt(mCurlEasyHandle, option, tstring); +} +void LLCurl::Easy::slist_append(const char* str) +{ + mHeaders = curl_slist_append(mHeaders, str); +} -LLCurl::Multi::Multi() +size_t curlReadCallback(char* data, size_t size, size_t nmemb, void* user_data) { - mHandle = curl_multi_init(); + LLCurl::Easy* easy = (LLCurl::Easy*)user_data; + + S32 n = size * nmemb; + S32 startpos = easy->getInput().tellg(); + easy->getInput().seekg(0, std::ios::end); + S32 endpos = easy->getInput().tellg(); + easy->getInput().seekg(startpos, std::ios::beg); + S32 maxn = endpos - startpos; + n = llmin(n, maxn); + easy->getInput().read((char*)data, n); + + return n; } -LLCurl::Multi::~Multi() +size_t curlWriteCallback(char* data, size_t size, size_t nmemb, void* user_data) { - // FIXME: should clean up excess handles in mFreeEasy - curl_multi_cleanup(mHandle); + LLCurl::Easy* easy = (LLCurl::Easy*)user_data; + + S32 n = size * nmemb; + easy->getOutput()->append(easy->getChannels().in(), (const U8*)data, n); + + return n; } +size_t curlHeaderCallback(void* data, size_t size, size_t nmemb, void* user_data) +{ + LLCurl::Easy* easy = (LLCurl::Easy*)user_data; + + size_t n = size * nmemb; + easy->getHeaderOutput().write((const char*)data, n); -void -LLCurl::Multi::get(const std::string& url, ResponderPtr responder) + return n; +} + +void LLCurl::Easy::prepRequest(const std::string& url, ResponderPtr responder, bool post) { - LLCurl::Easy* easy = easyAlloc(); - easy->get(url, responder); - curl_multi_add_handle(mHandle, easy->mHandle); + resetState(); + + if (post) setoptString(CURLOPT_ENCODING, ""); + +// setopt(CURLOPT_VERBOSE, 1); // usefull for debugging + setopt(CURLOPT_NOSIGNAL, 1); + + mOutput.reset(new LLBufferArray); + setopt(CURLOPT_WRITEFUNCTION, (void*)&curlWriteCallback); + setopt(CURLOPT_WRITEDATA, (void*)this); + + setopt(CURLOPT_READFUNCTION, (void*)&curlReadCallback); + setopt(CURLOPT_READDATA, (void*)this); + + setopt(CURLOPT_HEADERFUNCTION, (void*)&curlHeaderCallback); + setopt(CURLOPT_HEADERDATA, (void*)this); + + setErrorBuffer(); + setCA(); + + setopt(CURLOPT_SSL_VERIFYPEER, true); + setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT); + + setoptString(CURLOPT_URL, url); + + mResponder = responder; + + if (!post) + { + slist_append("Connection: keep-alive"); + slist_append("Keep-alive: 300"); + } + // *FIX: should have ACCEPT headers } + +//////////////////////////////////////////////////////////////////////////// + +class LLCurl::Multi +{ + LOG_CLASS(Multi); +public: + + Multi(); + ~Multi(); + + Easy* allocEasy(); + bool addEasy(Easy* easy); -void -LLCurl::Multi::getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr responder) + void removeEasy(Easy* easy); + + S32 process(); + S32 perform(); + + CURLMsg* info_read(S32* msgs_in_queue); + + S32 mQueued; + S32 mErrorCount; + +private: + void easyFree(Easy*); + + CURLM* mCurlMultiHandle; + + typedef std::set easy_active_list_t; + easy_active_list_t mEasyActiveList; + typedef std::map easy_active_map_t; + easy_active_map_t mEasyActiveMap; + typedef std::set easy_free_list_t; + easy_free_list_t mEasyFreeList; +}; + +LLCurl::Multi::Multi() + : mQueued(0), + mErrorCount(0) { - LLCurl::Easy* easy = easyAlloc(); - easy->getByteRange(url, offset, length, responder); - curl_multi_add_handle(mHandle, easy->mHandle); + mCurlMultiHandle = curl_multi_init(); + if (!mCurlMultiHandle) + { + llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl; + mCurlMultiHandle = curl_multi_init(); + } + llassert_always(mCurlMultiHandle); + ++gCurlMultiCount; } + +LLCurl::Multi::~Multi() +{ + // Clean up active + for(easy_active_list_t::iterator iter = mEasyActiveList.begin(); + iter != mEasyActiveList.end(); ++iter) + { + Easy* easy = *iter; + curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()); + delete easy; + } + mEasyActiveList.clear(); + mEasyActiveMap.clear(); -void -LLCurl::Multi::process() + // Clean up freed + for_each(mEasyFreeList.begin(), mEasyFreeList.end(), DeletePointer()); + mEasyFreeList.clear(); + + curl_multi_cleanup(mCurlMultiHandle); + --gCurlMultiCount; +} + +CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) { - int count; - for (int call_count = 0; call_count < 5; call_count += 1) + CURLMsg* curlmsg = curl_multi_info_read(mCurlMultiHandle, msgs_in_queue); + return curlmsg; +} + + +S32 LLCurl::Multi::perform() +{ + S32 q = 0; + for (S32 call_count = 0; + call_count < MULTI_PERFORM_CALL_REPEAT; + call_count += 1) { - if (CURLM_CALL_MULTI_PERFORM != curl_multi_perform(mHandle, &count)) + CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); + if (CURLM_CALL_MULTI_PERFORM != code || q == 0) { break; } } - + mQueued = q; + return q; +} + +S32 LLCurl::Multi::process() +{ + perform(); + CURLMsg* msg; int msgs_in_queue; - while ((msg = curl_multi_info_read(mHandle, &msgs_in_queue))) + + S32 processed = 0; + while ((msg = info_read(&msgs_in_queue))) { - if (msg->msg != CURLMSG_DONE) continue; - Easy* easy = 0; - curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &easy); - if (!easy) continue; - easy->report(msg->data.result); - - curl_multi_remove_handle(mHandle, easy->mHandle); - easyFree(easy); + ++processed; + if (msg->msg == CURLMSG_DONE) + { + U32 response = 0; + easy_active_map_t::iterator iter = mEasyActiveMap.find(msg->easy_handle); + if (iter != mEasyActiveMap.end()) + { + Easy* easy = iter->second; + response = easy->report(msg->data.result); + removeEasy(easy); + } + else + { + response = 499; + //*TODO: change to llwarns + llerrs << "cleaned up curl request completed!" << llendl; + } + if (response >= 400) + { + // failure of some sort, inc mErrorCount for debugging and flagging multi for destruction + ++mErrorCount; + } + } } + return processed; } - - -LLCurl::Easy* -LLCurl::Multi::easyAlloc() +LLCurl::Easy* LLCurl::Multi::allocEasy() { Easy* easy = 0; - - if (mFreeEasy.empty()) + + if (mEasyFreeList.empty()) { - easy = new Easy(); + easy = Easy::getEasy(); } else { - easy = mFreeEasy.back(); - mFreeEasy.pop_back(); + easy = *(mEasyFreeList.begin()); + mEasyFreeList.erase(easy); + } + if (easy) + { + mEasyActiveList.insert(easy); + mEasyActiveMap[easy->getCurlHandle()] = easy; } - return easy; } -void -LLCurl::Multi::easyFree(Easy* easy) +bool LLCurl::Multi::addEasy(Easy* easy) { - if (mFreeEasy.size() < 5) + CURLMcode mcode = curl_multi_add_handle(mCurlMultiHandle, easy->getCurlHandle()); + if (mcode != CURLM_OK) { - mFreeEasy.push_back(easy); + llwarns << "Curl Error: " << curl_multi_strerror(mcode) << llendl; + return false; + } + return true; +} + +void LLCurl::Multi::easyFree(Easy* easy) +{ + mEasyActiveList.erase(easy); + mEasyActiveMap.erase(easy->getCurlHandle()); + if (mEasyFreeList.size() < EASY_HANDLE_POOL_SIZE) + { + easy->resetState(); + mEasyFreeList.insert(easy); } else { @@ -333,53 +651,371 @@ LLCurl::Multi::easyFree(Easy* easy) } } +void LLCurl::Multi::removeEasy(Easy* easy) +{ + curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()); + easyFree(easy); +} + +//static +std::string LLCurl::strerror(CURLcode errorcode) +{ +#if LL_DARWIN + // curl_easy_strerror was added in libcurl 7.12.0. Unfortunately, the version in the Mac OS X 10.3.9 SDK is 7.10.2... + // There's a problem with the custom curl headers in our build that keeps me from #ifdefing this on the libcurl version number + // (the correct check would be #if LIBCURL_VERSION_NUM >= 0x070c00). We'll fix the header problem soon, but for now + // just punt and print the numeric error code on the Mac. + return llformat("%d", errorcode); +#else // LL_DARWIN + return std::string(curl_easy_strerror(errorcode)); +#endif // LL_DARWIN +} + +//////////////////////////////////////////////////////////////////////////// +// For generating a simple request for data +// using one multi and one easy per request + +LLCurlRequest::LLCurlRequest() + : mActiveMulti(NULL) +{ +} + +LLCurlRequest::~LLCurlRequest() +{ + for_each(mMultiSet.begin(), mMultiSet.end(), DeletePointer()); +} + +void LLCurlRequest::addMulti() +{ + LLCurl::Multi* multi = new LLCurl::Multi(); + mMultiSet.insert(multi); + mActiveMulti = multi; + mActiveRequestCount = 0; +} + +LLCurl::Easy* LLCurlRequest::allocEasy() +{ + if (!mActiveMulti || + mActiveRequestCount >= MAX_ACTIVE_REQUEST_COUNT || + mActiveMulti->mErrorCount > 0) + { + addMulti(); + } + llassert_always(mActiveMulti); + ++mActiveRequestCount; + LLCurl::Easy* easy = mActiveMulti->allocEasy(); + return easy; +} + +bool LLCurlRequest::addEasy(LLCurl::Easy* easy) +{ + llassert_always(mActiveMulti); + bool res = mActiveMulti->addEasy(easy); + return res; +} +void LLCurlRequest::get(const std::string& url, LLCurl::ResponderPtr responder) +{ + getByteRange(url, 0, -1, responder); +} + +bool LLCurlRequest::getByteRange(const std::string& url, S32 offset, S32 length, LLCurl::ResponderPtr responder) +{ + LLCurl::Easy* easy = allocEasy(); + if (!easy) + { + return false; + } + easy->prepRequest(url, responder); + easy->setopt(CURLOPT_HTTPGET, 1); + if (length > 0) + { + std::string range = llformat("Range: bytes=%d-%d", offset,offset+length-1); + easy->slist_append(range.c_str()); + } + easy->setHeaders(); + bool res = addEasy(easy); + return res; +} -namespace +bool LLCurlRequest::post(const std::string& url, const LLSD& data, LLCurl::ResponderPtr responder) { - static LLCurl::Multi* sMainMulti = 0; + LLCurl::Easy* easy = allocEasy(); + if (!easy) + { + return false; + } + easy->prepRequest(url, responder); + + LLSDSerialize::toXML(data, easy->getInput()); + S32 bytes = easy->getInput().str().length(); + + easy->setopt(CURLOPT_POST, 1); + easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL); + easy->setopt(CURLOPT_POSTFIELDSIZE, bytes); + + easy->slist_append("Content-Type: application/xml"); + easy->setHeaders(); + + lldebugs << "POSTING: " << bytes << " bytes." << llendl; + bool res = addEasy(easy); + return res; +} - LLCurl::Multi* - mainMulti() +// Note: call once per frame +S32 LLCurlRequest::process() +{ + S32 res = 0; + for (curlmulti_set_t::iterator iter = mMultiSet.begin(); + iter != mMultiSet.end(); ) { - if (!sMainMulti) { - sMainMulti = new LLCurl::Multi(); + curlmulti_set_t::iterator curiter = iter++; + LLCurl::Multi* multi = *curiter; + S32 tres = multi->process(); + res += tres; + if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0) + { + mMultiSet.erase(curiter); + delete multi; } - return sMainMulti; } + return res; +} - void freeMulti() +S32 LLCurlRequest::getQueued() +{ + S32 queued = 0; + for (curlmulti_set_t::iterator iter = mMultiSet.begin(); + iter != mMultiSet.end(); ) { - delete sMainMulti; - sMainMulti = NULL; + curlmulti_set_t::iterator curiter = iter++; + LLCurl::Multi* multi = *curiter; + queued += multi->mQueued; } + return queued; } -void -LLCurl::get(const std::string& url, ResponderPtr responder) +//////////////////////////////////////////////////////////////////////////// +// For generating one easy request +// associated with a single multi request + +LLCurlEasyRequest::LLCurlEasyRequest() + : mRequestSent(false), + mResultReturned(false) { - mainMulti()->get(url, responder); + mMulti = new LLCurl::Multi(); + mEasy = mMulti->allocEasy(); + if (mEasy) + { + mEasy->setErrorBuffer(); + mEasy->setCA(); + } } - -void -LLCurl::getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr responder) + +LLCurlEasyRequest::~LLCurlEasyRequest() { - mainMulti()->getByteRange(url, offset, length, responder); + delete mMulti; } -void LLCurl::initClass() +void LLCurlEasyRequest::setopt(CURLoption option, S32 value) { - curl_global_init(CURL_GLOBAL_ALL); + if (mEasy) + { + mEasy->setopt(option, value); + } } -void -LLCurl::process() +void LLCurlEasyRequest::setoptString(CURLoption option, const std::string& value) { - mainMulti()->process(); + if (mEasy) + { + mEasy->setoptString(option, value); + } } -void LLCurl::cleanup() +void LLCurlEasyRequest::setPost(char* postdata, S32 size) { - freeMulti(); + if (mEasy) + { + mEasy->setopt(CURLOPT_POST, 1); + mEasy->setopt(CURLOPT_POSTFIELDS, postdata); + mEasy->setopt(CURLOPT_POSTFIELDSIZE, size); + } +} + +void LLCurlEasyRequest::setHeaderCallback(curl_header_callback callback, void* userdata) +{ + if (mEasy) + { + mEasy->setopt(CURLOPT_HEADERFUNCTION, (void*)callback); + mEasy->setopt(CURLOPT_HEADERDATA, userdata); // aka CURLOPT_WRITEHEADER + } +} + +void LLCurlEasyRequest::setWriteCallback(curl_write_callback callback, void* userdata) +{ + if (mEasy) + { + mEasy->setopt(CURLOPT_WRITEFUNCTION, (void*)callback); + mEasy->setopt(CURLOPT_WRITEDATA, userdata); + } +} + +void LLCurlEasyRequest::setReadCallback(curl_read_callback callback, void* userdata) +{ + if (mEasy) + { + mEasy->setopt(CURLOPT_READFUNCTION, (void*)callback); + mEasy->setopt(CURLOPT_READDATA, userdata); + } +} + +void LLCurlEasyRequest::slist_append(const char* str) +{ + if (mEasy) + { + mEasy->slist_append(str); + } +} + +void LLCurlEasyRequest::sendRequest(const std::string& url) +{ + llassert_always(!mRequestSent); + mRequestSent = true; + if (mEasy) + { + mEasy->setHeaders(); + mEasy->setoptString(CURLOPT_URL, url); + mMulti->addEasy(mEasy); + } +} + +void LLCurlEasyRequest::requestComplete() +{ + llassert_always(mRequestSent); + mRequestSent = false; + if (mEasy) + { + mMulti->removeEasy(mEasy); + } +} + +S32 LLCurlEasyRequest::perform() +{ + return mMulti->perform(); +} + +// Usage: Call getRestult until it returns false (no more messages) +bool LLCurlEasyRequest::getResult(CURLcode* result, LLCurl::TransferInfo* info) +{ + if (!mEasy) + { + // Special case - we failed to initialize a curl_easy (can happen if too many open files) + // Act as though the request failed to connect + if (mResultReturned) + { + return false; + } + else + { + *result = CURLE_FAILED_INIT; + mResultReturned = true; + return true; + } + } + // In theory, info_read might return a message with a status other than CURLMSG_DONE + // In practice for all messages returned, msg == CURLMSG_DONE + // Ignore other messages just in case + while(1) + { + S32 q; + CURLMsg* curlmsg = info_read(&q, info); + if (curlmsg) + { + if (curlmsg->msg == CURLMSG_DONE) + { + *result = curlmsg->data.result; + return true; + } + // else continue + } + else + { + return false; + } + } +} + +// private +CURLMsg* LLCurlEasyRequest::info_read(S32* q, LLCurl::TransferInfo* info) +{ + if (mEasy) + { + CURLMsg* curlmsg = mMulti->info_read(q); + if (curlmsg && curlmsg->msg == CURLMSG_DONE) + { + if (info) + { + mEasy->getTransferInfo(info); + } + } + return curlmsg; + } + return NULL; +} + +std::string LLCurlEasyRequest::getErrorString() +{ + return mEasy ? std::string(mEasy->getErrorBuffer()) : std::string(); +} + +//////////////////////////////////////////////////////////////////////////// + +#if SAFE_SSL +//static +void LLCurl::ssl_locking_callback(int mode, int type, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) + { + LLCurl::sSSLMutex[type]->lock(); + } + else + { + LLCurl::sSSLMutex[type]->unlock(); + } +} + +//static +unsigned long LLCurl::ssl_thread_id(void) +{ + return LLThread::currentID(); +} +#endif + +void LLCurl::initClass() +{ + // Do not change this "unless you are familiar with and mean to control + // internal operations of libcurl" + // - http://curl.haxx.se/libcurl/c/curl_global_init.html + curl_global_init(CURL_GLOBAL_ALL); + +#if SAFE_SSL + S32 mutex_count = CRYPTO_num_locks(); + for (S32 i=0; i #include -#include +#include // TODO: remove dependency -// #include "llhttpclient.h" +#include "llbuffer.h" +#include "lliopipe.h" +#include "llsd.h" + +class LLMutex; + +// For whatever reason, this is not typedef'd in curl.h +typedef size_t (*curl_header_callback)(void *ptr, size_t size, size_t nmemb, void *stream); class LLCurl { + LOG_CLASS(LLCurl); + public: + class Easy; class Multi; + struct TransferInfo + { + TransferInfo() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {} + F64 mSizeDownload; + F64 mTotalTime; + F64 mSpeedDownload; + }; + class Responder { + //LOG_CLASS(Responder); public: + Responder(); virtual ~Responder(); - virtual void error(U32 status, const std::stringstream& content); // called with bad status codes + /** + * @brief return true if the status code indicates success. + */ + static bool isGoodStatus(U32 status) + { + return((200 <= status) && (status < 300)); + } + + virtual void error(U32 status, const std::string& reason); + // called with non-200 status codes - virtual void result(const std::stringstream& content); + virtual void result(const LLSD& content); - virtual void completed(U32 status, const std::stringstream& content); + // Override point for clients that may want to use this class when the response is some other format besides LLSD + virtual void completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer); + + virtual void completed(U32 status, const std::string& reason, const LLSD& content); /**< The default implemetnation calls either: * result(), or * error() */ + // Override to handle parsing of the header only. Note: this is the only place where the contents + // of the header can be parsed. In the ::completed call above only the body is contained in the LLSD. + virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content); + public: /* but not really -- don't touch this */ U32 mReferenceCount; }; typedef boost::intrusive_ptr ResponderPtr; - - class Easy - { - public: - Easy(); - ~Easy(); - - void get(const std::string& url, ResponderPtr); - void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr); - - void perform(); - private: - void prep(const std::string& url, ResponderPtr); - void report(CURLcode); - - CURL* mHandle; - struct curl_slist* mHeaders; - - std::string mURL; - std::string mRange; - std::stringstream mRequest; - std::stringstream mOutput; - char mErrorBuffer[CURL_ERROR_SIZE]; - - std::stringstream mHeaderOutput; // Debug - - ResponderPtr mResponder; - - friend class Multi; - }; + /** + * @ brief Set certificate authority file used to verify HTTPS certs. + */ + static void setCAFile(const std::string& file); + /** + * @ brief Set certificate authority path used to verify HTTPS certs. + */ + static void setCAPath(const std::string& path); + + /** + * @ brief Get certificate authority file used to verify HTTPS certs. + */ + static const std::string& getCAFile() { return sCAFile; } + + /** + * @ brief Get certificate authority path used to verify HTTPS certs. + */ + static const std::string& getCAPath() { return sCAPath; } + + /** + * @ brief Initialize LLCurl class + */ + static void initClass(); + + /** + * @ brief Cleanup LLCurl class + */ + static void cleanupClass(); + + /** + * @ brief curl error code -> string + */ + static std::string strerror(CURLcode errorcode); + + // For OpenSSL callbacks + static std::vector sSSLMutex; - class Multi - { - public: - Multi(); - ~Multi(); + // OpenSSL callbacks + static void LLCurl::ssl_locking_callback(int mode, int type, const char *file, int line); + static unsigned long LLCurl::ssl_thread_id(void); + + + +private: - void get(const std::string& url, ResponderPtr); - void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr); + static std::string sCAPath; + static std::string sCAFile; +}; - void process(); - - private: - Easy* easyAlloc(); - void easyFree(Easy*); - - CURLM* mHandle; - - typedef std::vector EasyList; - EasyList mFreeEasy; - }; +namespace boost +{ + void intrusive_ptr_add_ref(LLCurl::Responder* p); + void intrusive_ptr_release(LLCurl::Responder* p); +}; - static void get(const std::string& url, ResponderPtr); - static void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr responder); +class LLCurlRequest +{ +public: + LLCurlRequest(); + ~LLCurlRequest(); + + void get(const std::string& url, LLCurl::ResponderPtr responder); + bool getByteRange(const std::string& url, S32 offset, S32 length, LLCurl::ResponderPtr responder); + bool post(const std::string& url, const LLSD& data, LLCurl::ResponderPtr responder); + S32 process(); + S32 getQueued(); + +private: + void addMulti(); + LLCurl::Easy* allocEasy(); + bool addEasy(LLCurl::Easy* easy); - static void initClass(); // *NOTE:Mani - not thread safe! - static void process(); - static void cleanup(); // *NOTE:Mani - not thread safe! +private: + typedef std::set curlmulti_set_t; + curlmulti_set_t mMultiSet; + LLCurl::Multi* mActiveMulti; + S32 mActiveRequestCount; }; -namespace boost +class LLCurlEasyRequest { - void intrusive_ptr_add_ref(LLCurl::Responder* p); - void intrusive_ptr_release(LLCurl::Responder* p); +public: + LLCurlEasyRequest(); + ~LLCurlEasyRequest(); + void setopt(CURLoption option, S32 value); + void setoptString(CURLoption option, const std::string& value); + void setPost(char* postdata, S32 size); + void setHeaderCallback(curl_header_callback callback, void* userdata); + void setWriteCallback(curl_write_callback callback, void* userdata); + void setReadCallback(curl_read_callback callback, void* userdata); + void slist_append(const char* str); + void sendRequest(const std::string& url); + void requestComplete(); + S32 perform(); + bool getResult(CURLcode* result, LLCurl::TransferInfo* info = NULL); + std::string getErrorString(); + +private: + CURLMsg* info_read(S32* queue, LLCurl::TransferInfo* info); + +private: + LLCurl::Multi* mMulti; + LLCurl::Easy* mEasy; + bool mRequestSent; + bool mResultReturned; }; #endif // LL_LLCURL_H diff --git a/linden/indra/llmessage/llfiltersd2xmlrpc.cpp b/linden/indra/llmessage/llfiltersd2xmlrpc.cpp index d9e0ad3..4e38924 100644 --- a/linden/indra/llmessage/llfiltersd2xmlrpc.cpp +++ b/linden/indra/llmessage/llfiltersd2xmlrpc.cpp @@ -336,7 +336,7 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl( LLBufferStream stream(channels, buffer.get()); stream << XML_HEADER << XMLRPC_METHOD_RESPONSE_HEADER; LLSD sd; - LLSDSerialize::fromNotation(sd, stream); + LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in())); PUMP_DEBUG; LLIOPipe::EStatus rv = STATUS_ERROR; @@ -408,7 +408,7 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl( // See if we can parse it LLBufferStream stream(channels, buffer.get()); LLSD sd; - LLSDSerialize::fromNotation(sd, stream); + LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in())); if(stream.fail()) { llinfos << "STREAM FAILURE reading structure data." << llendl; diff --git a/linden/indra/llmessage/llhost.cpp b/linden/indra/llmessage/llhost.cpp index 57677b0..e139f6d 100644 --- a/linden/indra/llmessage/llhost.cpp +++ b/linden/indra/llmessage/llhost.cpp @@ -132,14 +132,13 @@ void LLHost::getHostName(char *buf, S32 len) const } } -LLString LLHost::getHostName() const +std::string LLHost::getHostName() const { - hostent *he; - + hostent* he; if (INVALID_HOST_IP_ADDRESS == mIP) { llwarns << "LLHost::getHostName() : Invalid IP address" << llendl; - return ""; + return std::string(); } he = gethostbyaddr((char *)&mIP, sizeof(mIP), AF_INET); if (!he) @@ -151,12 +150,11 @@ LLString LLHost::getHostName() const llwarns << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " << h_errno << llendl; #endif - return ""; + return std::string(); } else { - LLString hostname = he->h_name; - return hostname; + return ll_safe_string(he->h_name); } } diff --git a/linden/indra/llmessage/llhost.h b/linden/indra/llmessage/llhost.h index c393aa6..0b3afe8 100644 --- a/linden/indra/llmessage/llhost.h +++ b/linden/indra/llmessage/llhost.h @@ -38,8 +38,6 @@ #include "net.h" -#include "llstring.h" - const U32 INVALID_PORT = 0; const U32 INVALID_HOST_IP_ADDRESS = 0x0; @@ -102,7 +100,7 @@ public: void getIPString(char* buffer, S32 length) const; // writes IP into buffer std::string getIPString() const; void getHostName(char *buf, S32 len) const; - LLString getHostName() const; + std::string getHostName() const; std::string getIPandPort() const; friend std::ostream& operator<< (std::ostream& os, const LLHost &hh); diff --git a/linden/indra/llmessage/llhttpassetstorage.cpp b/linden/indra/llmessage/llhttpassetstorage.cpp index 74f5271..80598c6 100644 --- a/linden/indra/llmessage/llhttpassetstorage.cpp +++ b/linden/indra/llmessage/llhttpassetstorage.cpp @@ -422,11 +422,8 @@ void LLHTTPAssetStorage::_init(const char *web_host, const char *local_web_host, mLocalBaseURL = local_web_host; mHostName = host_name; - // Do not change this "unless you are familiar with and mean to control - // internal operations of libcurl" - // - http://curl.haxx.se/libcurl/c/curl_global_init.html - curl_global_init(CURL_GLOBAL_ALL); - + // curl_global_init moved to LLCurl::initClass() + mCurlMultiHandle = curl_multi_init(); } @@ -435,7 +432,7 @@ LLHTTPAssetStorage::~LLHTTPAssetStorage() curl_multi_cleanup(mCurlMultiHandle); mCurlMultiHandle = NULL; - curl_global_cleanup(); + // curl_global_cleanup moved to LLCurl::initClass() } // storing data is simpler than getting it, so we just overload the whole method @@ -451,7 +448,7 @@ void LLHTTPAssetStorage::storeAssetData( bool user_waiting, F64 timeout) { - if (mVFS->getExists(uuid, type)) + if (mVFS->getExists(uuid, type)) // VFS treats nonexistant and zero-length identically { LLAssetRequest *req = new LLAssetRequest(uuid, type); req->mUpCallback = callback; @@ -460,6 +457,19 @@ void LLHTTPAssetStorage::storeAssetData( req->mIsUserWaiting = user_waiting; req->mTimeout = timeout; + // LLAssetStorage metric: Successful Request + S32 size = mVFS->getSize(uuid, type); + const char *message; + if( store_local ) + { + message = "Added to local upload queue"; + } + else + { + message = "Added to upload queue"; + } + reportMetric( uuid, type, NULL, requesting_agent_id, size, MR_OKAY, __FILE__, __LINE__, message ); + // this will get picked up and transmitted in checkForTimeouts if(store_local) { @@ -479,6 +489,8 @@ void LLHTTPAssetStorage::storeAssetData( llwarns << "AssetStorage: attempt to upload non-existent vfile " << uuid << ":" << LLAssetType::lookup(type) << llendl; if (callback) { + // LLAssetStorage metric: Zero size VFS + reportMetric( uuid, type, NULL, requesting_agent_id, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" ); callback(uuid, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE); } } @@ -504,13 +516,17 @@ void LLHTTPAssetStorage::storeAssetData( legacy->mUserData = user_data; FILE *fp = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/ + S32 size = 0; if (fp) { - LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE); - fseek(fp, 0, SEEK_END); - S32 size = ftell(fp); + size = ftell(fp); fseek(fp, 0, SEEK_SET); + } + + if( size ) + { + LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE); file.setMaxSize(size); @@ -528,6 +544,7 @@ void LLHTTPAssetStorage::storeAssetData( LLFile::remove(filename); } + // LLAssetStorage metric: Success not needed; handled in the overloaded method here: storeAssetData( asset_id, asset_type, @@ -540,8 +557,19 @@ void LLHTTPAssetStorage::storeAssetData( user_waiting, timeout); } - else + else // !size { + if( fp ) + { + // LLAssetStorage metric: Zero size + reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file was zero length" ); + fclose( fp ); + } + else + { + // LLAssetStorage metric: Missing File + reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_FILE_NONEXIST, __FILE__, __LINE__, "The file didn't exist" ); + } if (callback) { callback(LLUUID::null, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE); @@ -827,7 +855,16 @@ void LLHTTPAssetStorage::checkForTimeouts() } else { - llinfos << "Requesting PUT " << new_req->mURLBuffer << llendl; + // Get the uncompressed file size. + LLVFile file(mVFS,new_req->getUUID(),new_req->getType()); + S32 size = file.getSize(); + llinfos << "Requesting PUT " << new_req->mURLBuffer << ", asset size: " << size << " bytes" << llendl; + if (size == 0) + { + llwarns << "Rejecting zero size PUT request!" << llendl; + new_req->cleanupCurlHandle(); + deletePendingRequest(RT_UPLOAD, new_req->getType(), new_req->getUUID()); + } } // Pending upload will have been flagged by the request } @@ -867,8 +904,19 @@ void LLHTTPAssetStorage::checkForTimeouts() } else { + // Get the uncompressed file size. + S32 size = file.getSize(); + llinfos << "TAT: LLHTTPAssetStorage::checkForTimeouts() : pending local!" - << " Requesting PUT " << new_req->mURLBuffer << llendl; + << " Requesting PUT " << new_req->mURLBuffer << ", asset size: " << size << " bytes" << llendl; + if (size == 0) + { + + llwarns << "Rejecting zero size PUT request!" << llendl; + new_req->cleanupCurlHandle(); + deletePendingRequest(RT_UPLOAD, new_req->getType(), new_req->getUUID()); + } + } // Pending upload will have been flagged by the request } @@ -1403,5 +1451,3 @@ void LLHTTPAssetStorage::clearTempAssetData() llinfos << "TAT: Clearing temp asset data map" << llendl; mTempAssets.clear(); } - - diff --git a/linden/indra/llmessage/llhttpclient.cpp b/linden/indra/llmessage/llhttpclient.cpp index 3ede02a..22c0c68 100644 --- a/linden/indra/llmessage/llhttpclient.cpp +++ b/linden/indra/llmessage/llhttpclient.cpp @@ -1,4 +1,4 @@ -/** + /** * @file llhttpclient.cpp * @brief Implementation of classes for making HTTP requests. * @@ -46,75 +46,18 @@ #include const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f; -static std::string gCABundle; - - -LLHTTPClient::Responder::Responder() - : mReferenceCount(0) -{ -} - -LLHTTPClient::Responder::~Responder() -{ -} - -// virtual -void LLHTTPClient::Responder::error(U32 status, const std::string& reason) -{ - llinfos << "LLHTTPClient::Responder::error " - << status << ": " << reason << llendl; -} - -// virtual -void LLHTTPClient::Responder::result(const LLSD& content) -{ -} - -// virtual -void LLHTTPClient::Responder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer) -{ - LLBufferStream istr(channels, buffer.get()); - LLSD content; - - if (isGoodStatus(status)) - { - LLSDSerialize::fromXML(content, istr); -/* - const S32 parseError = -1; - if(LLSDSerialize::fromXML(content, istr) == parseError) - { - mStatus = 498; - mReason = "Client Parse Error"; - } -*/ - } - - completed(status, reason, content); -} - -// virtual -void LLHTTPClient::Responder::completed(U32 status, const std::string& reason, const LLSD& content) -{ - if(isGoodStatus(status)) - { - result(content); - } - else - { - error(status, reason); - } -} +//////////////////////////////////////////////////////////////////////////// +// Responder class moved to LLCurl namespace { class LLHTTPClientURLAdaptor : public LLURLRequestComplete { public: - LLHTTPClientURLAdaptor(LLHTTPClient::ResponderPtr responder) - : mResponder(responder), - mStatus(499), mReason("LLURLRequest complete w/no status") + LLHTTPClientURLAdaptor(LLCurl::ResponderPtr responder) + : mResponder(responder), mStatus(499), + mReason("LLURLRequest complete w/no status") { } @@ -129,18 +72,24 @@ namespace } virtual void complete(const LLChannelDescriptors& channels, - const buffer_ptr_t& buffer) + const buffer_ptr_t& buffer) { if (mResponder.get()) { mResponder->completedRaw(mStatus, mReason, channels, buffer); + mResponder->completedHeader(mStatus, mReason, mHeaderOutput); } } + virtual void header(const std::string& header, const std::string& value) + { + mHeaderOutput[header] = value; + } private: - LLHTTPClient::ResponderPtr mResponder; + LLCurl::ResponderPtr mResponder; U32 mStatus; std::string mReason; + LLSD mHeaderOutput; }; class Injector : public LLIOPipe @@ -250,13 +199,14 @@ namespace LLPumpIO* theClientPump = NULL; } -static void request( - const std::string& url, - LLURLRequest::ERequestAction method, - Injector* body_injector, - LLHTTPClient::ResponderPtr responder, - const LLSD& headers, - const F32 timeout=HTTP_REQUEST_EXPIRY_SECS) +static void request(const std::string& url, + LLURLRequest::ERequestAction method, + Injector* body_injector, + LLCurl::ResponderPtr responder, + const LLSD& headers = LLSD(), + const F32 timeout = HTTP_REQUEST_EXPIRY_SECS, + S32 offset = 0, + S32 bytes = 0) { if (!LLHTTPClient::hasPump()) { @@ -266,7 +216,7 @@ static void request( LLPumpIO::chain_t chain; LLURLRequest *req = new LLURLRequest(method, url); - req->requestEncoding(""); + req->checkRootCertificate(true); // Insert custom headers is the caller sent any if (headers.isMap()) @@ -291,10 +241,6 @@ static void request( req->addHeader(header.str().c_str()); } } - if (!gCABundle.empty()) - { - req->checkRootCertificate(true, gCABundle.c_str()); - } req->setCallback(new LLHTTPClientURLAdaptor(responder)); if (method == LLURLRequest::HTTP_POST && gMessageSystem) @@ -310,19 +256,26 @@ static void request( chain.push_back(LLIOPipe::ptr_t(body_injector)); } + + if (method == LLURLRequest::HTTP_GET && (offset > 0 || bytes > 0)) + { + std::string range = llformat("Range: bytes=%d-%d", offset,offset+bytes-1); + req->addHeader(range.c_str()); + } + chain.push_back(LLIOPipe::ptr_t(req)); theClientPump->addChain(chain, timeout); } -static void request( - const std::string& url, - LLURLRequest::ERequestAction method, - Injector* body_injector, - LLHTTPClient::ResponderPtr responder, - const F32 timeout=HTTP_REQUEST_EXPIRY_SECS) + +void LLHTTPClient::getByteRange(const std::string& url, + S32 offset, S32 bytes, + ResponderPtr responder, + const LLSD& headers, + const F32 timeout) { - request(url, method, body_injector, responder, LLSD(), timeout); + request(url, LLURLRequest::HTTP_GET, NULL, responder, LLSD(), timeout, offset, bytes); } void LLHTTPClient::head(const std::string& url, ResponderPtr responder, const F32 timeout) @@ -334,10 +287,13 @@ void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const LLS { request(url, LLURLRequest::HTTP_GET, NULL, responder, headers, timeout); } - -void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const F32 timeout) +void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout) { - get(url, responder, LLSD(), timeout); + request(url, LLURLRequest::HTTP_HEAD, NULL, responder, headers, timeout); +} +void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const F32 timeout) +{ + getHeaderOnly(url, responder, LLSD(), timeout); } void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers, const F32 timeout) @@ -348,11 +304,6 @@ void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr r get(uri.asString(), responder, headers, timeout); } -void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const F32 timeout) -{ - get(url, query, responder, LLSD(), timeout); -} - // A simple class for managing data returned from a curl http request. class LLHTTPBuffer { @@ -388,6 +339,7 @@ private: std::string mBuffer; }; +// *TODO: Deprecate (only used by dataserver) // This call is blocking! This is probably usually bad. :( LLSD LLHTTPClient::blockingGet(const std::string& url) { @@ -481,24 +433,3 @@ bool LLHTTPClient::hasPump() { return theClientPump != NULL; } - -void LLHTTPClient::setCABundle(const std::string& caBundle) -{ - gCABundle = caBundle; -} - -namespace boost -{ - void intrusive_ptr_add_ref(LLHTTPClient::Responder* p) - { - ++p->mReferenceCount; - } - - void intrusive_ptr_release(LLHTTPClient::Responder* p) - { - if(p && 0 == --p->mReferenceCount) - { - delete p; - } - } -}; diff --git a/linden/indra/llmessage/llhttpclient.h b/linden/indra/llmessage/llhttpclient.h index 703ee61..1587268 100644 --- a/linden/indra/llmessage/llhttpclient.h +++ b/linden/indra/llmessage/llhttpclient.h @@ -41,7 +41,7 @@ #include #include "llassettype.h" -#include "llbuffer.h" +#include "llcurl.h" #include "lliopipe.h" extern const F32 HTTP_REQUEST_EXPIRY_SECS; @@ -54,48 +54,23 @@ class LLSD; class LLHTTPClient { public: - class Responder - { - public: - Responder(); - virtual ~Responder(); - - /** - * @brief return true if the status code indicates success. - */ - static bool isGoodStatus(U32 status) - { - return((200 <= status) && (status < 300)); - } - - virtual void error(U32 status, const std::string& reason); // called with bad status codes - - virtual void result(const LLSD& content); - - // Override point for clients that may want to use this class when the response is some other format besides LLSD - virtual void completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, - const LLIOPipe::buffer_ptr_t& buffer); - - virtual void completed(U32 status, const std::string& reason, const LLSD& content); - /**< The default implemetnation calls - either: - * result(), or - * error() - */ - - public: /* but not really -- don't touch this */ - U32 mReferenceCount; - }; - - typedef boost::intrusive_ptr ResponderPtr; - + // class Responder moved to LLCurl + + // For convenience + typedef LLCurl::Responder Responder; + typedef LLCurl::ResponderPtr ResponderPtr; + + // non-blocking static void head(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); - static void get(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); - static void get(const std::string& url, ResponderPtr, const LLSD& headers, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); - static void get(const std::string& url, const LLSD& query, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); - static void get(const std::string& url, const LLSD& query, ResponderPtr, const LLSD& headers, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); + static void getByteRange(const std::string& url, S32 offset, S32 bytes, ResponderPtr, const LLSD& headers=LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); + static void get(const std::string& url, ResponderPtr, const LLSD& headers = LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); + static void get(const std::string& url, const LLSD& query, ResponderPtr, const LLSD& headers = LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); + static void put(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); - ///< non-blocking + static void getHeaderOnly(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); + static void getHeaderOnly(const std::string& url, ResponderPtr, const LLSD& headers, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); + + ///< non-blocking static void post(const std::string& url, const LLSD& body, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); static void post(const std::string& url, const U8* data, S32 size, ResponderPtr responder, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); static void postFile(const std::string& url, const std::string& filename, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); @@ -113,20 +88,6 @@ public: ///< must be called before any of the above calls are made static bool hasPump(); ///< for testing - - static void setCABundle(const std::string& caBundle); - ///< use this root CA bundle when checking SSL connections - ///< defaults to the standard system root CA bundle - ///< @see LLURLRequest::checkRootCertificate() }; - - -namespace boost -{ - void intrusive_ptr_add_ref(LLHTTPClient::Responder* p); - void intrusive_ptr_release(LLHTTPClient::Responder* p); -}; - - #endif // LL_LLHTTPCLIENT_H diff --git a/linden/indra/llmessage/llhttpnode.h b/linden/indra/llmessage/llhttpnode.h index 9317e9c..b4d4aed 100644 --- a/linden/indra/llmessage/llhttpnode.h +++ b/linden/indra/llmessage/llhttpnode.h @@ -176,7 +176,7 @@ public: /* @name Description system The Description object contains information about a service. - All subclasses of LLHTTPNode should override description() and use + All subclasses of LLHTTPNode should override describe() and use the methods of the Description class to set the various properties. */ //@{ diff --git a/linden/indra/llmessage/lliohttpserver.cpp b/linden/indra/llmessage/lliohttpserver.cpp index 40f70c3..6e94ec6 100644 --- a/linden/indra/llmessage/lliohttpserver.cpp +++ b/linden/indra/llmessage/lliohttpserver.cpp @@ -156,7 +156,9 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( // assume deferred unless mResponse does otherwise mResponse = Response::create(this); - // TODO: Babbage: Parameterize parser? + // *TODO: Babbage: Parameterize parser? + // *TODO: We should look at content-type and do the right + // thing. Phoenix 2007-12-31 LLBufferStream istr(channels, buffer.get()); static LLTimer timer; @@ -171,14 +173,12 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( { LLSD input; LLSDSerialize::fromXML(input, istr); - mNode.put(LLHTTPNode::ResponsePtr(mResponse), context, input); } else if(verb == HTTP_VERB_POST) { LLSD input; LLSDSerialize::fromXML(input, istr); - mNode.post(LLHTTPNode::ResponsePtr(mResponse), context, input); } else if(verb == HTTP_VERB_DELETE) diff --git a/linden/indra/llmessage/llmessage.vcproj b/linden/indra/llmessage/llmessage.vcproj index 56b7d30..b011c24 100644 --- a/linden/indra/llmessage/llmessage.vcproj +++ b/linden/indra/llmessage/llmessage.vcproj @@ -394,9 +394,6 @@ RelativePath=".\llcachename.h"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llmessage/llmessage_vc9.vcproj b/linden/indra/llmessage/llmessage_vc9.vcproj index f197feb..e9f4889 100644 --- a/linden/indra/llmessage/llmessage_vc9.vcproj +++ b/linden/indra/llmessage/llmessage_vc9.vcproj @@ -1,926 +1,922 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llmessage/llnamevalue.h b/linden/indra/llmessage/llnamevalue.h index 123836b..c58172a 100644 --- a/linden/indra/llmessage/llnamevalue.h +++ b/linden/indra/llmessage/llnamevalue.h @@ -33,7 +33,6 @@ #define LL_LLNAMEVALUE_H #include "string_table.h" -#include "llskipmap.h" #include "llmath.h" #include "v3math.h" #include "lldbstrings.h" diff --git a/linden/indra/llmessage/llpacketring.h b/linden/indra/llmessage/llpacketring.h index 2153e96..dac52e6 100644 --- a/linden/indra/llmessage/llpacketring.h +++ b/linden/indra/llmessage/llpacketring.h @@ -36,7 +36,6 @@ #include #include "llpacketbuffer.h" -#include "linked_lists.h" #include "llhost.h" #include "net.h" #include "llthrottle.h" diff --git a/linden/indra/llmessage/llsdrpcclient.cpp b/linden/indra/llmessage/llsdrpcclient.cpp index c67992d..7c4b8e3 100644 --- a/linden/indra/llmessage/llsdrpcclient.cpp +++ b/linden/indra/llmessage/llsdrpcclient.cpp @@ -221,7 +221,7 @@ LLIOPipe::EStatus LLSDRPCClient::process_impl( // << llendl; LLBufferStream resp(channels, buffer.get()); LLSD sd; - LLSDSerialize::fromNotation(sd, resp); + LLSDSerialize::fromNotation(sd, resp, buffer->count(channels.in())); LLSDRPCResponse* response = (LLSDRPCResponse*)mResponse.get(); if (!response) { diff --git a/linden/indra/llmessage/llsdrpcserver.cpp b/linden/indra/llmessage/llsdrpcserver.cpp index 5406e02..c77ac5c 100644 --- a/linden/indra/llmessage/llsdrpcserver.cpp +++ b/linden/indra/llmessage/llsdrpcserver.cpp @@ -182,7 +182,10 @@ LLIOPipe::EStatus LLSDRPCServer::process_impl( PUMP_DEBUG; LLBufferStream istr(channels, buffer.get()); mRequest.clear(); - LLSDSerialize::fromNotation(mRequest, istr); + LLSDSerialize::fromNotation( + mRequest, + istr, + buffer->count(channels.in())); // { 'method':'...', 'parameter': ... } method_name = mRequest[LLSDRPC_METHOD_SD_NAME].asString(); diff --git a/linden/indra/llmessage/llservicebuilder.cpp b/linden/indra/llmessage/llservicebuilder.cpp index 6ffd480..195e24b 100644 --- a/linden/indra/llmessage/llservicebuilder.cpp +++ b/linden/indra/llmessage/llservicebuilder.cpp @@ -1,33 +1,33 @@ /** -* @file llservicebuilder.cpp -* @brief Implementation of the LLServiceBuilder class. -* -* $LicenseInfo:firstyear=2007&license=viewergpl$ -* -* Copyright (c) 2007-2008, Linden Research, Inc. -* -* Second Life Viewer Source Code -* The source code in this file ("Source Code") is provided by Linden Lab -* to you under the terms of the GNU General Public License, version 2.0 -* ("GPL"), unless you have obtained a separate licensing agreement -* ("Other License"), formally executed by you and Linden Lab. Terms of -* the GPL can be found in doc/GPL-license.txt in this distribution, or -* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 -* -* There are special exceptions to the terms and conditions of the GPL as -* it is applied to this Source Code. View the full text of the exception -* in the file doc/FLOSS-exception.txt in this software distribution, or -* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception -* -* By copying, modifying or distributing this software, you acknowledge -* that you have read and understood your obligations described above, -* and agree to abide by those obligations. -* -* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -* COMPLETENESS OR PERFORMANCE. -* $/LicenseInfo$ -*/ + * @file llservicebuilder.cpp + * @brief Implementation of the LLServiceBuilder class. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ #include "linden_common.h" #include "llapp.h" diff --git a/linden/indra/llmessage/llurlrequest.cpp b/linden/indra/llmessage/llurlrequest.cpp index 6c826cd..eabd951 100644 --- a/linden/indra/llmessage/llurlrequest.cpp +++ b/linden/indra/llmessage/llurlrequest.cpp @@ -37,6 +37,7 @@ #include #include +#include "llcurl.h" #include "llioutil.h" #include "llmemtype.h" #include "llpumpio.h" @@ -52,8 +53,7 @@ static const U32 HTTP_STATUS_PIPE_ERROR = 499; const std::string CONTEXT_DEST_URI_SD_LABEL("dest_uri"); -static -size_t headerCallback(void* data, size_t size, size_t nmemb, void* user); +static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user); /** * class LLURLRequestDetail @@ -63,12 +63,8 @@ class LLURLRequestDetail public: LLURLRequestDetail(); ~LLURLRequestDetail(); - CURLM* mCurlMulti; - CURL* mCurl; - struct curl_slist* mHeaders; - char* mURL; - char mCurlErrorBuf[CURL_ERROR_SIZE + 1]; /* Flawfinder: ignore */ - bool mNeedToRemoveEasyHandle; + std::string mURL; + LLCurlEasyRequest* mCurlRequest; LLBufferArray* mResponseBuffer; LLChannelDescriptors mChannels; U8* mLastRead; @@ -77,11 +73,7 @@ public: }; LLURLRequestDetail::LLURLRequestDetail() : - mCurlMulti(NULL), - mCurl(NULL), - mHeaders(NULL), - mURL(NULL), - mNeedToRemoveEasyHandle(false), + mCurlRequest(NULL), mResponseBuffer(NULL), mLastRead(NULL), mBodyLimit(0), @@ -89,34 +81,13 @@ LLURLRequestDetail::LLURLRequestDetail() : { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); - mCurlErrorBuf[0] = '\0'; + mCurlRequest = new LLCurlEasyRequest(); } LLURLRequestDetail::~LLURLRequestDetail() { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); - if(mCurl) - { - if(mNeedToRemoveEasyHandle && mCurlMulti) - { - curl_multi_remove_handle(mCurlMulti, mCurl); - mNeedToRemoveEasyHandle = false; - } - curl_easy_cleanup(mCurl); - mCurl = NULL; - } - if(mCurlMulti) - { - curl_multi_cleanup(mCurlMulti); - mCurlMulti = NULL; - } - if(mHeaders) - { - curl_slist_free_all(mHeaders); - mHeaders = NULL; - } - delete[] mURL; - mURL = NULL; + delete mCurlRequest; mResponseBuffer = NULL; mLastRead = NULL; } @@ -126,9 +97,6 @@ LLURLRequestDetail::~LLURLRequestDetail() * class LLURLRequest */ -static std::string sCAFile(""); -static std::string sCAPath(""); - LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action) : mAction(action) { @@ -155,31 +123,13 @@ LLURLRequest::~LLURLRequest() void LLURLRequest::setURL(const std::string& url) { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); - if(mDetail->mURL) - { - // *NOTE: if any calls to set the url have been made to curl, - // this will probably lead to a crash. - delete[] mDetail->mURL; - mDetail->mURL = NULL; - } - if(!url.empty()) - { - mDetail->mURL = new char[url.size() + 1]; - url.copy(mDetail->mURL, url.size()); - mDetail->mURL[url.size()] = '\0'; - } + mDetail->mURL = url; } void LLURLRequest::addHeader(const char* header) { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); - mDetail->mHeaders = curl_slist_append(mDetail->mHeaders, header); -} - -void LLURLRequest::requestEncoding(const char* encoding) -{ - LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); - curl_easy_setopt(mDetail->mCurl, CURLOPT_ENCODING, encoding); + mDetail->mCurlRequest->slist_append(header); } void LLURLRequest::setBodyLimit(U32 size) @@ -188,22 +138,17 @@ void LLURLRequest::setBodyLimit(U32 size) mDetail->mIsBodyLimitSet = true; } -void LLURLRequest::checkRootCertificate(bool check, const char* caBundle) +void LLURLRequest::checkRootCertificate(bool check) { - curl_easy_setopt(mDetail->mCurl, CURLOPT_SSL_VERIFYPEER, (check? TRUE : FALSE)); - if (caBundle) - { - curl_easy_setopt(mDetail->mCurl, CURLOPT_CAINFO, caBundle); - } + mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, (check? TRUE : FALSE)); + mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, ""); } void LLURLRequest::setCallback(LLURLRequestComplete* callback) { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); mCompletionCallback = callback; - - curl_easy_setopt(mDetail->mCurl, CURLOPT_HEADERFUNCTION, &headerCallback); - curl_easy_setopt(mDetail->mCurl, CURLOPT_WRITEHEADER, callback); + mDetail->mCurlRequest->setHeaderCallback(&headerCallback, (void*)callback); } // Added to mitigate the effect of libcurl looking @@ -235,15 +180,15 @@ void LLURLRequest::useProxy(bool use_proxy) } - lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << env_proxy << llendl; + lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl; if (env_proxy && use_proxy) { - curl_easy_setopt(mDetail->mCurl, CURLOPT_PROXY, env_proxy); + mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy); } else { - curl_easy_setopt(mDetail->mCurl, CURLOPT_PROXY, ""); + mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, ""); } } @@ -309,27 +254,20 @@ LLIOPipe::EStatus LLURLRequest::process_impl( case STATE_PROCESSING_RESPONSE: { PUMP_DEBUG; - const S32 MAX_CALLS = 5; - S32 count = MAX_CALLS; - CURLMcode code; LLIOPipe::EStatus status = STATUS_BREAK; - S32 queue; - do - { - LLFastTimer t2(LLFastTimer::FTM_CURL); - code = curl_multi_perform(mDetail->mCurlMulti, &queue); - }while((CURLM_CALL_MULTI_PERFORM == code) && (queue > 0) && count--); - CURLMsg* curl_msg; - do + mDetail->mCurlRequest->perform(); + while(1) { - curl_msg = curl_multi_info_read(mDetail->mCurlMulti, &queue); - if(curl_msg && (curl_msg->msg == CURLMSG_DONE)) + CURLcode result; + bool newmsg = mDetail->mCurlRequest->getResult(&result); + if (!newmsg) { - mState = STATE_HAVE_RESPONSE; + break; + } - CURLcode result = curl_msg->data.result; - switch(result) - { + mState = STATE_HAVE_RESPONSE; + switch(result) + { case CURLE_OK: case CURLE_WRITE_ERROR: // NB: The error indication means that we stopped the @@ -352,31 +290,21 @@ LLIOPipe::EStatus LLURLRequest::process_impl( mCompletionCallback = NULL; } break; + case CURLE_FAILED_INIT: case CURLE_COULDNT_CONNECT: status = STATUS_NO_CONNECTION; break; default: - llwarns << "URLRequest Error: " << curl_msg->data.result + llwarns << "URLRequest Error: " << result << ", " -#if LL_DARWIN - // curl_easy_strerror was added in libcurl 7.12.0. Unfortunately, the version in the Mac OS X 10.3.9 SDK is 7.10.2... - // There's a problem with the custom curl headers in our build that keeps me from #ifdefing this on the libcurl version number - // (the correct check would be #if LIBCURL_VERSION_NUM >= 0x070c00). We'll fix the header problem soon, but for now - // just punt and print the numeric error code on the Mac. - << curl_msg->data.result -#else // LL_DARWIN - << curl_easy_strerror(curl_msg->data.result) -#endif // LL_DARWIN + << LLCurl::strerror(result) << ", " - << (mDetail->mURL ? mDetail->mURL : "") + << (mDetail->mURL.empty() ? "" : mDetail->mURL) << llendl; status = STATUS_ERROR; break; - } - curl_multi_remove_handle(mDetail->mCurlMulti, mDetail->mCurl); - mDetail->mNeedToRemoveEasyHandle = false; } - }while(curl_msg && (queue > 0)); + } return status; } case STATE_HAVE_RESPONSE: @@ -397,26 +325,9 @@ void LLURLRequest::initialize() LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); mState = STATE_INITIALIZED; mDetail = new LLURLRequestDetail; - mDetail->mCurl = curl_easy_init(); - mDetail->mCurlMulti = curl_multi_init(); - curl_easy_setopt(mDetail->mCurl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_WRITEFUNCTION, &downCallback); - curl_easy_setopt(mDetail->mCurl, CURLOPT_WRITEDATA, this); - curl_easy_setopt(mDetail->mCurl, CURLOPT_READFUNCTION, &upCallback); - curl_easy_setopt(mDetail->mCurl, CURLOPT_READDATA, this); - curl_easy_setopt( - mDetail->mCurl, - CURLOPT_ERRORBUFFER, - mDetail->mCurlErrorBuf); - - if(sCAPath != std::string("")) - { - curl_easy_setopt(mDetail->mCurl, CURLOPT_CAPATH, sCAPath.c_str()); - } - if(sCAFile != std::string("")) - { - curl_easy_setopt(mDetail->mCurl, CURLOPT_CAINFO, sCAFile.c_str()); - } + mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1); + mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this); + mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this); } bool LLURLRequest::configure() @@ -429,15 +340,14 @@ bool LLURLRequest::configure() switch(mAction) { case HTTP_HEAD: - curl_easy_setopt(mDetail->mCurl, CURLOPT_HEADER, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_NOBODY, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_FOLLOWLOCATION, 1); + mDetail->mCurlRequest->setopt(CURLOPT_HEADER, 1); + mDetail->mCurlRequest->setopt(CURLOPT_NOBODY, 1); + mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1); rv = true; break; - case HTTP_GET: - curl_easy_setopt(mDetail->mCurl, CURLOPT_HTTPGET, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_FOLLOWLOCATION, 1); + mDetail->mCurlRequest->setopt(CURLOPT_HTTPGET, 1); + mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1); rv = true; break; @@ -446,8 +356,8 @@ bool LLURLRequest::configure() // to turning this on, and I am not too sure what it means. addHeader("Expect:"); - curl_easy_setopt(mDetail->mCurl, CURLOPT_UPLOAD, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_INFILESIZE, bytes); + mDetail->mCurlRequest->setopt(CURLOPT_UPLOAD, 1); + mDetail->mCurlRequest->setopt(CURLOPT_INFILESIZE, bytes); rv = true; break; @@ -461,15 +371,13 @@ bool LLURLRequest::configure() addHeader("Content-Type:"); // Set the handle for an http post - curl_easy_setopt(mDetail->mCurl, CURLOPT_POST, 1); - curl_easy_setopt(mDetail->mCurl, CURLOPT_POSTFIELDS, NULL); - curl_easy_setopt(mDetail->mCurl, CURLOPT_POSTFIELDSIZE, bytes); + mDetail->mCurlRequest->setPost(NULL, bytes); rv = true; break; case HTTP_DELETE: // Set the handle for an http post - curl_easy_setopt(mDetail->mCurl, CURLOPT_CUSTOMREQUEST, "DELETE"); + mDetail->mCurlRequest->setoptString(CURLOPT_CUSTOMREQUEST, "DELETE"); rv = true; break; @@ -479,24 +387,14 @@ bool LLURLRequest::configure() } if(rv) { - if(mDetail->mHeaders) - { - curl_easy_setopt( - mDetail->mCurl, - CURLOPT_HTTPHEADER, - mDetail->mHeaders); - } - curl_easy_setopt(mDetail->mCurl, CURLOPT_URL, mDetail->mURL); - lldebugs << "URL: " << mDetail->mURL << llendl; - curl_multi_add_handle(mDetail->mCurlMulti, mDetail->mCurl); - mDetail->mNeedToRemoveEasyHandle = true; + mDetail->mCurlRequest->sendRequest(mDetail->mURL); } return rv; } // static size_t LLURLRequest::downCallback( - void* data, + char* data, size_t size, size_t nmemb, void* user) @@ -530,7 +428,7 @@ size_t LLURLRequest::downCallback( // static size_t LLURLRequest::upCallback( - void* data, + char* data, size_t size, size_t nmemb, void* user) @@ -550,8 +448,7 @@ size_t LLURLRequest::upCallback( return bytes; } -static -size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) +static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) { const char* headerLine = (const char*)data; size_t headerLen = size * nmemb; @@ -607,18 +504,6 @@ size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) return headerLen; } -//static -void LLURLRequest::setCertificateAuthorityFile(const std::string& file_name) -{ - sCAFile = file_name; -} - -//static -void LLURLRequest::setCertificateAuthorityPath(const std::string& path) -{ - sCAPath = path; -} - /** * LLContextURLExtractor */ diff --git a/linden/indra/llmessage/llurlrequest.h b/linden/indra/llmessage/llurlrequest.h index 3b91a1d..dd82a9f 100644 --- a/linden/indra/llmessage/llurlrequest.h +++ b/linden/indra/llmessage/llurlrequest.h @@ -129,18 +129,8 @@ public: * * Set whether request will check that remote server * certificates are signed by a known root CA when using HTTPS. - * Use the supplied root certificate bundle if supplied, else use - * the standard bundle as found by libcurl and openssl. */ - void checkRootCertificate(bool check, const char* caBundle = NULL); - - /** - * @brief Request a particular response encoding if available. - * - * This call is a shortcut for requesting a particular encoding - * from the server, eg, 'gzip'. - */ - void requestEncoding(const char* encoding); + void checkRootCertificate(bool check); /** * @brief Return at most size bytes of body. @@ -168,16 +158,6 @@ public: void setCallback(LLURLRequestComplete* callback); //@} - /** - * @ brief Set certificate authority file used to verify HTTPS certs. - */ - static void setCertificateAuthorityFile(const std::string& file_name); - - /** - * @ brief Set certificate authority path used to verify HTTPS certs. - */ - static void setCertificateAuthorityPath(const std::string& path); - /* @name LLIOPipe virtual implementations */ @@ -234,7 +214,7 @@ private: * @brief Download callback method. */ static size_t downCallback( - void* data, + char* data, size_t size, size_t nmemb, void* user); @@ -243,7 +223,7 @@ private: * @brief Upload callback method. */ static size_t upCallback( - void* data, + char* data, size_t size, size_t nmemb, void* user); diff --git a/linden/indra/llmessage/llxfermanager.cpp b/linden/indra/llmessage/llxfermanager.cpp index e08acd9..47c950b 100644 --- a/linden/indra/llmessage/llxfermanager.cpp +++ b/linden/indra/llmessage/llxfermanager.cpp @@ -90,8 +90,9 @@ void LLXferManager::free () { LLXfer *xferp; LLXfer *delp; - - mOutgoingHosts.deleteAllData(); + + for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer()); + mOutgoingHosts.clear(); delp = mSendList; while (delp) @@ -155,12 +156,15 @@ void LLXferManager::updateHostStatus() LLXfer *xferp; LLHostStatus *host_statusp = NULL; - mOutgoingHosts.deleteAllData(); + for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer()); + mOutgoingHosts.clear(); for (xferp = mSendList; xferp; xferp = xferp->mNext) { - for (host_statusp = mOutgoingHosts.getFirstData(); host_statusp; host_statusp = mOutgoingHosts.getNextData()) + for (status_list_t::iterator iter = mOutgoingHosts.begin(); + iter != mOutgoingHosts.end(); ++iter) { + host_statusp = *iter; if (host_statusp->mHost == xferp->mRemoteHost) { break; @@ -172,7 +176,7 @@ void LLXferManager::updateHostStatus() if (host_statusp) { host_statusp->mHost = xferp->mRemoteHost; - mOutgoingHosts.addData(host_statusp); + mOutgoingHosts.push_front(host_statusp); } } if (host_statusp) @@ -195,12 +199,14 @@ void LLXferManager::updateHostStatus() void LLXferManager::printHostStatus() { LLHostStatus *host_statusp = NULL; - if (mOutgoingHosts.getFirstData()) + if (!mOutgoingHosts.empty()) { llinfos << "Outgoing Xfers:" << llendl; - for (host_statusp = mOutgoingHosts.getFirstData(); host_statusp; host_statusp = mOutgoingHosts.getNextData()) + for (status_list_t::iterator iter = mOutgoingHosts.begin(); + iter != mOutgoingHosts.end(); ++iter) { + host_statusp = *iter; llinfos << " " << host_statusp->mHost << " active: " << host_statusp->mNumActive << " pending: " << host_statusp->mNumPending << llendl; } } @@ -275,8 +281,10 @@ S32 LLXferManager::numPendingXfers(const LLHost &host) { LLHostStatus *host_statusp = NULL; - for (host_statusp = mOutgoingHosts.getFirstData(); host_statusp; host_statusp = mOutgoingHosts.getNextData()) + for (status_list_t::iterator iter = mOutgoingHosts.begin(); + iter != mOutgoingHosts.end(); ++iter) { + host_statusp = *iter; if (host_statusp->mHost == host) { return (host_statusp->mNumPending); @@ -291,8 +299,10 @@ S32 LLXferManager::numActiveXfers(const LLHost &host) { LLHostStatus *host_statusp = NULL; - for (host_statusp = mOutgoingHosts.getFirstData(); host_statusp; host_statusp = mOutgoingHosts.getNextData()) + for (status_list_t::iterator iter = mOutgoingHosts.begin(); + iter != mOutgoingHosts.end(); ++iter) { + host_statusp = *iter; if (host_statusp->mHost == host) { return (host_statusp->mNumActive); @@ -307,8 +317,10 @@ void LLXferManager::changeNumActiveXfers(const LLHost &host, S32 delta) { LLHostStatus *host_statusp = NULL; - for (host_statusp = mOutgoingHosts.getFirstData(); host_statusp; host_statusp = mOutgoingHosts.getNextData()) + for (status_list_t::iterator iter = mOutgoingHosts.begin(); + iter != mOutgoingHosts.end(); ++iter) { + host_statusp = *iter; if (host_statusp->mHost == host) { host_statusp->mNumActive += delta; @@ -1010,15 +1022,15 @@ void LLXferManager::startPendingDownloads() // stateful iteration, it would be possible for old requests to // never start. LLXfer* xferp = mReceiveList; - LLLinkedList pending_downloads; + std::list pending_downloads; S32 download_count = 0; S32 pending_count = 0; while(xferp) { if(xferp->mStatus == e_LL_XFER_PENDING) { - ++pending_count; // getLength() is O(N), so track it here. - pending_downloads.addData(xferp); + ++pending_count; + pending_downloads.push_front(xferp); } else if(xferp->mStatus == e_LL_XFER_IN_PROGRESS) { @@ -1036,16 +1048,18 @@ void LLXferManager::startPendingDownloads() if((start_count > 0) && (pending_count > 0)) { S32 result; - xferp = pending_downloads.getFirstData(); - while(start_count-- && xferp) + for (std::list::iterator iter = pending_downloads.begin(); + iter != pending_downloads.end(); ++iter) { + xferp = *iter; + if (start_count-- <= 0) + break; result = xferp->startDownload(); if(result) { xferp->abort(result); ++start_count; } - xferp = pending_downloads.getNextData(); } } } diff --git a/linden/indra/llmessage/llxfermanager.h b/linden/indra/llmessage/llxfermanager.h index 7b3a888..82cd8e9 100644 --- a/linden/indra/llmessage/llxfermanager.h +++ b/linden/indra/llmessage/llxfermanager.h @@ -45,7 +45,6 @@ class LLVFS; #include "llxfer.h" #include "message.h" #include "llassetstorage.h" -#include "linked_lists.h" #include "lldir.h" #include "lllinkedqueue.h" #include "llthrottle.h" @@ -101,7 +100,8 @@ class LLXferManager LLXfer *mSendList; LLXfer *mReceiveList; - LLLinkedList mOutgoingHosts; + typedef std::list status_list_t; + status_list_t mOutgoingHosts; private: protected: diff --git a/linden/indra/llmessage/message.h b/linden/indra/llmessage/message.h index 424674d..05aa592 100644 --- a/linden/indra/llmessage/message.h +++ b/linden/indra/llmessage/message.h @@ -216,8 +216,6 @@ class LLMessageSystem LLPacketRing mPacketRing; LLReliablePacketParams mReliablePacketParams; - //LLLinkedList mAckList; - // Set this flag to TRUE when you want *very* verbose logs. BOOL mVerboseLog; diff --git a/linden/indra/llprimitive/llmaterialtable.cpp b/linden/indra/llprimitive/llmaterialtable.cpp index ee088d0..537c968 100644 --- a/linden/indra/llprimitive/llmaterialtable.cpp +++ b/linden/indra/llprimitive/llmaterialtable.cpp @@ -32,6 +32,7 @@ #include "linden_common.h" #include "llmaterialtable.h" +#include "llstl.h" #include "material_codes.h" #include "sound_ids.h" #include "imageids.h" @@ -70,7 +71,8 @@ LLMaterialTable::~LLMaterialTable() mRollingSoundMatrix = NULL; } - mMaterialInfoList.deleteAllData(); + for_each(mMaterialInfoList.begin(), mMaterialInfoList.end(), DeletePointer()); + mMaterialInfoList.clear(); } void LLMaterialTable::initBasicTable() @@ -290,7 +292,7 @@ BOOL LLMaterialTable::add(U8 mcode, char* name, const LLUUID &uuid) // Add at the end so the order in menus matches the order in this // file. JNC 11.30.01 - mMaterialInfoList.addDataAtEnd(infop); + mMaterialInfoList.push_back(infop); return TRUE; } @@ -336,10 +338,10 @@ BOOL LLMaterialTable::addRollingSound(U8 mcode, U8 mcode2, const LLUUID &uuid) BOOL LLMaterialTable::addShatterSound(U8 mcode, const LLUUID &uuid) { - LLMaterialInfo *infop; - - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { infop->mShatterSoundID = uuid; @@ -352,10 +354,10 @@ BOOL LLMaterialTable::addShatterSound(U8 mcode, const LLUUID &uuid) BOOL LLMaterialTable::addDensity(U8 mcode, const F32 &density) { - LLMaterialInfo *infop; - - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { infop->mDensity = density; @@ -368,10 +370,10 @@ BOOL LLMaterialTable::addDensity(U8 mcode, const F32 &density) BOOL LLMaterialTable::addRestitution(U8 mcode, const F32 &restitution) { - LLMaterialInfo *infop; - - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { infop->mRestitution = restitution; @@ -384,10 +386,10 @@ BOOL LLMaterialTable::addRestitution(U8 mcode, const F32 &restitution) BOOL LLMaterialTable::addFriction(U8 mcode, const F32 &friction) { - LLMaterialInfo *infop; - - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { infop->mFriction = friction; @@ -400,10 +402,10 @@ BOOL LLMaterialTable::addFriction(U8 mcode, const F32 &friction) BOOL LLMaterialTable::addDamageAndEnergy(U8 mcode, const F32 &hp_mod, const F32 &damage_mod, const F32 &ep_mod) { - LLMaterialInfo *infop; - - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { infop->mHPModifier = hp_mod; @@ -418,10 +420,10 @@ BOOL LLMaterialTable::addDamageAndEnergy(U8 mcode, const F32 &hp_mod, const F32 LLUUID LLMaterialTable::getDefaultTextureID(char* name) { - LLMaterialInfo *infop; - - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (!strcmp(name, infop->mName)) { return infop->mDefaultTextureID; @@ -434,12 +436,11 @@ LLUUID LLMaterialTable::getDefaultTextureID(char* name) LLUUID LLMaterialTable::getDefaultTextureID(U8 mcode) { - LLMaterialInfo *infop; - mcode &= LL_MCODE_MASK; - - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { return infop->mDefaultTextureID; @@ -452,10 +453,10 @@ LLUUID LLMaterialTable::getDefaultTextureID(U8 mcode) U8 LLMaterialTable::getMCode(const char* name) { - LLMaterialInfo *infop; - - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (!strcmp(name, infop->mName)) { return infop->mMCode; @@ -468,12 +469,11 @@ U8 LLMaterialTable::getMCode(const char* name) char* LLMaterialTable::getName(U8 mcode) { - LLMaterialInfo *infop; - mcode &= LL_MCODE_MASK; - - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { return infop->mName; @@ -569,11 +569,11 @@ LLUUID LLMaterialTable::getGroundCollisionParticleUUID(U8 mcode) F32 LLMaterialTable::getDensity(U8 mcode) { - LLMaterialInfo *infop; - mcode &= LL_MCODE_MASK; - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { return infop->mDensity; @@ -585,11 +585,11 @@ F32 LLMaterialTable::getDensity(U8 mcode) F32 LLMaterialTable::getRestitution(U8 mcode) { - LLMaterialInfo *infop; - mcode &= LL_MCODE_MASK; - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { return infop->mRestitution; @@ -601,11 +601,11 @@ F32 LLMaterialTable::getRestitution(U8 mcode) F32 LLMaterialTable::getFriction(U8 mcode) { - LLMaterialInfo *infop; - mcode &= LL_MCODE_MASK; - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { return infop->mFriction; @@ -617,11 +617,11 @@ F32 LLMaterialTable::getFriction(U8 mcode) F32 LLMaterialTable::getHPMod(U8 mcode) { - LLMaterialInfo *infop; - mcode &= LL_MCODE_MASK; - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { return infop->mHPModifier; @@ -633,11 +633,11 @@ F32 LLMaterialTable::getHPMod(U8 mcode) F32 LLMaterialTable::getDamageMod(U8 mcode) { - LLMaterialInfo *infop; - mcode &= LL_MCODE_MASK; - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { return infop->mDamageModifier; @@ -649,11 +649,11 @@ F32 LLMaterialTable::getDamageMod(U8 mcode) F32 LLMaterialTable::getEPMod(U8 mcode) { - LLMaterialInfo *infop; - mcode &= LL_MCODE_MASK; - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { return infop->mEPModifier; @@ -665,11 +665,11 @@ F32 LLMaterialTable::getEPMod(U8 mcode) LLUUID LLMaterialTable::getShatterSoundUUID(U8 mcode) { - LLMaterialInfo *infop; - mcode &= LL_MCODE_MASK; - for (infop = mMaterialInfoList.getFirstData(); infop != NULL; infop = mMaterialInfoList.getNextData() ) + for (info_list_t::iterator iter = mMaterialInfoList.begin(); + iter != mMaterialInfoList.end(); ++iter) { + LLMaterialInfo *infop = *iter; if (mcode == infop->mMCode) { return infop->mShatterSoundID; diff --git a/linden/indra/llprimitive/llmaterialtable.h b/linden/indra/llprimitive/llmaterialtable.h index b620238..b48c832 100644 --- a/linden/indra/llprimitive/llmaterialtable.h +++ b/linden/indra/llprimitive/llmaterialtable.h @@ -84,7 +84,9 @@ public: class LLMaterialTable { public: - LLLinkedList mMaterialInfoList; + typedef std::list info_list_t; + info_list_t mMaterialInfoList; + LLUUID *mCollisionSoundMatrix; LLUUID *mSlidingSoundMatrix; LLUUID *mRollingSoundMatrix; diff --git a/linden/indra/llprimitive/llprimitive_vc8.vcproj b/linden/indra/llprimitive/llprimitive_vc8.vcproj index a660023..860f88a 100644 --- a/linden/indra/llprimitive/llprimitive_vc8.vcproj +++ b/linden/indra/llprimitive/llprimitive_vc8.vcproj @@ -1,319 +1,319 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llprimitive/llprimitive_vc9.vcproj b/linden/indra/llprimitive/llprimitive_vc9.vcproj index 427e752..1e04970 100644 --- a/linden/indra/llprimitive/llprimitive_vc9.vcproj +++ b/linden/indra/llprimitive/llprimitive_vc9.vcproj @@ -1,320 +1,320 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llprimitive/lltextureentry.cpp b/linden/indra/llprimitive/lltextureentry.cpp index 9b13182..e1a4882 100644 --- a/linden/indra/llprimitive/lltextureentry.cpp +++ b/linden/indra/llprimitive/lltextureentry.cpp @@ -389,4 +389,3 @@ S32 LLTextureEntry::setGlow(F32 glow) } return 0; } - diff --git a/linden/indra/llrender/files.lst b/linden/indra/llrender/files.lst index a4d541e..3ada47b 100644 --- a/linden/indra/llrender/files.lst +++ b/linden/indra/llrender/files.lst @@ -1,5 +1,7 @@ llrender/llfont.cpp llrender/llfontgl.cpp llrender/llgldbg.cpp +llrender/llglimmediate.cpp llrender/llimagegl.cpp +llrender/llrendertarget.cpp llrender/llvertexbuffer.cpp diff --git a/linden/indra/llrender/llfontgl.cpp b/linden/indra/llrender/llfontgl.cpp index 99f68d6..bb60b70 100644 --- a/linden/indra/llrender/llfontgl.cpp +++ b/linden/indra/llrender/llfontgl.cpp @@ -36,6 +36,7 @@ #include "llfont.h" #include "llfontgl.h" #include "llgl.h" +#include "llglimmediate.h" #include "v4color.h" #include "llstl.h" @@ -556,8 +557,8 @@ S32 LLFontGL::render(const LLWString &wstr, BOOL use_embedded, BOOL use_ellipses) const { - LLGLEnable texture_2d(GL_TEXTURE_2D); - + LLGLEnable tex(GL_TEXTURE_2D); + if (wstr.empty()) { return 0; @@ -593,9 +594,9 @@ S32 LLFontGL::render(const LLWString &wstr, } } - glPushMatrix(); + gGL.pushMatrix(); glLoadIdentity(); - glTranslatef(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ); + gGL.translatef(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ); //glScalef(sScaleX, sScaleY, 1.0f); // avoid half pixels @@ -604,20 +605,20 @@ S32 LLFontGL::render(const LLWString &wstr, //F32 half_pixel_distance = llabs(fmodf(sCurOrigin.mX * sScaleX, 1.f) - 0.5f); //if (half_pixel_distance < PIXEL_BORDER_THRESHOLD) //{ - glTranslatef(PIXEL_CORRECTION_DISTANCE*sScaleX, 0.f, 0.f); + gGL.translatef(PIXEL_CORRECTION_DISTANCE*sScaleX, 0.f, 0.f); //} // this code would just snap to pixel grid, although it seems to introduce more jitter //F32 pixel_offset_x = llround(sCurOrigin.mX * sScaleX) - (sCurOrigin.mX * sScaleX); //F32 pixel_offset_y = llround(sCurOrigin.mY * sScaleY) - (sCurOrigin.mY * sScaleY); - //glTranslatef(-pixel_offset_x, -pixel_offset_y, 0.f); + //gGL.translatef(-pixel_offset_x, -pixel_offset_y, 0.f); // scale back to native pixel size //glScalef(1.f / sScaleX, 1.f / sScaleY, 1.f); //glScaled(1.0 / (F64) sScaleX, 1.0 / (F64) sScaleY, 1.0f); LLFastTimer t(LLFastTimer::FTM_RENDER_FONTS); - glColor4fv( color.mV ); + gGL.color4fv( color.mV ); S32 chars_drawn = 0; S32 i; @@ -638,7 +639,7 @@ S32 LLFontGL::render(const LLWString &wstr, mImageGLp->bind(0); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Not guaranteed to be set correctly + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Not guaranteed to be set correctly cur_x = ((F32)x * sScaleX); cur_y = ((F32)y * sScaleY); @@ -743,9 +744,9 @@ S32 LLFontGL::render(const LLWString &wstr, if (!label.empty()) { - glPushMatrix(); + gGL.pushMatrix(); //glLoadIdentity(); - //glTranslatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f); + //gGL.translatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f); //glScalef(sScaleX, sScaleY, 1.f); gExtCharFont->render(label, 0, /*llfloor*/((ext_x + (F32)ext_image->getWidth() + EXT_X_BEARING) / sScaleX), @@ -753,10 +754,10 @@ S32 LLFontGL::render(const LLWString &wstr, color, halign, BASELINE, NORMAL, S32_MAX, S32_MAX, NULL, TRUE ); - glPopMatrix(); + gGL.popMatrix(); } - glColor4fv(color.mV); + gGL.color4fv(color.mV); chars_drawn++; cur_x += ext_advance; @@ -836,10 +837,10 @@ S32 LLFontGL::render(const LLWString &wstr, if (style & UNDERLINE) { LLGLSNoTexture no_texture; - glBegin(GL_LINES); - glVertex2f(start_x, cur_y - (mDescender)); - glVertex2f(cur_x, cur_y - (mDescender)); - glEnd(); + gGL.begin(GL_LINES); + gGL.vertex2f(start_x, cur_y - (mDescender)); + gGL.vertex2f(cur_x, cur_y - (mDescender)); + gGL.end(); } // *FIX: get this working in all alignment cases, etc. @@ -847,9 +848,9 @@ S32 LLFontGL::render(const LLWString &wstr, { // recursively render ellipses at end of string // we've already reserved enough room - glPushMatrix(); + gGL.pushMatrix(); //glLoadIdentity(); - //glTranslatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f); + //gGL.translatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f); //glScalef(sScaleX, sScaleY, 1.f); renderUTF8("...", 0, @@ -860,10 +861,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32_MAX, max_pixels, right_x, FALSE); - glPopMatrix(); + gGL.popMatrix(); } - glPopMatrix(); + gGL.popMatrix(); return chars_drawn; } @@ -1309,20 +1310,20 @@ void LLFontGL::removeEmbeddedChar( llwchar wc ) void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const { - glTexCoord2f(uv_rect.mRight, uv_rect.mTop); - glVertex2f(llfont_round_x(screen_rect.mRight), + gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); + gGL.vertex2f(llfont_round_x(screen_rect.mRight), llfont_round_y(screen_rect.mTop)); - glTexCoord2f(uv_rect.mLeft, uv_rect.mTop); - glVertex2f(llfont_round_x(screen_rect.mLeft), + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); + gGL.vertex2f(llfont_round_x(screen_rect.mLeft), llfont_round_y(screen_rect.mTop)); - glTexCoord2f(uv_rect.mLeft, uv_rect.mBottom); - glVertex2f(llfont_round_x(screen_rect.mLeft + slant_amt), + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); + gGL.vertex2f(llfont_round_x(screen_rect.mLeft + slant_amt), llfont_round_y(screen_rect.mBottom)); - glTexCoord2f(uv_rect.mRight, uv_rect.mBottom); - glVertex2f(llfont_round_x(screen_rect.mRight + slant_amt), + gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); + gGL.vertex2f(llfont_round_x(screen_rect.mRight + slant_amt), llfont_round_y(screen_rect.mBottom)); } @@ -1331,13 +1332,13 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con F32 slant_offset; slant_offset = ((style & ITALIC) ? ( -mAscender * 0.2f) : 0.f); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { //FIXME: bold and drop shadow are mutually exclusive only for convenience //Allow both when we need them. if (style & BOLD) { - glColor4fv(color.mV); + gGL.color4fv(color.mV); for (S32 pass = 0; pass < 2; pass++) { LLRectf screen_rect_offset = screen_rect; @@ -1350,7 +1351,7 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con { LLColor4 shadow_color = LLFontGL::sShadowColor; shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH; - glColor4fv(shadow_color.mV); + gGL.color4fv(shadow_color.mV); for (S32 pass = 0; pass < 5; pass++) { LLRectf screen_rect_offset = screen_rect; @@ -1376,28 +1377,28 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con renderQuad(screen_rect_offset, uv_rect, slant_offset); } - glColor4fv(color.mV); + gGL.color4fv(color.mV); renderQuad(screen_rect, uv_rect, slant_offset); } else if (style & DROP_SHADOW) { LLColor4 shadow_color = LLFontGL::sShadowColor; shadow_color.mV[VALPHA] = color.mV[VALPHA] * drop_shadow_strength; - glColor4fv(shadow_color.mV); + gGL.color4fv(shadow_color.mV); LLRectf screen_rect_shadow = screen_rect; screen_rect_shadow.translate(1.f, -1.f); renderQuad(screen_rect_shadow, uv_rect, slant_offset); - glColor4fv(color.mV); + gGL.color4fv(color.mV); renderQuad(screen_rect, uv_rect, slant_offset); } else // normal rendering { - glColor4fv(color.mV); + gGL.color4fv(color.mV); renderQuad(screen_rect, uv_rect, slant_offset); } } - glEnd(); + gGL.end(); } // static diff --git a/linden/indra/llrender/llglimmediate.cpp b/linden/indra/llrender/llglimmediate.cpp new file mode 100644 index 0000000..db62f3d --- /dev/null +++ b/linden/indra/llrender/llglimmediate.cpp @@ -0,0 +1,354 @@ +/** + * @file llglimmediate.cpp + * @brief LLGLImmediate implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llglimmediate.h" +#include "llvertexbuffer.h" + +LLGLImmediate gGL; + +#ifdef LL_RELEASE_FOR_DOWNLOAD +#define IMM_ERRS llwarns +#else +#define IMM_ERRS llerrs +#endif + +bool LLGLImmediate::sClever = false; + +static BOOL sStarted = FALSE; + +LLGLImmediate::LLGLImmediate() +{ + mCount = 0; + mMode = GL_TRIANGLES; + memset(mBuffer, 0, sizeof(Vertex)*4096); +} + +void LLGLImmediate::start() +{ + if(sClever) + { + if (sStarted) + { + llerrs << "Redundant start." << llendl; + } + + sStarted = TRUE; + LLVertexBuffer::unbind(); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + const U32 stride = sizeof(Vertex); + + glVertexPointer(3, GL_FLOAT, stride, &(mBuffer[0].v)); + glTexCoordPointer(2, GL_FLOAT, stride, &(mBuffer[0].uv)); + glColorPointer(4, GL_UNSIGNED_BYTE, stride, &(mBuffer[0].c)); + + color4f(1,1,1,1); + } +} + +void LLGLImmediate::stop() +{ + if (sClever) + { + if (!sStarted) + { + llerrs << "Redundant stop." << llendl; + } + + flush(); + + sStarted = FALSE; + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } +} + +void LLGLImmediate::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) +{ + flush(); + glTranslatef(x,y,z); +} + +void LLGLImmediate::pushMatrix() +{ + flush(); + glPushMatrix(); +} + +void LLGLImmediate::popMatrix() +{ + flush(); + glPopMatrix(); +} + +void LLGLImmediate::blendFunc(GLenum sfactor, GLenum dfactor) +{ + if (sStarted) + { + flush(); + } + glBlendFunc(sfactor, dfactor); +} + +void LLGLImmediate::begin(const GLuint& mode) +{ + if (sClever) + { + if (mode != mMode) + { + if (mMode == GL_QUADS || + mMode == GL_LINES || + mMode == GL_TRIANGLES || + mMode == GL_POINTS) + { + flush(); + } + else if (mCount != 0) + { + llerrs << "gGL.begin() called redundantly." << llendl; + } + + mMode = mode; + } + } + else + { + glBegin(mode); + } +} + +void LLGLImmediate::end() +{ + if (sClever) + { + if (mCount == 0) + { + IMM_ERRS << "GL begin and end called with no vertices specified." << llendl; + } + + if ((mMode != GL_QUADS && + mMode != GL_LINES && + mMode != GL_TRIANGLES && + mMode != GL_POINTS) || + mCount > 2048) + { + flush(); + } + } + else + { + glEnd(); + } +} + +void LLGLImmediate::flush() +{ + if (sClever) + { + if (mCount > 0) + { +#if 0 + if (!glIsEnabled(GL_VERTEX_ARRAY)) + { + llerrs << "foo 1" << llendl; + } + + if (!glIsEnabled(GL_COLOR_ARRAY)) + { + llerrs << "foo 2" << llendl; + } + + if (!glIsEnabled(GL_TEXTURE_COORD_ARRAY)) + { + llerrs << "foo 3" << llendl; + } + + if (glIsEnabled(GL_NORMAL_ARRAY)) + { + llerrs << "foo 7" << llendl; + } + + GLvoid* pointer; + + glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer); + if (pointer != &(mBuffer[0].v)) + { + llerrs << "foo 4" << llendl; + } + + glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer); + if (pointer != &(mBuffer[0].c)) + { + llerrs << "foo 5" << llendl; + } + + glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer); + if (pointer != &(mBuffer[0].uv)) + { + llerrs << "foo 6" << llendl; + } +#endif + if (!sStarted) + { + llerrs << "Drawing call issued outside start/stop." << llendl; + } + glDrawArrays(mMode, 0, mCount); + mBuffer[0] = mBuffer[mCount]; + mCount = 0; + } + } +} + +void LLGLImmediate::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) +{ + if (sClever) + { + if (mCount >= 4096) + { + // llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl; + return; + } + + mBuffer[mCount].v[0] = x; + mBuffer[mCount].v[1] = y; + mBuffer[mCount].v[2] = z; + mCount++; + if (mCount < 4096) + { + mBuffer[mCount] = mBuffer[mCount-1]; + } + } + else + { + glVertex3f(x,y,z); + } +} + +void LLGLImmediate::vertex2i(const GLint& x, const GLint& y) +{ + vertex3f((GLfloat) x, (GLfloat) y, 0); +} + +void LLGLImmediate::vertex2f(const GLfloat& x, const GLfloat& y) +{ + vertex3f(x,y,0); +} + +void LLGLImmediate::vertex2fv(const GLfloat* v) +{ + vertex3f(v[0], v[1], 0); +} + +void LLGLImmediate::vertex3fv(const GLfloat* v) +{ + vertex3f(v[0], v[1], v[2]); +} + +void LLGLImmediate::texCoord2f(const GLfloat& x, const GLfloat& y) +{ + if (sClever) + { + mBuffer[mCount].uv[0] = x; + mBuffer[mCount].uv[1] = y; + } + else + { + glTexCoord2f(x,y); + } +} + +void LLGLImmediate::texCoord2i(const GLint& x, const GLint& y) +{ + texCoord2f((GLfloat) x, (GLfloat) y); +} + +void LLGLImmediate::texCoord2fv(const GLfloat* tc) +{ + texCoord2f(tc[0], tc[1]); +} + +void LLGLImmediate::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a) +{ + if (sClever) + { + mBuffer[mCount].c[0] = r; + mBuffer[mCount].c[1] = g; + mBuffer[mCount].c[2] = b; + mBuffer[mCount].c[3] = a; + } + else + { + glColor4ub(r,g,b,a); + } +} + +void LLGLImmediate::color4ubv(const GLubyte* c) +{ + color4ub(c[0], c[1], c[2], c[3]); +} + +void LLGLImmediate::color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a) +{ + color4ub((GLubyte) (llclamp(r, 0.f, 1.f)*255), + (GLubyte) (llclamp(g, 0.f, 1.f)*255), + (GLubyte) (llclamp(b, 0.f, 1.f)*255), + (GLubyte) (llclamp(a, 0.f, 1.f)*255)); +} + +void LLGLImmediate::color4fv(const GLfloat* c) +{ + color4f(c[0],c[1],c[2],c[3]); +} + +void LLGLImmediate::color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b) +{ + color4f(r,g,b,1); +} + +void LLGLImmediate::color3fv(const GLfloat* c) +{ + color4f(c[0],c[1],c[2],1); +} + +void LLGLImmediate::setClever(bool do_clever) +{ + llassert(!sStarted); + llassert(mCount == 0); + + sClever = do_clever; +} + diff --git a/linden/indra/llrender/llglimmediate.h b/linden/indra/llrender/llglimmediate.h new file mode 100644 index 0000000..bf2f9ab --- /dev/null +++ b/linden/indra/llrender/llglimmediate.h @@ -0,0 +1,104 @@ +/** + * @file llglimmediate.h + * @brief LLGLImmediate definition + * + * This class acts as a wrapper for OpenGL immediate calls concerning glBegin and glEnd. + * The goal of this class is to minimize the number of api calls due to legacy rendering + * code, and to define an interface for a multiple rendering API abstraction of the UI + * rendering. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLGLIMMEDIATE_H +#define LL_LLGLIMMEDIATE_H + +#include "stdtypes.h" +#include "llgltypes.h" +#include "llglheaders.h" + +class LLGLImmediate +{ +public: + LLGLImmediate(); + + void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z); + void pushMatrix(); + void popMatrix(); + void blendFunc(GLenum sfactor, GLenum dfactor); + void start(); + void stop(); + void flush(); + + void begin(const GLuint& mode); + void end(); + void vertex2i(const GLint& x, const GLint& y); + void vertex2f(const GLfloat& x, const GLfloat& y); + void vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z); + void vertex2fv(const GLfloat* v); + void vertex3fv(const GLfloat* v); + + void texCoord2i(const GLint& x, const GLint& y); + void texCoord2f(const GLfloat& x, const GLfloat& y); + void texCoord2fv(const GLfloat* tc); + + void color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a); + void color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a); + void color4fv(const GLfloat* c); + void color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b); + void color3fv(const GLfloat* c); + void color4ubv(const GLubyte* c); + + // switch clever mode GL immediate rendering on or off. Setting to true builds + // client arrays manually, setting to false passes through the GL immediate mode + // commands to the GL implementation. Controllable by the RenderUseCleverUI + // debug setting. + // *NOTE: I have measured that this has about a 9% performance cost (0.6ms) for the + // Render/UI fasttimer vs the old #if CLEVER compile time switch. Dave Parks and I + // agreed that this was acceptable at the time due to it enabling better regression + // testing for QA. + // -Brad + void setClever(bool do_clever); + + typedef struct Vertex + { + GLfloat v[3]; + GLubyte c[4]; + GLfloat uv[2]; + }; + +private: + static bool sClever; + + U32 mCount; + U32 mMode; + Vertex mBuffer[4096]; +}; + +extern LLGLImmediate gGL; + +#endif diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp index b2b08e0..76c8252 100644 --- a/linden/indra/llrender/llimagegl.cpp +++ b/linden/indra/llrender/llimagegl.cpp @@ -41,6 +41,8 @@ #include "llmath.h" #include "llgl.h" +#include "llglimmediate.h" + //---------------------------------------------------------------------------- @@ -49,6 +51,8 @@ const F32 MIN_TEXTURE_LIFETIME = 10.f; //statics LLGLuint LLImageGL::sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS] = { 0 }; +U32 LLImageGL::sUniqueCount = 0; +U32 LLImageGL::sBindCount = 0; S32 LLImageGL::sGlobalTextureMemory = 0; S32 LLImageGL::sBoundTextureMemory = 0; S32 LLImageGL::sCurBoundTextureMemory = 0; @@ -123,6 +127,7 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat) // static void LLImageGL::bindExternalTexture(LLGLuint gl_name, S32 stage, LLGLenum bind_target ) { + gGL.flush(); glActiveTextureARB(GL_TEXTURE0_ARB + stage); glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); glBindTexture(bind_target, gl_name); @@ -135,6 +140,7 @@ void LLImageGL::unbindTexture(S32 stage, LLGLenum bind_target) // LLGLSLShader can return -1 if (stage >= 0) { + gGL.flush(); glActiveTextureARB(GL_TEXTURE0_ARB + stage); glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); glBindTexture(bind_target, 0); @@ -148,6 +154,7 @@ void LLImageGL::unbindTexture(S32 stage) // LLGLSLShader can return -1 if (stage >= 0) { + gGL.flush(); glActiveTextureARB(GL_TEXTURE0_ARB + stage); glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); glBindTexture(GL_TEXTURE_2D, 0); @@ -411,6 +418,7 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const llwarns << "Trying to bind a texture while GL is disabled!" << llendl; } + glActiveTextureARB(GL_TEXTURE0_ARB + stage); if (sCurrentBoundTextures[stage] && sCurrentBoundTextures[stage] == mTexName) @@ -425,12 +433,15 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const mMissed = ! getIsResident(TRUE); #endif + gGL.flush(); glBindTexture(mBindTarget, mTexName); sCurrentBoundTextures[stage] = mTexName; + sBindCount++; if (mLastBindTime != sLastFrameTime) { // we haven't accounted for this texture yet this frame + sUniqueCount++; updateBoundTexMem(mTextureMemory); mLastBindTime = sLastFrameTime; } @@ -439,6 +450,7 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const } else { + gGL.flush(); glBindTexture(mBindTarget, 0); sCurrentBoundTextures[stage] = 0; return FALSE; @@ -665,7 +677,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } mHasMipMaps = FALSE; } - glFlush(); stop_glerror(); } @@ -686,7 +697,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 return FALSE; } - if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight()) + if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height) { setImage(datap, FALSE); } @@ -759,7 +770,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); stop_glerror(); } - glFlush(); + return TRUE; } @@ -1046,6 +1057,7 @@ void LLImageGL::destroyGLTexture() { unbindTexture(i, GL_TEXTURE_2D); stop_glerror(); + glActiveTextureARB(GL_TEXTURE0_ARB); } } diff --git a/linden/indra/llrender/llimagegl.h b/linden/indra/llrender/llimagegl.h index afcb763..efe94c2 100644 --- a/linden/indra/llrender/llimagegl.h +++ b/linden/indra/llrender/llimagegl.h @@ -185,7 +185,8 @@ public: static S32 sGlobalTextureMemory; // Tracks main memory texmem static S32 sBoundTextureMemory; // Tracks bound texmem for last completed frame static S32 sCurBoundTextureMemory; // Tracks bound texmem for current frame - + static U32 sBindCount; // Tracks number of texture binds for current frame + static U32 sUniqueCount; // Tracks number of unique texture binds for current frame static BOOL sGlobalUseAnisotropic; #if DEBUG_MISS diff --git a/linden/indra/llrender/llrender.vcproj b/linden/indra/llrender/llrender.vcproj index ac9aa2e..2c6e2d2 100644 --- a/linden/indra/llrender/llrender.vcproj +++ b/linden/indra/llrender/llrender.vcproj @@ -165,9 +165,15 @@ RelativePath=".\llgldbg.cpp"> + + + + @@ -200,9 +206,15 @@ RelativePath=".\llgldbg.h"> + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llrender/llrender_vc9.vcproj b/linden/indra/llrender/llrender_vc9.vcproj index e4bc1b6..08e3362 100644 --- a/linden/indra/llrender/llrender_vc9.vcproj +++ b/linden/indra/llrender/llrender_vc9.vcproj @@ -1,314 +1,330 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llrender/llrendertarget.cpp b/linden/indra/llrender/llrendertarget.cpp new file mode 100644 index 0000000..974e0a2 --- /dev/null +++ b/linden/indra/llrender/llrendertarget.cpp @@ -0,0 +1,185 @@ +/** + * @file llrendertarget.cpp + * @brief LLRenderTarget implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llrendertarget.h" +#include "llglimmediate.h" + + +BOOL LLRenderTarget::sUseFBO = FALSE; + +LLRenderTarget::LLRenderTarget() +{ + mResX = mResY = mTex = mFBO = mDepth = 0; + mUseDepth = FALSE; + mUsage = GL_TEXTURE_2D; +} + +LLRenderTarget::~LLRenderTarget() +{ + release(); +} + +void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage, BOOL force_fbo) +{ + mResX = resx; + mResY = resy; + + mUsage = usage; + mUseDepth = depth; + release(); + + glGenTextures(1, (GLuint *) &mTex); + glBindTexture(mUsage, mTex); + glTexImage2D(mUsage, 0, color_fmt, mResX, mResY, 0, color_fmt, GL_UNSIGNED_BYTE, NULL); + + glTexParameteri(mUsage, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(mUsage, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + if (mUsage != GL_TEXTURE_RECTANGLE_ARB) + { + glTexParameteri(mUsage, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTexParameteri(mUsage, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + } + else + { + // ATI doesn't support mirrored repeat for rectangular textures. + glTexParameteri(mUsage, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(mUsage, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + stop_glerror(); + + if (sUseFBO || force_fbo) + { + if (depth) + { + glGenRenderbuffersEXT(1, (GLuint *) &mDepth); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepth); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT,mResX,mResY); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + + glGenFramebuffersEXT(1, (GLuint *) &mFBO); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); + + if (mDepth) + { + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, mDepth); + } + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + mUsage, mTex, 0); + + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } +} + +void LLRenderTarget::release() +{ + if (mFBO) + { + glDeleteFramebuffersEXT(1, (GLuint *) &mFBO); + mFBO = 0; + } + + if (mTex) + { + glDeleteTextures(1, (GLuint *) &mTex); + mTex = 0; + } + + if (mDepth) + { + glDeleteRenderbuffersEXT(1, (GLuint *) &mDepth); + mDepth = 0; + } +} + +void LLRenderTarget::bindTarget() +{ + if (mFBO) + { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); + } + + glViewport(0, 0, mResX, mResY); +} + +void LLRenderTarget::clear() +{ + U32 mask = GL_COLOR_BUFFER_BIT; + if (mUseDepth) + { + mask |= GL_DEPTH_BUFFER_BIT; + } + if (mFBO) + { + glClear(mask); + } + else + { + LLGLEnable scissor(GL_SCISSOR_TEST); + glScissor(0, 0, mResX, mResY); + glClear(mask); + } +} + +void LLRenderTarget::bindTexture() +{ + glBindTexture(mUsage, mTex); +} + +void LLRenderTarget::flush() +{ + gGL.flush(); + if (!mFBO) + { + bindTexture(); + glCopyTexSubImage2D(mUsage, 0, 0, 0, 0, 0, mResX, mResY); + } +} + +BOOL LLRenderTarget::isComplete() const +{ + return (mTex || mDepth) ? TRUE : FALSE; +} + +void LLRenderTarget::getViewport(S32* viewport) +{ + viewport[0] = 0; + viewport[1] = 0; + viewport[2] = mResX; + viewport[3] = mResY; +} + diff --git a/linden/indra/llrender/llrendertarget.h b/linden/indra/llrender/llrendertarget.h new file mode 100644 index 0000000..cc36146 --- /dev/null +++ b/linden/indra/llrender/llrendertarget.h @@ -0,0 +1,116 @@ +/** + * @file llrendertarget.h + * @brief Off screen render target abstraction. Loose wrapper for GL_EXT_framebuffer_objects. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLRENDERTARGET_H +#define LL_LLRENDERTARGET_H + +#include "llgl.h" + +/* + SAMPLE USAGE: + + LLFBOTarget target; + + ... + + //allocate a 256x256 RGBA render target with depth buffer + target.allocate(256,256,GL_RGBA,TRUE); + + //render to contents of offscreen buffer + target.bindTarget(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + ... ... + target.flush(); + + ... + + //use target as a texture + target.bindTexture(); + ... ... + +*/ + + +class LLRenderTarget +{ +public: + //whether or not to use FBO implementation + static BOOL sUseFBO; + + LLRenderTarget(); + ~LLRenderTarget(); + + //allocate resources for rendering + //must be called before use + //multiple calls will release previously allocated resources + void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage = GL_TEXTURE_2D, BOOL force_fbo = FALSE); + + //free any allocated resources + //safe to call redundantly + void release(); + + //bind target for rendering + //applies appropriate viewport + void bindTarget(); + + //clear render targer, clears depth buffer if present, + //uses scissor rect if in copy-to-texture mode + void clear(); + + //get applied viewport + void getViewport(S32* viewport); + + //bind results of render for sampling + void bindTexture(); + + //flush rendering operations + //must be called when rendering is complete + //should be used 1:1 with bindTarget + // call bindTarget once, do all your rendering, call flush once + void flush(); + + //Returns TRUE if target is ready to be rendered into. + //That is, if the target has been allocated with at least + //one renderable attachment (i.e. color buffer, depth buffer). + BOOL isComplete() const; + +private: + U32 mResX; + U32 mResY; + U32 mTex; + U32 mFBO; + U32 mDepth; + BOOL mUseDepth; + U32 mUsage; +}; + +#endif + diff --git a/linden/indra/llrender/llvertexbuffer.cpp b/linden/indra/llrender/llvertexbuffer.cpp index d19e885..f3c6997 100644 --- a/linden/indra/llrender/llvertexbuffer.cpp +++ b/linden/indra/llrender/llvertexbuffer.cpp @@ -31,6 +31,8 @@ #include "linden_common.h" +#include + #include "llvertexbuffer.h" // #include "llrender.h" #include "llglheaders.h" @@ -40,8 +42,16 @@ //============================================================================ //static +LLVBOPool LLVertexBuffer::sStreamVBOPool; +LLVBOPool LLVertexBuffer::sDynamicVBOPool; +LLVBOPool LLVertexBuffer::sStreamIBOPool; +LLVBOPool LLVertexBuffer::sDynamicIBOPool; + +U32 LLVertexBuffer::sBindCount = 0; +U32 LLVertexBuffer::sSetCount = 0; S32 LLVertexBuffer::sCount = 0; S32 LLVertexBuffer::sGLCount = 0; +S32 LLVertexBuffer::sMappedCount = 0; BOOL LLVertexBuffer::sEnableVBOs = TRUE; U32 LLVertexBuffer::sGLRenderBuffer = 0; U32 LLVertexBuffer::sGLRenderIndices = 0; @@ -50,9 +60,9 @@ BOOL LLVertexBuffer::sVBOActive = FALSE; BOOL LLVertexBuffer::sIBOActive = FALSE; U32 LLVertexBuffer::sAllocatedBytes = 0; BOOL LLVertexBuffer::sRenderActive = FALSE; +BOOL LLVertexBuffer::sMapped = FALSE; std::vector LLVertexBuffer::sDeleteList; -LLVertexBuffer::buffer_list_t LLVertexBuffer::sLockedList; S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] = { @@ -70,6 +80,10 @@ S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] = void LLVertexBuffer::initClass(bool use_vbo) { sEnableVBOs = use_vbo; + LLGLNamePool::registerPool(&sDynamicVBOPool); + LLGLNamePool::registerPool(&sDynamicIBOPool); + LLGLNamePool::registerPool(&sStreamVBOPool); + LLGLNamePool::registerPool(&sStreamIBOPool); } //static @@ -88,13 +102,13 @@ void LLVertexBuffer::unbind() sGLRenderBuffer = 0; sGLRenderIndices = 0; + sLastMask = 0; } //static void LLVertexBuffer::cleanupClass() { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); - sLockedList.clear(); startRender(); stopRender(); clientCopy(); // deletes GL buffers @@ -127,41 +141,8 @@ void LLVertexBuffer::clientCopy(F64 max_time) { if (!sDeleteList.empty()) { - size_t num = sDeleteList.size(); glDeleteBuffersARB(sDeleteList.size(), (GLuint*) &(sDeleteList[0])); sDeleteList.clear(); - sGLCount -= num; - } - - if (sEnableVBOs) - { - LLTimer timer; - BOOL reset = TRUE; - buffer_list_t::iterator iter = sLockedList.begin(); - while(iter != sLockedList.end()) - { - LLVertexBuffer* buffer = *iter; - if (buffer->isLocked() && buffer->useVBOs()) - { - buffer->setBuffer(0); - } - ++iter; - if (reset) - { - reset = FALSE; - timer.reset(); //skip first copy (don't count pipeline stall) - } - else - { - if (timer.getElapsedTimeF64() > max_time) - { - break; - } - } - - } - - sLockedList.erase(sLockedList.begin(), iter); } } @@ -175,27 +156,40 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mFinal(FALSE), mFilthy(FALSE), mEmpty(TRUE), - mResized(FALSE) + mResized(FALSE), + mDynamicSize(FALSE) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (!sEnableVBOs) { - mUsage = GL_STREAM_DRAW_ARB; + mUsage = 0 ; } + S32 stride = calcStride(typemask, mOffsets); + + mTypeMask = typemask; + mStride = stride; + sCount++; +} + +//static +S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets) +{ S32 stride = 0; for (S32 i=0; i= 65535) + { + llwarns << "Vertex buffer overflow!" << llendl; + nverts = 65535; + } + + mRequestedNumVerts = nverts; + if (!mDynamicSize) { mNumVerts = nverts; @@ -336,18 +410,19 @@ void LLVertexBuffer::updateNumVerts(S32 nverts) nverts > mNumVerts || nverts < mNumVerts/2) { - if (mUsage != GL_STATIC_DRAW_ARB) + if (mUsage != GL_STATIC_DRAW_ARB && nverts + nverts/4 <= 65535) { nverts += nverts/4; } - mNumVerts = nverts; } + } void LLVertexBuffer::updateNumIndices(S32 nindices) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + mRequestedNumIndices = nindices; if (!mDynamicSize) { mNumIndices = nindices; @@ -365,54 +440,6 @@ void LLVertexBuffer::updateNumIndices(S32 nindices) } } -void LLVertexBuffer::makeStatic() -{ - if (!sEnableVBOs) - { - return; - } - - if (sRenderActive) - { - llerrs << "Make static called during render." << llendl; - } - - if (mUsage != GL_STATIC_DRAW_ARB) - { - if (useVBOs()) - { - if (mGLBuffer) - { - sDeleteList.push_back(mGLBuffer); - } - if (mGLIndices) - { - sDeleteList.push_back(mGLIndices); - } - } - - if (mGLBuffer) - { - sGLCount++; - glGenBuffersARB(1, (GLuint*) &mGLBuffer); - } - if (mGLIndices) - { - sGLCount++; - glGenBuffersARB(1, (GLuint*) &mGLIndices); - } - - mUsage = GL_STATIC_DRAW_ARB; - mResized = TRUE; - - if (!mLocked) - { - mLocked = TRUE; - sLockedList.push_back(this); - } - } -} - void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); @@ -435,6 +462,9 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) { + mRequestedNumVerts = newnverts; + mRequestedNumIndices = newnindices; + LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); mDynamicSize = TRUE; if (mUsage == GL_STATIC_DRAW_ARB) @@ -469,22 +499,25 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) else { //delete old buffer, keep GL buffer for now - U8* old = mMappedData; - mMappedData = new U8[newsize]; - if (old) - { - memcpy(mMappedData, old, llmin(newsize, oldsize)); - if (newsize > oldsize) + if (!useVBOs()) + { + U8* old = mMappedData; + mMappedData = new U8[newsize]; + if (old) + { + memcpy(mMappedData, old, llmin(newsize, oldsize)); + if (newsize > oldsize) + { + memset(mMappedData+oldsize, 0, newsize-oldsize); + } + + delete [] old; + } + else { - memset(mMappedData+oldsize, 0, newsize-oldsize); + memset(mMappedData, 0, newsize); + mEmpty = TRUE; } - - delete [] old; - } - else - { - memset(mMappedData, 0, newsize); - mEmpty = TRUE; } mResized = TRUE; } @@ -502,22 +535,26 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) } else { - //delete old buffer, keep GL buffer for now - U8* old = mMappedIndexData; - mMappedIndexData = new U8[new_index_size]; - if (old) - { - memcpy(mMappedIndexData, old, llmin(new_index_size, old_index_size)); - if (new_index_size > old_index_size) + if (!useVBOs()) + { + //delete old buffer, keep GL buffer for now + U8* old = mMappedIndexData; + mMappedIndexData = new U8[new_index_size]; + + if (old) + { + memcpy(mMappedIndexData, old, llmin(new_index_size, old_index_size)); + if (new_index_size > old_index_size) + { + memset(mMappedIndexData+old_index_size, 0, new_index_size - old_index_size); + } + delete [] old; + } + else { - memset(mMappedIndexData+old_index_size, 0, new_index_size - old_index_size); + memset(mMappedIndexData, 0, new_index_size); + mEmpty = TRUE; } - delete [] old; - } - else - { - memset(mMappedIndexData, 0, new_index_size); - mEmpty = TRUE; } mResized = TRUE; } @@ -527,18 +564,29 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) destroyGLIndices(); } } + + if (mResized && useVBOs()) + { + setBuffer(0); + } } BOOL LLVertexBuffer::useVBOs() const { - //it's generally ineffective to use VBO for things that are streaming - //when we already have a client buffer around - if (mUsage == GL_STREAM_DRAW_ARB) + //it's generally ineffective to use VBO for things that are streaming on apple + +#if LL_DARWIN + if (!mUsage || mUsage == GL_STREAM_DRAW_ARB) { return FALSE; } - - return sEnableVBOs && (!sRenderActive || !mLocked); +#else + if (!mUsage) + { + return FALSE; + } +#endif + return sEnableVBOs; // && (!sRenderActive || !mLocked); } //---------------------------------------------------------------------------- @@ -547,27 +595,27 @@ BOOL LLVertexBuffer::useVBOs() const U8* LLVertexBuffer::mapBuffer(S32 access) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); - if (sRenderActive) - { - llwarns << "Buffer mapped during render frame!" << llendl; - } - if (!mGLBuffer && !mGLIndices) - { - llerrs << "LLVertexBuffer::mapBuffer() called before createGLBuffer" << llendl; - } if (mFinal) { llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; } - if (!mMappedData && !mMappedIndexData) + if (!useVBOs() && !mMappedData && !mMappedIndexData) { llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; } - + if (!mLocked && useVBOs()) { + setBuffer(0); mLocked = TRUE; - sLockedList.push_back(this); + mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + /*if (sMapped) + { + llerrs << "Mapped two VBOs at the same time!" << llendl; + } + sMapped = TRUE;*/ + sMappedCount++; } return mMappedData; @@ -580,64 +628,19 @@ void LLVertexBuffer::unmapBuffer() { if (useVBOs() && mLocked) { - if (mGLBuffer) - { - if (mResized) - { - glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), mMappedData, mUsage); - } - else - { - if (mEmpty || mDirtyRegions.empty()) - { - glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData); - } - else - { - for (std::vector::iterator i = mDirtyRegions.begin(); i != mDirtyRegions.end(); ++i) - { - DirtyRegion& region = *i; - glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, region.mIndex*mStride, region.mCount*mStride, mMappedData + region.mIndex*mStride); - } - } - } - } - - if (mGLIndices) + glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); + glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); + + /*if (!sMapped) { - if (mResized) - { - glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), mMappedIndexData, mUsage); - } - else - { - if (mEmpty || mDirtyRegions.empty()) - { - glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData); - } - else - { - for (std::vector::iterator i = mDirtyRegions.begin(); i != mDirtyRegions.end(); ++i) - { - DirtyRegion& region = *i; - glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, region.mIndicesIndex*sizeof(U32), - region.mIndicesCount*sizeof(U32), mMappedIndexData + region.mIndicesIndex*sizeof(U32)); - } - } - } + llerrs << "Redundantly unmapped VBO!" << llendl; } - - mDirtyRegions.clear(); - mFilthy = FALSE; - mResized = FALSE; + sMapped = FALSE;*/ + sMappedCount--; if (mUsage == GL_STATIC_DRAW_ARB) { //static draw buffers can only be mapped a single time //throw out client data (we won't be using it again) - delete [] mMappedData; - delete [] mMappedIndexData; - mMappedIndexData = NULL; - mMappedData = NULL; mEmpty = TRUE; mFinal = TRUE; } @@ -645,10 +648,11 @@ void LLVertexBuffer::unmapBuffer() { mEmpty = FALSE; } + + mMappedIndexData = NULL; + mMappedData = NULL; mLocked = FALSE; - - glFlush(); } } } @@ -690,9 +694,9 @@ bool LLVertexBuffer::getVertexStrider(LLStrider& strider, S32 index) { return VertexBufferStrider::get(*this, strider, index); } -bool LLVertexBuffer::getIndexStrider(LLStrider& strider, S32 index) +bool LLVertexBuffer::getIndexStrider(LLStrider& strider, S32 index) { - return VertexBufferStrider::get(*this, strider, index); + return VertexBufferStrider::get(*this, strider, index); } bool LLVertexBuffer::getTexCoordStrider(LLStrider& strider, S32 index) { @@ -755,16 +759,46 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)) { + /*if (sMapped) + { + llerrs << "VBO bound while another VBO mapped!" << llendl; + }*/ glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); + sBindCount++; sVBOActive = TRUE; setup = TRUE; // ... or the bound buffer changed } if (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)) { + /*if (sMapped) + { + llerrs << "VBO bound while another VBO mapped!" << llendl; + }*/ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); + sBindCount++; sIBOActive = TRUE; } + if (mResized) + { + if (mGLBuffer) + { + glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage); + } + if (mGLIndices) + { + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage); + } + + mEmpty = TRUE; + mResized = FALSE; + + if (data_mask != 0) + { + llerrs << "Buffer set for rendering before being filled after resize." << llendl; + } + } + unmapBuffer(); } else @@ -774,6 +808,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (sEnableVBOs && sVBOActive) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + sBindCount++; sVBOActive = FALSE; setup = TRUE; // ... or a VBO is deactivated } @@ -784,7 +819,12 @@ void LLVertexBuffer::setBuffer(U32 data_mask) } if (sEnableVBOs && mGLIndices && sIBOActive) { + /*if (sMapped) + { + llerrs << "VBO unbound while potentially mapped!" << llendl; + }*/ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + sBindCount++; sIBOActive = FALSE; } } @@ -803,9 +843,11 @@ void LLVertexBuffer::setBuffer(U32 data_mask) llwarns << "Vertex buffer set for rendering outside of render frame." << llendl; } setupVertexBuffer(data_mask); // subclass specific setup (virtual function) - sLastMask = data_mask; + sSetCount++; } } + + sLastMask = data_mask; } // virtual (default) @@ -821,10 +863,6 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; } - if (data_mask & MAP_VERTEX) - { - glVertexPointer(3,GL_FLOAT, stride, (void*)(base + 0)); - } if (data_mask & MAP_NORMAL) { glNormalPointer(GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_NORMAL])); @@ -855,49 +893,19 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const { glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, stride, (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); } + if (data_mask & MAP_VERTEX) + { + glVertexPointer(3,GL_FLOAT, stride, (void*)(base + 0)); + } llglassertok(); } void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count) { - if (useVBOs() && !mFilthy) - { - if (!mDirtyRegions.empty()) - { - DirtyRegion& region = *(mDirtyRegions.rbegin()); - - if (region.mIndex+region.mCount > vert_index) - { - //this buffer has received multiple updates since the last copy, mark it filthy - mFilthy = TRUE; - mDirtyRegions.clear(); - return; - } - - if (region.mIndex + region.mCount == vert_index && - region.mIndicesIndex + region.mIndicesCount == indices_index) - { - region.mCount += vert_count; - region.mIndicesCount += indices_count; - return; - } - } - - mDirtyRegions.push_back(DirtyRegion(vert_index,vert_count,indices_index,indices_count)); - } -} - -void LLVertexBuffer::markClean() -{ - if (!mResized && !mEmpty && !mFilthy) + // TODO: use GL_APPLE_flush_buffer_range here + /*if (useVBOs() && !mFilthy) { - buffer_list_t::reverse_iterator iter = sLockedList.rbegin(); - if (*iter == this) - { - mLocked = FALSE; - sLockedList.pop_back(); - } - } + + }*/ } - diff --git a/linden/indra/llrender/llvertexbuffer.h b/linden/indra/llrender/llvertexbuffer.h index 43a32c9..3031b2d 100644 --- a/linden/indra/llrender/llvertexbuffer.h +++ b/linden/indra/llrender/llvertexbuffer.h @@ -50,12 +50,38 @@ // be called as soon as getVertexPointer(), etc is called (which MUST ONLY be // called from the main (i.e OpenGL) thread) + +//============================================================================ +// gl name pools for dynamic and streaming buffers + +class LLVBOPool : public LLGLNamePool +{ +protected: + virtual GLuint allocateName() + { + GLuint name; + glGenBuffersARB(1, &name); + return name; + } + + virtual void releaseName(GLuint name) + { + glDeleteBuffersARB(1, &name); + } +}; + + //============================================================================ // base class class LLVertexBuffer : public LLRefCount { public: + static LLVBOPool sStreamVBOPool; + static LLVBOPool sDynamicVBOPool; + static LLVBOPool sStreamIBOPool; + static LLVBOPool sDynamicIBOPool; + static void initClass(bool use_vbo); static void cleanupClass(); static void startRender(); //between start and stop render, no client copies will occur @@ -63,6 +89,12 @@ public: static void clientCopy(F64 max_time = 0.005); //copy data from client to GL static void unbind(); //unbind any bound vertex buffer + //get the size of a vertex with the given typemask + //if offsets is not NULL, its contents will be filled + //with the offset of each vertex component in the buffer, + // indexed by the following enum + static S32 calcStride(const U32& typemask, S32* offsets = NULL); + enum { TYPE_VERTEX, TYPE_NORMAL, @@ -92,10 +124,16 @@ public: }; protected: + friend class LLGLImmediate; + virtual ~LLVertexBuffer(); // use unref() virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer() - + + void genBuffer(); + void genIndices(); + void releaseBuffer(); + void releaseIndices(); void createGLBuffer(); void createGLIndices(); void destroyGLBuffer(); @@ -104,7 +142,7 @@ protected: void updateNumIndices(S32 nindices); virtual BOOL useVBOs() const; void unmapBuffer(); - + public: LLVertexBuffer(U32 typemask, S32 usage); @@ -115,8 +153,7 @@ public: // allocate buffer void allocateBuffer(S32 nverts, S32 nindices, bool create); virtual void resizeBuffer(S32 newnverts, S32 newnindices); - void makeStatic(); - + // Only call each getVertexPointer, etc, once before calling unmapBuffer() // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer() // example: @@ -125,7 +162,7 @@ public: // setVertsNorms(verts, norms); // vb->unmapBuffer(); bool getVertexStrider(LLStrider& strider, S32 index=0); - bool getIndexStrider(LLStrider& strider, S32 index=0); + bool getIndexStrider(LLStrider& strider, S32 index=0); bool getTexCoordStrider(LLStrider& strider, S32 index=0); bool getTexCoord2Strider(LLStrider& strider, S32 index=0); bool getNormalStrider(LLStrider& strider, S32 index=0); @@ -138,13 +175,16 @@ public: BOOL isLocked() const { return mLocked; } S32 getNumVerts() const { return mNumVerts; } S32 getNumIndices() const { return mNumIndices; } + S32 getRequestedVerts() const { return mRequestedNumVerts; } + S32 getRequestedIndices() const { return mRequestedNumIndices; } + U8* getIndicesPointer() const { return useVBOs() ? NULL : mMappedIndexData; } U8* getVerticesPointer() const { return useVBOs() ? NULL : mMappedData; } S32 getStride() const { return mStride; } S32 getTypeMask() const { return mTypeMask; } BOOL hasDataType(S32 type) const { return ((1 << type) & getTypeMask()) ? TRUE : FALSE; } S32 getSize() const { return mNumVerts*mStride; } - S32 getIndicesSize() const { return mNumIndices * sizeof(U32); } + S32 getIndicesSize() const { return mNumIndices * sizeof(U16); } U8* getMappedData() const { return mMappedData; } U8* getMappedIndices() const { return mMappedIndexData; } S32 getOffset(S32 type) const { return mOffsets[type]; } @@ -153,11 +193,13 @@ public: void setStride(S32 type, S32 new_stride); void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count); - void markClean(); protected: - S32 mNumVerts; // Number of vertices - S32 mNumIndices; // Number of indices + S32 mNumVerts; // Number of vertices allocated + S32 mNumIndices; // Number of indices allocated + S32 mRequestedNumVerts; // Number of vertices requested + S32 mRequestedNumIndices; // Number of indices requested + S32 mStride; U32 mTypeMask; S32 mUsage; // GL usage @@ -192,10 +234,11 @@ public: static BOOL sRenderActive; static S32 sCount; static S32 sGLCount; + static S32 sMappedCount; + static BOOL sMapped; static std::vector sDeleteList; typedef std::list buffer_list_t; - static buffer_list_t sLockedList; - + static BOOL sEnableVBOs; static S32 sTypeOffsets[TYPE_MAX]; static U32 sGLRenderBuffer; @@ -204,6 +247,8 @@ public: static BOOL sIBOActive; static U32 sLastMask; static U32 sAllocatedBytes; + static U32 sBindCount; + static U32 sSetCount; }; diff --git a/linden/indra/llui/files.lst b/linden/indra/llui/files.lst index 96bb170..56bc2c3 100644 --- a/linden/indra/llui/files.lst +++ b/linden/indra/llui/files.lst @@ -13,6 +13,8 @@ llui/llkeywords.cpp llui/lllineeditor.cpp llui/llmenugl.cpp llui/llmodaldialog.cpp +llui/llmultislider.cpp +llui/llmultisliderctrl.cpp llui/llpanel.cpp llui/llradiogroup.cpp llui/llresizebar.cpp @@ -39,4 +41,6 @@ llui/llundo.cpp llui/llview.cpp llui/llviewborder.cpp llui/llviewquery.cpp +llui/llmultislider.cpp +llui/llmultisliderctrl.cpp diff --git a/linden/indra/llui/llalertdialog.cpp b/linden/indra/llui/llalertdialog.cpp index 204fb10..e60ef42 100644 --- a/linden/indra/llui/llalertdialog.cpp +++ b/linden/indra/llui/llalertdialog.cpp @@ -177,11 +177,11 @@ LLAlertDialog::LLAlertDialog( const LLAlertDialogTemplate* xml_template, // so that the alert is valid until show() is called. bool LLAlertDialog::show() { - // If mModal, check to see if we are not displaying alerts, + // If modal, check to see if we are not displaying alerts, // and do any application logic before showing modal alerts if (sDisplayCallback) { - bool show = sDisplayCallback(mModal); + bool show = sDisplayCallback(isModal()); if (show == false) { mOptionChosen = mDefaultOption; @@ -330,7 +330,7 @@ void LLAlertDialog::createDialog(const std::vector* optionsp, S32 defa } reshape( dialog_width, dialog_height, FALSE ); - S32 msg_y = mRect.getHeight() - VPAD; + S32 msg_y = getRect().getHeight() - VPAD; S32 msg_x = HPAD; if (hasTitleBar()) { @@ -355,7 +355,7 @@ void LLAlertDialog::createDialog(const std::vector* optionsp, S32 defa addChild(msg_box); // Buttons - S32 button_left = (mRect.getWidth() - btn_total_width) / 2; + S32 button_left = (getRect().getWidth() - btn_total_width) / 2; for( S32 i = 0; i < mNumOptions; i++ ) { @@ -403,18 +403,18 @@ bool LLAlertDialog::setCheckBox( const LLString& check_title, const LLString& ch const S32 LINE_HEIGHT = llfloor(font->getLineHeight() + 0.99f); // Extend dialog for "check next time" - S32 max_msg_width = mRect.getWidth() - 2 * HPAD; + S32 max_msg_width = getRect().getWidth() - 2 * HPAD; S32 check_width = S32(font->getWidth(check_title) + 0.99f) + 16; max_msg_width = llmax(max_msg_width, check_width); S32 dialog_width = max_msg_width + 2 * HPAD; - S32 dialog_height = mRect.getHeight(); + S32 dialog_height = getRect().getHeight(); dialog_height += LINE_HEIGHT; dialog_height += LINE_HEIGHT / 2; reshape( dialog_width, dialog_height, FALSE ); - S32 msg_x = (mRect.getWidth() - max_msg_width) / 2; + S32 msg_x = (getRect().getWidth() - max_msg_width) / 2; LLRect check_rect; check_rect.setOriginAndSize(msg_x, VPAD+BTN_HEIGHT+LINE_HEIGHT/2, @@ -556,7 +556,7 @@ void LLAlertDialog::draw() LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow"); S32 shadow_lines = LLUI::sConfigGroup->getS32("DropShadowFloater"); - gl_drop_shadow( 0, mRect.getHeight(), mRect.getWidth(), 0, + gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0, shadow_color, shadow_lines); LLModalDialog::draw(); diff --git a/linden/indra/llui/llalertdialog.h b/linden/indra/llui/llalertdialog.h index 31f4769..4978d71 100644 --- a/linden/indra/llui/llalertdialog.h +++ b/linden/indra/llui/llalertdialog.h @@ -42,6 +42,7 @@ class LLCheckBoxCtrl; class LLAlertDialogTemplate; class LLLineEditor; +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLAlertDialog&oldid=81388 class LLAlertDialog : public LLModalDialog { public: @@ -60,17 +61,13 @@ public: static void setURLLoader(URLLoader* loader) { sURLLoader = loader; - }; - -protected: - struct ButtonData - { - LLAlertDialog* mSelf; - LLButton* mButton; - S32 mOption; - }; + } public: + // User's responsibility to call show() after creating these. + LLAlertDialog( const LLAlertDialogTemplate* xml_template, const LLString::format_map_t& args, + alert_callback_t callback = NULL, void *user_data = NULL); + virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ); virtual void draw(); @@ -106,14 +103,25 @@ public: static const LLString& getTemplateMessage(const LLString& xml_desc); static void setDisplayCallback(display_callback_t callback) { sDisplayCallback = callback; } - - // Must call show() after creating these - LLAlertDialog( const LLAlertDialogTemplate* xml_template, const LLString::format_map_t& args, - alert_callback_t callback = NULL, void *user_data = NULL); void format(LLString& msg, const LLString::format_map_t& args); - -protected: + + static LLControlGroup* sSettings; + + // use LLPointer so they delete themselves when sTemplates is destroyed + typedef std::map > template_map_t; + static template_map_t sAlertTemplates; // by mLabel + static template_map_t sIgnorableTemplates; // by mIgnoreLabel + + +private: + + static std::map sUniqueActiveMap; + static display_callback_t sDisplayCallback; + + static LLString sStringSkipNextTime; + static LLString sStringAlwaysChoose; + void createDialog(const std::vector* options, S32 default_option, const LLString& msg, const LLString::format_map_t& args, const LLString& edit_text); @@ -123,7 +131,13 @@ protected: // Does it have a readable title label, or minimize or close buttons? BOOL hasTitleBar() const; -protected: + struct ButtonData + { + LLAlertDialog* mSelf; + LLButton* mButton; + S32 mOption; + } * mButtonData; + alert_callback_t mCallback; void* mUserData; S32 mNumOptions; @@ -135,7 +149,6 @@ protected: S32 mIgnorable; LLString mLabel; LLString mIgnoreLabel; - ButtonData* mButtonData; LLFrameTimer mDefaultBtnTimer; // For Dialogs that take a line as text as input: LLLineEditor* mLineEditor; @@ -143,18 +156,6 @@ protected: // For Dialogs linked to a URL LLString mURL; // Some alerts will direct the resident to a URL S32 mURLOption; - -public: - // use LLPointer so they delete themselves when sTemplates is destroyed - typedef std::map > template_map_t; - static template_map_t sAlertTemplates; // by mLabel - static template_map_t sIgnorableTemplates; // by mIgnoreLabel - static LLControlGroup* sSettings; - static std::map sUniqueActiveMap; - static display_callback_t sDisplayCallback; - - static LLString sStringSkipNextTime; - static LLString sStringAlwaysChoose; private: static URLLoader* sURLLoader; diff --git a/linden/indra/llui/llbutton.cpp b/linden/indra/llui/llbutton.cpp index 7513fc2..4af40ff 100644 --- a/linden/indra/llui/llbutton.cpp +++ b/linden/indra/llui/llbutton.cpp @@ -48,6 +48,7 @@ #include "llglheaders.h" #include "llfocusmgr.h" #include "llwindow.h" +#include "llglimmediate.h" // globals loaded from settings.xml S32 LLBUTTON_ORIG_H_PAD = 6; // Pre-zoomable UI @@ -189,7 +190,7 @@ void LLButton::init(void (*click_callback)(void*), void *callback_data, const LL mGLFont = ( font ? font : LLFontGL::sSansSerif); // Hack to make sure there is space for at least one character - if (mRect.getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(" ")) + if (getRect().getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(" ")) { // Use old defaults mLeftHPad = LLBUTTON_ORIG_H_PAD; @@ -252,12 +253,12 @@ void LLButton::onCommit() (*mMouseUpCallback)(mCallbackUserData); } - if (mSoundFlags & MOUSE_DOWN) + if (getSoundFlags() & MOUSE_DOWN) { make_ui_sound("UISndClick"); } - if (mSoundFlags & MOUSE_UP) + if (getSoundFlags() & MOUSE_UP) { make_ui_sound("UISndClickRelease"); } @@ -279,7 +280,7 @@ void LLButton::onCommit() BOOL LLButton::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) { BOOL handled = FALSE; - if( getVisible() && mEnabled && !called_from_parent && ' ' == uni_char && !gKeyboard->getKeyRepeated(' ')) + if( getVisible() && getEnabled() && !called_from_parent && ' ' == uni_char && !gKeyboard->getKeyRepeated(' ')) { if (mIsToggle) { @@ -298,7 +299,7 @@ BOOL LLButton::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) BOOL LLButton::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) { BOOL handled = FALSE; - if( getVisible() && mEnabled && !called_from_parent ) + if( getVisible() && getEnabled() && !called_from_parent ) { if( mCommitOnReturn && KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key)) { @@ -337,7 +338,7 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) mMouseDownTimer.start(); mMouseDownFrame = LLFrameTimer::getFrameCount(); - if (mSoundFlags & MOUSE_DOWN) + if (getSoundFlags() & MOUSE_DOWN) { make_ui_sound("UISndClick"); } @@ -367,7 +368,7 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) // If mouseup in the widget, it's been clicked if (pointInView(x, y)) { - if (mSoundFlags & MOUSE_UP) + if (getSoundFlags() & MOUSE_UP) { make_ui_sound("UISndClickRelease"); } @@ -400,7 +401,7 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) if (mMouseDownTimer.getStarted() && NULL != mHeldDownCallback) { - F32 elapsed = mMouseDownTimer.getElapsedTimeF32(); + F32 elapsed = getHeldDownTime(); if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= LLFrameTimer::getFrameCount() - mMouseDownFrame) { mHeldDownCallback( mCallbackUserData ); @@ -505,11 +506,11 @@ void LLButton::draw() // enabled and tentative // or // disabled but checked - if (!mImageDisabledSelected.isNull() && ( (mEnabled && mTentative) || (!mEnabled && pressed ) ) ) + if (!mImageDisabledSelected.isNull() && ( (getEnabled() && getTentative()) || (!getEnabled() && pressed ) ) ) { mImagep = mImageDisabledSelected; } - else if (!mImageDisabled.isNull() && !mEnabled && !pressed) + else if (!mImageDisabled.isNull() && !getEnabled() && !pressed) { mImagep = mImageDisabled; } @@ -523,7 +524,7 @@ void LLButton::draw() LLColor4 label_color; // label changes when button state changes, not when pressed - if ( mEnabled ) + if ( getEnabled() ) { if ( mToggleState ) { @@ -551,7 +552,7 @@ void LLButton::draw() if( mToggleState ) { - if( mEnabled || mDisabledSelectedLabel.empty() ) + if( getEnabled() || mDisabledSelectedLabel.empty() ) { label = mSelectedLabel; } @@ -562,7 +563,7 @@ void LLButton::draw() } else { - if( mEnabled || mDisabledLabel.empty() ) + if( getEnabled() || mDisabledLabel.empty() ) { label = mUnselectedLabel; } @@ -573,7 +574,7 @@ void LLButton::draw() } // draw default button border - if (mEnabled && mBorderEnabled && gFocusMgr.getAppHasFocus()) // because we're the default button in a panel + if (getEnabled() && mBorderEnabled && gFocusMgr.getAppHasFocus()) // because we're the default button in a panel { drawBorder(LLUI::sColorsGroup->getColor( "ButtonBorderColor" ), BORDER_SIZE); } @@ -598,37 +599,37 @@ void LLButton::draw() // Otherwise draw basic rectangular button. if( mImagep.notNull() && !mScaleImage) { - mImagep->draw(0, 0, mEnabled ? mImageColor : mDisabledImageColor ); + mImagep->draw(0, 0, getEnabled() ? mImageColor : mDisabledImageColor ); if (mCurGlowStrength > 0.01f) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); mImagep->drawSolid(0, 0, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } } else if ( mImagep.notNull() && mScaleImage) { - mImagep->draw(0, 0, mRect.getWidth(), mRect.getHeight(), mEnabled ? mImageColor : mDisabledImageColor ); + mImagep->draw(0, 0, getRect().getWidth(), getRect().getHeight(), getEnabled() ? mImageColor : mDisabledImageColor ); if (mCurGlowStrength > 0.01f) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - mImagep->drawSolid(0, 0, mRect.getWidth(), mRect.getHeight(), LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); + mImagep->drawSolid(0, 0, getRect().getWidth(), getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } } else { // no image - llwarns << "No image for button " << mName << llendl; + llwarns << "No image for button " << getName() << llendl; // draw it in pink so we can find it - gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4::pink1, FALSE); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4::pink1, FALSE); } // let overlay image and text play well together S32 text_left = mLeftHPad; - S32 text_right = mRect.getWidth() - mRightHPad; - S32 text_width = mRect.getWidth() - mLeftHPad - mRightHPad; + S32 text_right = getRect().getWidth() - mRightHPad; + S32 text_width = getRect().getWidth() - mLeftHPad - mRightHPad; // draw overlay image if (mImageOverlay.notNull()) @@ -637,7 +638,7 @@ void LLButton::draw() S32 overlay_width = mImageOverlay->getWidth(); S32 overlay_height = mImageOverlay->getHeight(); - F32 scale_factor = llmin((F32)mRect.getWidth() / (F32)overlay_width, (F32)mRect.getHeight() / (F32)overlay_height, 1.f); + F32 scale_factor = llmin((F32)getRect().getWidth() / (F32)overlay_width, (F32)getRect().getHeight() / (F32)overlay_height, 1.f); overlay_width = llround((F32)overlay_width * scale_factor); overlay_height = llround((F32)overlay_height * scale_factor); @@ -682,7 +683,7 @@ void LLButton::draw() text_right -= overlay_width + 1; text_width -= overlay_width + 1; mImageOverlay->draw( - mRect.getWidth() - mRightHPad - overlay_width, + getRect().getWidth() - mRightHPad - overlay_width, center_y - (overlay_height / 2), overlay_width, overlay_height, @@ -706,7 +707,7 @@ void LLButton::draw() x = text_right; break; case LLFontGL::HCENTER: - x = mRect.getWidth() / 2; + x = getRect().getWidth() / 2; break; case LLFontGL::LEFT: default: @@ -714,7 +715,7 @@ void LLButton::draw() break; } - S32 y_offset = 2 + (mRect.getHeight() - 20)/2; + S32 y_offset = 2 + (getRect().getHeight() - 20)/2; if (pressed) { @@ -743,8 +744,8 @@ void LLButton::draw() void LLButton::drawBorder(const LLColor4& color, S32 size) { S32 left = -size; - S32 top = mRect.getHeight() + size; - S32 right = mRect.getWidth() + size; + S32 top = getRect().getHeight() + size; + S32 right = getRect().getWidth() + size; S32 bottom = -size; if (mImagep.isNull()) @@ -1146,7 +1147,7 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa return button; } -void LLButton::setHelpURLCallback(std::string help_url) +void LLButton::setHelpURLCallback(const LLString &help_url) { mHelpURL = help_url; setClickedCallback(clicked_help,this); diff --git a/linden/indra/llui/llbutton.h b/linden/indra/llui/llbutton.h index 7d50f40..18f4e07 100644 --- a/linden/indra/llui/llbutton.h +++ b/linden/indra/llui/llbutton.h @@ -52,10 +52,14 @@ extern S32 LLBUTTON_V_PAD; extern S32 BTN_HEIGHT_SMALL; extern S32 BTN_HEIGHT; - // All button widths should be rounded up to this size extern S32 BTN_GRID; +// +// Helpful functions +// +S32 round_up(S32 grid, S32 value); + class LLUICtrlFactory; @@ -124,6 +128,7 @@ public: BOOL getFlashing() const { return mFlashing; } void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } + LLFontGL::HAlign getHAlign() const { return mHAlign; } void setLeftHPad( S32 pad ) { mLeftHPad = pad; } void setRightHPad( S32 pad ) { mRightHPad = pad; } @@ -162,6 +167,7 @@ public: void setFont(const LLFontGL *font) { mGLFont = ( font ? font : LLFontGL::sSansSerif); } void setScaleImage(BOOL scale) { mScaleImage = scale; } + BOOL getScaleImage() const { return mScaleImage; } void setDropShadowedText(BOOL b) { mDropShadowedText = b; } @@ -171,9 +177,10 @@ public: void setHoverGlowStrength(F32 strength) { mHoverGlowStrength = strength; } -public: void setImageUnselected(const LLString &image_name); + const LLString& getImageUnselectedName() const { return mImageUnselectedName; } void setImageSelected(const LLString &image_name); + const LLString& getImageSelectedName() const { return mImageSelectedName; } void setImageHoverSelected(const LLString &image_name); void setImageHoverUnselected(const LLString &image_name); void setImageDisabled(const LLString &image_name); @@ -187,14 +194,29 @@ public: void setImageDisabledSelected(LLPointer image); void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; } - BOOL getCommitOnReturn() { return mCommitOnReturn; } + BOOL getCommitOnReturn() const { return mCommitOnReturn; } + + void setHelpURLCallback(const LLString &help_url); + const LLString& getHelpURL() const { return mHelpURL; } - void setHelpURLCallback(std::string help_url); - LLString getHelpURL() { return mHelpURL; } protected: + virtual void drawBorder(const LLColor4& color, S32 size); -protected: + void setImageUnselectedID(const LLUUID &image_id); + const LLUUID& getImageUnselectedID() const { return mImageUnselectedID; } + void setImageSelectedID(const LLUUID &image_id); + const LLUUID& getImageSelectedID() const { return mImageSelectedID; } + void setImageHoverSelectedID(const LLUUID &image_id); + void setImageHoverUnselectedID(const LLUUID &image_id); + void setImageDisabledID(const LLUUID &image_id); + void setImageDisabledSelectedID(const LLUUID &image_id); + const LLPointer& getImageUnselected() const { return mImageUnselected; } + const LLPointer& getImageSelected() const { return mImageSelected; } + + LLFrameTimer mMouseDownTimer; + +private: void (*mClickedCallback)(void* data ); void (*mMouseDownCallback)(void *data); @@ -203,7 +225,6 @@ protected: const LLFontGL *mGLFont; - LLFrameTimer mMouseDownTimer; S32 mMouseDownFrame; F32 mHeldDownDelay; // seconds, after which held-down callbacks get called S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called @@ -232,7 +253,6 @@ protected: LLUIString mDisabledSelectedLabel; LLColor4 mDisabledSelectedLabelColor; - LLUUID mImageUnselectedID; LLUUID mImageSelectedID; LLUUID mImageHoverSelectedID; @@ -280,7 +300,4 @@ protected: LLFrameTimer mFlashingTimer; }; -// Helpful functions -S32 round_up(S32 grid, S32 value); - #endif // LL_LLBUTTON_H diff --git a/linden/indra/llui/llcheckboxctrl.cpp b/linden/indra/llui/llcheckboxctrl.cpp index ff46a80..ecb6342 100644 --- a/linden/indra/llui/llcheckboxctrl.cpp +++ b/linden/indra/llui/llcheckboxctrl.cpp @@ -89,7 +89,16 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLString& name, const LLRect& rect, LLCHECKBOXCTRL_VPAD + 1, // padding to get better alignment text_width + LLCHECKBOXCTRL_HPAD, text_height ); - mLabel = new LLTextBox( "CheckboxCtrl Label", label_rect, label.c_str(), mFont ); + + // *HACK Get rid of this with SL-55508... + // this allows blank check boxes and radio boxes for now + LLString local_label = label; + if(local_label.empty()) + { + local_label = " "; + } + + mLabel = new LLTextBox( "CheckboxCtrl Label", label_rect, local_label.c_str(), mFont ); mLabel->setFollowsLeft(); mLabel->setFollowsBottom(); addChild(mLabel); @@ -212,7 +221,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) void LLCheckBoxCtrl::draw() { - if (mEnabled) + if (getEnabled()) { mLabel->setColor( mTextEnabledColor ); } diff --git a/linden/indra/llui/llclipboard.cpp b/linden/indra/llui/llclipboard.cpp index eaf7798..31d02a4 100644 --- a/linden/indra/llui/llclipboard.cpp +++ b/linden/indra/llui/llclipboard.cpp @@ -61,7 +61,7 @@ void LLClipboard::copyFromSubstring(const LLWString &src, S32 pos, S32 len, cons } -LLWString LLClipboard::getPasteWString( LLUUID* source_id ) +const LLWString& LLClipboard::getPasteWString( LLUUID* source_id ) { if( mSourceID.notNull() ) { @@ -88,7 +88,7 @@ LLWString LLClipboard::getPasteWString( LLUUID* source_id ) } -BOOL LLClipboard::canPasteString() +BOOL LLClipboard::canPasteString() const { return LLView::getWindow()->isClipboardTextAvailable(); } diff --git a/linden/indra/llui/llclipboard.h b/linden/indra/llui/llclipboard.h index 82ea334..2ebc2de 100644 --- a/linden/indra/llui/llclipboard.h +++ b/linden/indra/llui/llclipboard.h @@ -36,24 +36,20 @@ #include "llstring.h" #include "lluuid.h" -// -// Classes -// + class LLClipboard { -protected: - LLUUID mSourceID; - LLWString mString; - public: LLClipboard(); ~LLClipboard(); void copyFromSubstring(const LLWString ©_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null ); - - - BOOL canPasteString(); - LLWString getPasteWString(LLUUID* source_id = NULL); + BOOL canPasteString() const; + const LLWString& getPasteWString(LLUUID* source_id = NULL); + +private: + LLUUID mSourceID; + LLWString mString; }; diff --git a/linden/indra/llui/llcombobox.cpp b/linden/indra/llui/llcombobox.cpp index 0e0f5f2..c486042 100644 --- a/linden/indra/llui/llcombobox.cpp +++ b/linden/indra/llui/llcombobox.cpp @@ -99,7 +99,7 @@ LLComboBox::LLComboBox( const LLString& name, const LLRect &rect, const LLString mList->setCommitOnKeyboardMovement(FALSE); addChild(mList); - LLRect border_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect border_rect(0, getRect().getHeight(), getRect().getWidth(), 0); mBorder = new LLViewBorder( "combo border", border_rect ); addChild( mBorder ); mBorder->setFollowsAll(); @@ -444,7 +444,7 @@ void LLComboBox::setButtonVisible(BOOL visible) mButton->setVisible(visible); if (mTextEntry) { - LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); if (visible) { text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth(0)) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); @@ -460,7 +460,7 @@ void LLComboBox::draw() { mBorder->setKeyboardFocusHighlight(hasFocus()); - mButton->setEnabled(mEnabled /*&& !mList->isEmpty()*/); + mButton->setEnabled(getEnabled() /*&& !mList->isEmpty()*/); // Draw children normally LLUICtrl::draw(); @@ -494,13 +494,13 @@ void LLComboBox::updateLayout() if (mAllowTextEntry) { S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton"); - mButton->setRect(LLRect( mRect.getWidth() - llmax(8,mArrowImage->getWidth(0)) - 2 * shadow_size, + mButton->setRect(LLRect( getRect().getWidth() - llmax(8,mArrowImage->getWidth(0)) - 2 * shadow_size, rect.mTop, rect.mRight, rect.mBottom)); mButton->setTabStop(FALSE); if (!mTextEntry) { - LLRect text_entry_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth(0)) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton"); // clear label on button LLString cur_label = mButton->getLabelSelected(); @@ -575,7 +575,7 @@ void LLComboBox::showList() LLRect rect = mList->getRect(); - S32 min_width = mRect.getWidth(); + S32 min_width = getRect().getWidth(); S32 max_width = llmax(min_width, MAX_COMBO_WIDTH); S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width); @@ -589,7 +589,7 @@ void LLComboBox::showList() else { // stack on top or bottom, depending on which has more room - if (-root_view_local.mBottom > root_view_local.mTop - mRect.getHeight()) + if (-root_view_local.mBottom > root_view_local.mTop - getRect().getHeight()) { // Move rect so it hangs off the bottom of this view rect.setLeftTopAndSize(0, 0, list_width, llmin(-root_view_local.mBottom, rect.getHeight())); @@ -597,21 +597,21 @@ void LLComboBox::showList() else { // move rect so it stacks on top of this view (clipped to size of screen) - rect.setOriginAndSize(0, mRect.getHeight(), list_width, llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); + rect.setOriginAndSize(0, getRect().getHeight(), list_width, llmin(root_view_local.mTop - getRect().getHeight(), rect.getHeight())); } } } else // ABOVE { - if (rect.getHeight() <= root_view_local.mTop - mRect.getHeight()) + if (rect.getHeight() <= root_view_local.mTop - getRect().getHeight()) { // move rect so it stacks on top of this view (clipped to size of screen) - rect.setOriginAndSize(0, mRect.getHeight(), list_width, llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); + rect.setOriginAndSize(0, getRect().getHeight(), list_width, llmin(root_view_local.mTop - getRect().getHeight(), rect.getHeight())); } else { // stack on top or bottom, depending on which has more room - if (-root_view_local.mBottom > root_view_local.mTop - mRect.getHeight()) + if (-root_view_local.mBottom > root_view_local.mTop - getRect().getHeight()) { // Move rect so it hangs off the bottom of this view rect.setLeftTopAndSize(0, 0, list_width, llmin(-root_view_local.mBottom, rect.getHeight())); @@ -619,7 +619,7 @@ void LLComboBox::showList() else { // move rect so it stacks on top of this view (clipped to size of screen) - rect.setOriginAndSize(0, mRect.getHeight(), list_width, llmin(root_view_local.mTop - mRect.getHeight(), rect.getHeight())); + rect.setOriginAndSize(0, getRect().getHeight(), list_width, llmin(root_view_local.mTop - getRect().getHeight(), rect.getHeight())); } } @@ -640,12 +640,6 @@ void LLComboBox::showList() // NB: this call will trigger the focuslost callback which will hide the list, so do it first // before finally showing the list - if (!mList->getFirstSelected()) - { - // if nothing is selected, select the first item - // so that the callback is not immediately triggered on setFocus() - mList->selectFirstItem(); - } mList->setFocus(TRUE); // register ourselves as a "top" control @@ -718,7 +712,7 @@ void LLComboBox::onButtonDown(void *userdata) else { self->hideList(); - } + } } @@ -741,31 +735,36 @@ void LLComboBox::onItemSelected(LLUICtrl* item, void *userdata) self->mTextEntry->selectAll(); } } - else - { - // invalid selection, just restore existing value - LLString orig_selection = self->mAllowTextEntry ? self->mTextEntry->getText() : self->mButton->getLabelSelected(); - - self->mList->selectItemByLabel(orig_selection); - } - self->onCommit(); + // hiding the list reasserts the old value stored in the text editor/dropdown button self->hideList(); + + // commit does the reverse, asserting the value in the list + self->onCommit(); } BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) { LLString tool_tip; + if(LLUICtrl::handleToolTip(x, y, msg, sticky_rect_screen)) + { + return TRUE; + } + if (LLUI::sShowXUINames) { tool_tip = getShowNamesToolTip(); } else { - tool_tip = mToolTipMsg; + tool_tip = getToolTip(); + if (tool_tip.empty()) + { + tool_tip = getValue().asString(); + } } - + if( !tool_tip.empty() ) { msg = tool_tip; @@ -775,7 +774,7 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_ 0, 0, &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); localPointToScreen( - mRect.getWidth(), mRect.getHeight(), + getRect().getWidth(), getRect().getHeight(), &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); } return TRUE; @@ -1042,11 +1041,11 @@ BOOL LLComboBox::setCurrentByID(const LLUUID& id) return found; } -LLUUID LLComboBox::getCurrentID() +LLUUID LLComboBox::getCurrentID() const { return mList->getStringUUIDSelectedItem(); } -BOOL LLComboBox::setSelectedByValue(LLSD value, BOOL selected) +BOOL LLComboBox::setSelectedByValue(const LLSD& value, BOOL selected) { BOOL found = mList->setSelectedByValue(value, selected); if (found) @@ -1061,7 +1060,7 @@ LLSD LLComboBox::getSelectedValue() return mList->getSelectedValue(); } -BOOL LLComboBox::isSelected(LLSD value) +BOOL LLComboBox::isSelected(const LLSD& value) const { return mList->isSelected(value); } @@ -1199,14 +1198,14 @@ void LLFlyoutButton::updateLayout() { LLComboBox::updateLayout(); - mButton->setOrigin(mRect.getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, 0); - mButton->reshape(FLYOUT_BUTTON_ARROW_WIDTH, mRect.getHeight()); + mButton->setOrigin(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, 0); + mButton->reshape(FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight()); mButton->setFollows(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM); mButton->setTabStop(FALSE); mButton->setImageOverlay(mListPosition == BELOW ? "down_arrow.tga" : "up_arrow.tga", LLFontGL::RIGHT); mActionButton->setOrigin(0, 0); - mActionButton->reshape(mRect.getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, mRect.getHeight()); + mActionButton->reshape(getRect().getWidth() - FLYOUT_BUTTON_ARROW_WIDTH, getRect().getHeight()); } //static diff --git a/linden/indra/llui/llcombobox.h b/linden/indra/llui/llcombobox.h index db1c251..f9ca4d2 100644 --- a/linden/indra/llui/llcombobox.h +++ b/linden/indra/llui/llcombobox.h @@ -159,10 +159,10 @@ public: virtual BOOL selectItemRange( S32 first, S32 last ); virtual S32 getFirstSelectedIndex() const { return getCurrentIndex(); } virtual BOOL setCurrentByID( const LLUUID& id ); - virtual LLUUID getCurrentID(); // LLUUID::null if no items in menu - virtual BOOL setSelectedByValue(LLSD value, BOOL selected); + virtual LLUUID getCurrentID() const; // LLUUID::null if no items in menu + virtual BOOL setSelectedByValue(const LLSD& value, BOOL selected); virtual LLSD getSelectedValue(); - virtual BOOL isSelected(LLSD value); + virtual BOOL isSelected(const LLSD& value) const; virtual BOOL operateOnSelection(EOperation op); virtual BOOL operateOnAll(EOperation op); @@ -183,18 +183,20 @@ public: void updateSelection(); virtual void showList(); virtual void hideList(); - + protected: LLButton* mButton; LLScrollListCtrl* mList; - S32 mButtonPadding; LLViewBorder* mBorder; + EPreferredPosition mListPosition; + LLPointer mArrowImage; + +private: + S32 mButtonPadding; LLLineEditor* mTextEntry; - LLPointer mArrowImage; BOOL mAllowTextEntry; S32 mMaxChars; BOOL mTextEntryTentative; - EPreferredPosition mListPosition; void (*mPrearrangeCallback)(LLUICtrl*,void*); void (*mTextEntryCallback)(LLLineEditor*, void*); }; diff --git a/linden/indra/llui/llctrlselectioninterface.h b/linden/indra/llui/llctrlselectioninterface.h index b4d3fc0..f303861 100644 --- a/linden/indra/llui/llctrlselectioninterface.h +++ b/linden/indra/llui/llctrlselectioninterface.h @@ -64,14 +64,14 @@ public: // TomY TODO: Simply cast the UUIDs to LLSDs, using the selectByValue function virtual BOOL setCurrentByID( const LLUUID& id ) = 0; - virtual LLUUID getCurrentID() = 0; + virtual LLUUID getCurrentID() const = 0; - BOOL selectByValue(LLSD value); - BOOL deselectByValue(LLSD value); - virtual BOOL setSelectedByValue(LLSD value, BOOL selected) = 0; + BOOL selectByValue(const LLSD value); + BOOL deselectByValue(const LLSD value); + virtual BOOL setSelectedByValue(const LLSD& value, BOOL selected) = 0; virtual LLSD getSelectedValue() = 0; - virtual BOOL isSelected(LLSD value) = 0; + virtual BOOL isSelected(const LLSD& value) const = 0; virtual BOOL operateOnSelection(EOperation op) = 0; virtual BOOL operateOnAll(EOperation op) = 0; @@ -101,7 +101,7 @@ class LLCtrlScrollInterface public: virtual ~LLCtrlScrollInterface(); - virtual S32 getScrollPos() = 0; + virtual S32 getScrollPos() const = 0; virtual void setScrollPos( S32 pos ) = 0; virtual void scrollToShowSelected() = 0; }; diff --git a/linden/indra/llui/lldraghandle.cpp b/linden/indra/llui/lldraghandle.cpp index 032cb91..516afc6 100644 --- a/linden/indra/llui/lldraghandle.cpp +++ b/linden/indra/llui/lldraghandle.cpp @@ -74,7 +74,24 @@ LLDragHandle::LLDragHandle( const LLString& name, const LLRect& rect, const LLSt void LLDragHandle::setTitleVisible(BOOL visible) { - mTitleBox->setVisible(visible); + if(mTitleBox) + { + mTitleBox->setVisible(visible); + } +} + +void LLDragHandle::setTitleBox(LLTextBox* titlebox) +{ + if( mTitleBox ) + { + removeChild(mTitleBox); + delete mTitleBox; + } + mTitleBox = titlebox; + if(mTitleBox) + { + addChild( mTitleBox ); + } } LLDragHandleTop::LLDragHandleTop(const LLString& name, const LLRect &rect, const LLString& title) @@ -113,46 +130,28 @@ LLString LLDragHandleLeft::getWidgetTag() const void LLDragHandleTop::setTitle(const LLString& title) { - if( mTitleBox ) - { - removeChild(mTitleBox); - delete mTitleBox; - } - LLString trimmed_title = title; LLString::trim(trimmed_title); const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF ); - mTitleBox = new LLTextBox( "Drag Handle Title", mRect, trimmed_title, font ); - mTitleBox->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT); - mTitleBox->setFontStyle(LLFontGL::DROP_SHADOW_SOFT); - reshapeTitleBox(); + LLTextBox* titlebox = new LLTextBox( "Drag Handle Title", getRect(), trimmed_title, font ); + titlebox->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT); + titlebox->setFontStyle(LLFontGL::DROP_SHADOW_SOFT); - // allow empty titles, as default behavior replaces them with title box name - if (trimmed_title.empty()) - { - mTitleBox->setText(LLString::null); - } - addChild( mTitleBox ); + setTitleBox(titlebox); + reshapeTitleBox(); } const LLString& LLDragHandleTop::getTitle() const { - return mTitleBox->getText(); + return getTitleBox() == NULL ? LLString::null : getTitleBox()->getText(); } void LLDragHandleLeft::setTitle(const LLString& ) { - if( mTitleBox ) - { - removeChild(mTitleBox); - delete mTitleBox; - } - - mTitleBox = NULL; - + setTitleBox(NULL); /* no title on left edge */ } @@ -166,14 +165,14 @@ const LLString& LLDragHandleLeft::getTitle() const void LLDragHandleTop::draw() { /* Disable lines. Can drag anywhere in most windows. JC - if( getVisible() && mEnabled && mForeground) + if( getVisible() && getEnabled() && mForeground) { const S32 BORDER_PAD = 2; const S32 HPAD = 2; const S32 VPAD = 2; S32 left = BORDER_PAD + HPAD; - S32 top = mRect.getHeight() - 2 * VPAD; - S32 right = mRect.getWidth() - HPAD; + S32 top = getRect().getHeight() - 2 * VPAD; + S32 right = getRect().getWidth() - HPAD; // S32 bottom = VPAD; // draw lines for drag areas @@ -183,7 +182,7 @@ void LLDragHandleTop::draw() LLRect title_rect = mTitleBox->getRect(); S32 title_right = title_rect.mLeft + mTitleWidth; - BOOL show_right_side = title_right < mRect.getWidth(); + BOOL show_right_side = title_right < getRect().getWidth(); for( S32 i=0; i<4; i++ ) { @@ -204,9 +203,9 @@ void LLDragHandleTop::draw() */ // Colorize the text to match the frontmost state - if (mTitleBox) + if (getTitleBox()) { - mTitleBox->setEnabled(mForeground); + getTitleBox()->setEnabled(getForeground()); } LLView::draw(); @@ -217,7 +216,7 @@ void LLDragHandleTop::draw() void LLDragHandleLeft::draw() { /* Disable lines. Can drag anywhere in most windows. JC - if( getVisible() && mEnabled && mForeground ) + if( getVisible() && getEnabled() && mForeground ) { const S32 BORDER_PAD = 2; // const S32 HPAD = 2; @@ -225,8 +224,8 @@ void LLDragHandleLeft::draw() const S32 LINE_SPACING = 3; S32 left = BORDER_PAD + LINE_SPACING; - S32 top = mRect.getHeight() - 2 * VPAD; -// S32 right = mRect.getWidth() - HPAD; + S32 top = getRect().getHeight() - 2 * VPAD; +// S32 right = getRect().getWidth() - HPAD; S32 bottom = VPAD; // draw lines for drag areas @@ -234,7 +233,7 @@ void LLDragHandleLeft::draw() // no titles yet //LLRect title_rect = mTitleBox->getRect(); //S32 title_right = title_rect.mLeft + mTitleWidth; - //BOOL show_right_side = title_right < mRect.getWidth(); + //BOOL show_right_side = title_right < getRect().getWidth(); S32 line = left; for( S32 i=0; i<4; i++ ) @@ -249,9 +248,9 @@ void LLDragHandleLeft::draw() */ // Colorize the text to match the frontmost state - if (mTitleBox) + if (getTitleBox()) { - mTitleBox->setEnabled(mForeground); + getTitleBox()->setEnabled(getForeground()); } LLView::draw(); @@ -259,19 +258,23 @@ void LLDragHandleLeft::draw() void LLDragHandleTop::reshapeTitleBox() { + if( ! getTitleBox()) + { + return; + } const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF ); - S32 title_width = font->getWidth( mTitleBox->getText() ) + TITLE_PAD; - if (mMaxTitleWidth > 0) - title_width = llmin(title_width, mMaxTitleWidth); + S32 title_width = font->getWidth( getTitleBox()->getText() ) + TITLE_PAD; + if (getMaxTitleWidth() > 0) + title_width = llmin(title_width, getMaxTitleWidth()); S32 title_height = llround(font->getLineHeight()); LLRect title_rect; title_rect.setLeftTopAndSize( LEFT_PAD, - mRect.getHeight() - BORDER_PAD, - mRect.getWidth() - LEFT_PAD - RIGHT_PAD, + getRect().getHeight() - BORDER_PAD, + getRect().getWidth() - LEFT_PAD - RIGHT_PAD, title_height); - mTitleBox->setRect( title_rect ); + getTitleBox()->setRect( title_rect ); } void LLDragHandleTop::reshape(S32 width, S32 height, BOOL called_from_parent) diff --git a/linden/indra/llui/lldraghandle.h b/linden/indra/llui/lldraghandle.h index a48c0f7..cb9924d 100644 --- a/linden/indra/llui/lldraghandle.h +++ b/linden/indra/llui/lldraghandle.h @@ -45,11 +45,14 @@ class LLDragHandle : public LLView { public: LLDragHandle(const LLString& name, const LLRect& rect, const LLString& title ); + virtual ~LLDragHandle() { setTitleBox(NULL); } virtual void setValue(const LLSD& value); void setForeground(BOOL b) { mForeground = b; } + BOOL getForeground() const { return mForeground; } void setMaxTitleWidth(S32 max_width) {mMaxTitleWidth = llmin(max_width, mMaxTitleWidth); } + S32 getMaxTitleWidth() const { return mMaxTitleWidth; } void setTitleVisible(BOOL visible); virtual void setTitle( const LLString& title ) = 0; @@ -61,6 +64,10 @@ public: virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); protected: + LLTextBox* getTitleBox() const { return mTitleBox; } + void setTitleBox(LLTextBox*); + +private: S32 mDragLastScreenX; S32 mDragLastScreenY; S32 mLastMouseScreenX; diff --git a/linden/indra/llui/lleditmenuhandler.cpp b/linden/indra/llui/lleditmenuhandler.cpp index 6291088..2f29f71 100644 --- a/linden/indra/llui/lleditmenuhandler.cpp +++ b/linden/indra/llui/lleditmenuhandler.cpp @@ -33,98 +33,6 @@ #include "lleditmenuhandler.h" -LLEditMenuHandler* gEditMenuHandler = NULL; +/* static */ +LLEditMenuHandler* LLEditMenuHandler::gEditMenuHandler = NULL; -// virtual -LLEditMenuHandler::~LLEditMenuHandler() -{ } - -// virtual -void LLEditMenuHandler::undo() -{ } - -// virtual -BOOL LLEditMenuHandler::canUndo() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::redo() -{ } - -// virtual -BOOL LLEditMenuHandler::canRedo() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::cut() -{ } - -// virtual -BOOL LLEditMenuHandler::canCut() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::copy() -{ } - -// virtual -BOOL LLEditMenuHandler::canCopy() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::paste() -{ } - -// virtual -BOOL LLEditMenuHandler::canPaste() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::doDelete() -{ } - -// virtual -BOOL LLEditMenuHandler::canDoDelete() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::selectAll() -{ } - -// virtual -BOOL LLEditMenuHandler::canSelectAll() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::deselect() -{ } - -// virtual -BOOL LLEditMenuHandler::canDeselect() -{ - return FALSE; -} - -// virtual -void LLEditMenuHandler::duplicate() -{ } - -// virtual -BOOL LLEditMenuHandler::canDuplicate() -{ - return FALSE; -} diff --git a/linden/indra/llui/lleditmenuhandler.h b/linden/indra/llui/lleditmenuhandler.h index ef9b1dd..82bb058 100644 --- a/linden/indra/llui/lleditmenuhandler.h +++ b/linden/indra/llui/lleditmenuhandler.h @@ -37,37 +37,43 @@ class LLEditMenuHandler { public: // this is needed even though this is just an interface class. - virtual ~LLEditMenuHandler(); + virtual ~LLEditMenuHandler() {}; - virtual void undo(); - virtual BOOL canUndo(); + virtual void undo() {}; + virtual BOOL canUndo() const { return FALSE; } - virtual void redo(); - virtual BOOL canRedo(); + virtual void redo() {}; + virtual BOOL canRedo() const { return FALSE; } - virtual void cut(); - virtual BOOL canCut(); + virtual void cut() {}; + virtual BOOL canCut() const { return FALSE; } - virtual void copy(); - virtual BOOL canCopy(); + virtual void copy() {}; + virtual BOOL canCopy() const { return FALSE; } - virtual void paste(); - virtual BOOL canPaste(); + virtual void paste() {}; + virtual BOOL canPaste() const { return FALSE; } // "delete" is a keyword - virtual void doDelete(); - virtual BOOL canDoDelete(); + virtual void doDelete() {}; + virtual BOOL canDoDelete() const { return FALSE; } - virtual void selectAll(); - virtual BOOL canSelectAll(); + virtual void selectAll() {}; + virtual BOOL canSelectAll() const { return FALSE; } - virtual void deselect(); - virtual BOOL canDeselect(); + virtual void deselect() {}; + virtual BOOL canDeselect() const { return FALSE; } - virtual void duplicate(); - virtual BOOL canDuplicate(); + virtual void duplicate() {}; + virtual BOOL canDuplicate() const { return FALSE; } + + // TODO: Instead of being a public data member, it would be better to hide it altogether + // and have a "set" method and then a bunch of static versions of the cut, copy, paste + // methods, etc that operate on the current global instance. That would drastically + // simplify the existing code that accesses this global variable by putting all the + // null checks in the one implementation of those static methods. -MG + static LLEditMenuHandler* gEditMenuHandler; }; -extern LLEditMenuHandler* gEditMenuHandler; #endif diff --git a/linden/indra/llui/llfloater.cpp b/linden/indra/llui/llfloater.cpp index 6d86652..493e68f 100644 --- a/linden/indra/llui/llfloater.cpp +++ b/linden/indra/llui/llfloater.cpp @@ -142,20 +142,18 @@ LLFloater::LLFloater() : mButtons[i] = NULL; } mDragHandle = NULL; + mHandle.bind(this); } LLFloater::LLFloater(const LLString& name) -: LLPanel(name) +: LLPanel(name), mAutoFocus(TRUE) // automatically take focus when opened { for (S32 i = 0; i < BUTTON_COUNT; i++) { mButtonsEnabled[i] = FALSE; mButtons[i] = NULL; } - LLString title; // null string - // automatically take focus when opened - mAutoFocus = TRUE; init(title, FALSE, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, FALSE, TRUE, TRUE); // defaults } @@ -168,15 +166,13 @@ LLFloater::LLFloater(const LLString& name, const LLRect& rect, const LLString& t BOOL minimizable, BOOL close_btn, BOOL bordered) -: LLPanel(name, rect, bordered) +: LLPanel(name, rect, bordered), mAutoFocus(TRUE) // automatically take focus when opened { for (S32 i = 0; i < BUTTON_COUNT; i++) { mButtonsEnabled[i] = FALSE; mButtons[i] = NULL; } - // automatically take focus when opened - mAutoFocus = TRUE; init( title, resizable, min_width, min_height, drag_on_left, minimizable, close_btn); } @@ -188,15 +184,13 @@ LLFloater::LLFloater(const LLString& name, const LLString& rect_control, const L BOOL minimizable, BOOL close_btn, BOOL bordered) -: LLPanel(name, rect_control, bordered) +: LLPanel(name, rect_control, bordered), mAutoFocus(TRUE) // automatically take focus when opened { for (S32 i = 0; i < BUTTON_COUNT; i++) { mButtonsEnabled[i] = FALSE; mButtons[i] = NULL; } - // automatically take focus when opened - mAutoFocus = TRUE; init( title, resizable, min_width, min_height, drag_on_left, minimizable, close_btn); } @@ -206,6 +200,8 @@ void LLFloater::init(const LLString& title, BOOL resizable, S32 min_width, S32 min_height, BOOL drag_on_left, BOOL minimizable, BOOL close_btn) { + mHandle.bind(this); + // Init function can be called more than once, so clear out old data. for (S32 i = 0; i < BUTTON_COUNT; i++) { @@ -219,20 +215,20 @@ void LLFloater::init(const LLString& title, } mButtonScale = 1.f; - BOOL need_border = mBorder != NULL; - + //sjb: Thia is a bit of a hack: + BOOL need_border = hasBorder(); + // remove the border since deleteAllChildren() will also delete the border (but not clear mBorder) + removeBorder(); // this will delete mBorder too deleteAllChildren(); - // make sure we don't have a pointer to an old, deleted border - mBorder = NULL; - //sjb: HACK! we had a border which was just deleted, so re-create it + // add the border back if we want it if (need_border) { - addBorder(); + addBorder(); } // chrome floaters don't take focus at all - mIsFocusRoot = !getIsChrome(); + setFocusRoot(!getIsChrome()); // Reset cached pointers mDragHandle = NULL; @@ -257,7 +253,7 @@ void LLFloater::init(const LLString& title, // Floaters start not minimized. When minimized, they save their // prior rectangle to be used on restore. mMinimized = FALSE; - mPreviousRect.set(0,0,0,0); + mExpandedRect.set(0,0,0,0); S32 close_pad; // space to the right of close box S32 close_box_size; // For layout purposes, how big is the close box? @@ -288,31 +284,20 @@ void LLFloater::init(const LLString& title, // Drag Handle // Add first so it's in the background. // const S32 drag_pad = 2; - LLRect drag_handle_rect; - if (!drag_on_left) - { - drag_handle_rect.set( 0, mRect.getHeight(), mRect.getWidth(), 0 ); - - /* - drag_handle_rect.setLeftTopAndSize( - 0, mRect.getHeight(), - mRect.getWidth() - - LLPANEL_BORDER_WIDTH - - drag_pad - - minimize_box_size - minimize_pad - - close_box_size - close_pad, - DRAG_HANDLE_HEIGHT); - */ - mDragHandle = new LLDragHandleTop( "Drag Handle", drag_handle_rect, title ); - } - else + if (drag_on_left) { + LLRect drag_handle_rect; drag_handle_rect.setOriginAndSize( 0, 0, DRAG_HANDLE_WIDTH, - mRect.getHeight() - LLPANEL_BORDER_WIDTH - close_box_size); + getRect().getHeight() - LLPANEL_BORDER_WIDTH - close_box_size); mDragHandle = new LLDragHandleLeft("drag", drag_handle_rect, title ); } + else // drag on top + { + LLRect drag_handle_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 ); + mDragHandle = new LLDragHandleTop( "Drag Handle", drag_handle_rect, title ); + } addChild(mDragHandle); // Resize Handle @@ -327,28 +312,28 @@ void LLFloater::init(const LLString& title, mResizeBar[LLResizeBar::LEFT] = new LLResizeBar( "resizebar_left", this, - LLRect( 0, mRect.getHeight(), RESIZE_BAR_THICKNESS, 0), + LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0), min_width, S32_MAX, LLResizeBar::LEFT ); addChild( mResizeBar[0] ); mResizeBar[LLResizeBar::TOP] = new LLResizeBar( "resizebar_top", this, - LLRect( 0, mRect.getHeight(), mRect.getWidth(), mRect.getHeight() - RESIZE_BAR_THICKNESS), + LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS), min_height, S32_MAX, LLResizeBar::TOP ); addChild( mResizeBar[1] ); mResizeBar[LLResizeBar::RIGHT] = new LLResizeBar( "resizebar_right", this, - LLRect( mRect.getWidth() - RESIZE_BAR_THICKNESS, mRect.getHeight(), mRect.getWidth(), 0), + LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0), min_width, S32_MAX, LLResizeBar::RIGHT ); addChild( mResizeBar[2] ); mResizeBar[LLResizeBar::BOTTOM] = new LLResizeBar( "resizebar_bottom", this, - LLRect( 0, RESIZE_BAR_THICKNESS, mRect.getWidth(), 0), + LLRect( 0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0), min_height, S32_MAX, LLResizeBar::BOTTOM ); addChild( mResizeBar[3] ); @@ -356,14 +341,14 @@ void LLFloater::init(const LLString& title, // Resize handles (corners) mResizeHandle[0] = new LLResizeHandle( "Resize Handle", - LLRect( mRect.getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, mRect.getWidth(), 0), + LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0), min_width, min_height, LLResizeHandle::RIGHT_BOTTOM); addChild(mResizeHandle[0]); mResizeHandle[1] = new LLResizeHandle( "resize", - LLRect( mRect.getWidth() - RESIZE_HANDLE_WIDTH, mRect.getHeight(), mRect.getWidth(), mRect.getHeight() - RESIZE_HANDLE_HEIGHT), + LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT), min_width, min_height, LLResizeHandle::RIGHT_TOP ); @@ -377,7 +362,7 @@ void LLFloater::init(const LLString& title, addChild(mResizeHandle[2]); mResizeHandle[3] = new LLResizeHandle( "resize", - LLRect( 0, mRect.getHeight(), RESIZE_HANDLE_WIDTH, mRect.getHeight() - RESIZE_HANDLE_HEIGHT ), + LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ), min_width, min_height, LLResizeHandle::LEFT_TOP ); @@ -413,7 +398,7 @@ void LLFloater::init(const LLString& title, setVisible(FALSE); // add self to handle->floater map - sFloaterMap[mViewHandle] = this; + sFloaterMap[mHandle] = this; if (!getParent()) { @@ -450,7 +435,7 @@ LLFloater::~LLFloater() // correct, non-minimized positions. setMinimized( FALSE ); - sFloaterMap.erase(mViewHandle); + sFloaterMap.erase(mHandle); delete mDragHandle; for (S32 i = 0; i < 4; i++) @@ -460,22 +445,6 @@ LLFloater::~LLFloater() } } -// virtual -EWidgetType LLFloater::getWidgetType() const -{ - return WIDGET_TYPE_FLOATER; -} - -// virtual -LLString LLFloater::getWidgetTag() const -{ - return LL_FLOATER_TAG; -} - -void LLFloater::destroy() -{ - die(); -} void LLFloater::setVisible( BOOL visible ) { @@ -501,7 +470,7 @@ void LLFloater::setVisible( BOOL visible ) for(handle_set_iter_t dependent_it = mDependents.begin(); dependent_it != mDependents.end(); ) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* floaterp = dependent_it->get(); if (floaterp) { @@ -513,10 +482,10 @@ void LLFloater::setVisible( BOOL visible ) void LLFloater::open() /* Flawfinder: ignore */ { - if (mSoundFlags != SILENT + if (getSoundFlags() != SILENT // don't play open sound for hosted (tabbed) windows && !getHost() - && !sHostp + && !getFloaterHost() && (!getVisible() || isMinimized())) { make_ui_sound("UISndWindowOpen"); @@ -524,17 +493,16 @@ void LLFloater::open() /* Flawfinder: ignore */ //RN: for now, we don't allow rehosting from one multifloater to another // just need to fix the bugs - LLMultiFloater* hostp = getHost(); - if (sHostp != NULL && hostp == NULL) + if (getFloaterHost() != NULL && getHost() == NULL) { // needs a host // only select tabs if window they are hosted in is visible - sHostp->addFloater(this, sHostp->getVisible()); + getFloaterHost()->addFloater(this, getFloaterHost()->getVisible()); } - else if (hostp != NULL) + else if (getHost() != NULL) { // already hosted - hostp->showFloater(this); + getHost()->showFloater(this); } else { @@ -558,7 +526,7 @@ void LLFloater::close(bool app_quitting) ((LLMultiFloater*)getHost())->removeFloater(this); } - if (mSoundFlags != SILENT + if (getSoundFlags() != SILENT && getVisible() && !getHost() && !app_quitting) @@ -571,7 +539,7 @@ void LLFloater::close(bool app_quitting) dependent_it != mDependents.end(); ) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* floaterp = dependent_it->get(); if (floaterp) { ++dependent_it; @@ -595,7 +563,7 @@ void LLFloater::close(bool app_quitting) // give focus to dependee floater if it exists, and we had focus first if (isDependent()) { - LLFloater* dependee = LLFloater::getFloaterByHandle(mDependeeHandle); + LLFloater* dependee = mDependeeHandle.get(); if (dependee && !dependee->isDead()) { dependee->setFocus(TRUE); @@ -661,20 +629,15 @@ void LLFloater::center() // hosted floaters can't move return; } - const LLRect &window = gFloaterView->getRect(); - - S32 left = window.mLeft + (window.getWidth() - mRect.getWidth()) / 2; - S32 bottom = window.mBottom + (window.getHeight() - mRect.getHeight()) / 2; - - translate( left - mRect.mLeft, bottom - mRect.mBottom ); + centerWithin(gFloaterView->getRect()); } void LLFloater::applyRectControl() { - if (!mRectControl.empty()) + if (!getRectControl().empty()) { - const LLRect& rect = LLUI::sConfigGroup->getRect(mRectControl); - translate( rect.mLeft - mRect.mLeft, rect.mBottom - mRect.mBottom); + const LLRect& rect = LLUI::sConfigGroup->getRect(getRectControl()); + translate( rect.mLeft - getRect().mLeft, rect.mBottom - getRect().mBottom); if (mResizable) { reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight())); @@ -715,7 +678,7 @@ LLString LLFloater::getShortTitle() -BOOL LLFloater::canSnapTo(LLView* other_view) +BOOL LLFloater::canSnapTo(const LLView* other_view) { if (NULL == other_view) { @@ -727,7 +690,7 @@ BOOL LLFloater::canSnapTo(LLView* other_view) { LLFloater* other_floaterp = (LLFloater*)other_view; - if (other_floaterp->getSnapTarget() == mViewHandle && mDependents.find(other_floaterp->getHandle()) != mDependents.end()) + if (other_floaterp->getSnapTarget() == getHandle() && mDependents.find(other_floaterp->getHandle()) != mDependents.end()) { // this is a dependent that is already snapped to us, so don't snap back to it return FALSE; @@ -737,7 +700,7 @@ BOOL LLFloater::canSnapTo(LLView* other_view) return LLPanel::canSnapTo(other_view); } -void LLFloater::snappedTo(LLView* snap_view) +void LLFloater::snappedTo(const LLView* snap_view) { if (!snap_view || snap_view == getParent()) { @@ -754,7 +717,7 @@ void LLFloater::snappedTo(LLView* snap_view) void LLFloater::userSetShape(const LLRect& new_rect) { - LLRect old_rect = mRect; + const LLRect& old_rect = getRect(); LLView::userSetShape(new_rect); // if not minimized, adjust all snapped dependents to new shape @@ -764,22 +727,22 @@ void LLFloater::userSetShape(const LLRect& new_rect) for(handle_set_iter_t dependent_it = mDependents.begin(); dependent_it != mDependents.end(); ++dependent_it) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* floaterp = dependent_it->get(); // is a dependent snapped to us? - if (floaterp && floaterp->getSnapTarget() == mViewHandle) + if (floaterp && floaterp->getSnapTarget() == getHandle()) { S32 delta_x = 0; S32 delta_y = 0; // check to see if it snapped to right or top, and move if dependee floater is resizing LLRect dependent_rect = floaterp->getRect(); - if (dependent_rect.mLeft - mRect.mLeft >= old_rect.getWidth() || // dependent on my right? - dependent_rect.mRight == mRect.mLeft + old_rect.getWidth()) // dependent aligned with my right + if (dependent_rect.mLeft - getRect().mLeft >= old_rect.getWidth() || // dependent on my right? + dependent_rect.mRight == getRect().mLeft + old_rect.getWidth()) // dependent aligned with my right { // was snapped directly onto right side or aligned with it delta_x += new_rect.getWidth() - old_rect.getWidth(); } - if (dependent_rect.mBottom - mRect.mBottom >= old_rect.getHeight() || - dependent_rect.mTop == mRect.mBottom + old_rect.getHeight()) + if (dependent_rect.mBottom - getRect().mBottom >= old_rect.getHeight() || + dependent_rect.mTop == getRect().mBottom + old_rect.getHeight()) { // was snapped directly onto top side or aligned with it delta_y += new_rect.getHeight() - old_rect.getHeight(); @@ -812,7 +775,7 @@ void LLFloater::setMinimized(BOOL minimize) if (minimize) { - mPreviousRect = mRect; + mExpandedRect = getRect(); reshape( MINIMIZED_WIDTH, LLFLOATER_HEADER_SIZE, TRUE); @@ -843,7 +806,7 @@ void LLFloater::setMinimized(BOOL minimize) LLView* viewp = *child_it; if (!viewp->getVisible()) { - mMinimizedHiddenChildren.push_back(viewp->mViewHandle); + mMinimizedHiddenChildren.push_back(viewp->getHandle()); } viewp->setVisible(FALSE); } @@ -860,7 +823,7 @@ void LLFloater::setMinimized(BOOL minimize) dependent_it != mDependents.end(); ++dependent_it) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* floaterp = dependent_it->get(); if (floaterp) { if (floaterp->isMinimizeable()) @@ -890,8 +853,8 @@ void LLFloater::setMinimized(BOOL minimize) mPreviousMinimizedBottom = currentRect.mBottom; } - reshape( mPreviousRect.getWidth(), mPreviousRect.getHeight(), TRUE ); - setOrigin( mPreviousRect.mLeft, mPreviousRect.mBottom ); + reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE ); + setOrigin( mExpandedRect.mLeft, mExpandedRect.mBottom ); if (mButtonsEnabled[BUTTON_RESTORE]) { @@ -906,10 +869,10 @@ void LLFloater::setMinimized(BOOL minimize) viewp->setVisible(TRUE); } - std::vector::iterator itor = mMinimizedHiddenChildren.begin(); + std::vector >::iterator itor = mMinimizedHiddenChildren.begin(); for ( ; itor != mMinimizedHiddenChildren.end(); ++itor) { - LLView* viewp = LLView::getViewByHandle(*itor); + LLView* viewp = itor->get(); if(viewp) { viewp->setVisible(FALSE); @@ -922,7 +885,7 @@ void LLFloater::setMinimized(BOOL minimize) dependent_it != mDependents.end(); ++dependent_it) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* floaterp = dependent_it->get(); if (floaterp) { floaterp->setMinimized(FALSE); @@ -979,7 +942,7 @@ void LLFloater::setIsChrome(BOOL is_chrome) // remove focus if we're changing to chrome setFocus(FALSE); // can't Ctrl-Tab to "chrome" floaters - mIsFocusRoot = FALSE; + setFocusRoot(FALSE); } // no titles displayed on "chrome" floaters @@ -1011,7 +974,7 @@ void LLFloater::cleanupHandles() for(handle_set_iter_t dependent_it = mDependents.begin(); dependent_it != mDependents.end(); ) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* floaterp = dependent_it->get(); if (!floaterp) { mDependents.erase(dependent_it++); @@ -1085,7 +1048,7 @@ void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition) if (reposition) { floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp)); - floaterp->setSnapTarget(mViewHandle); + floaterp->setSnapTarget(getHandle()); } gFloaterView->adjustToFitScreen(floaterp, FALSE); if (floaterp->isFrontmost()) @@ -1095,9 +1058,9 @@ void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition) } } -void LLFloater::addDependentFloater(LLViewHandle dependent, BOOL reposition) +void LLFloater::addDependentFloater(LLHandle dependent, BOOL reposition) { - LLFloater* dependent_floaterp = LLFloater::getFloaterByHandle(dependent); + LLFloater* dependent_floaterp = dependent.get(); if(dependent_floaterp) { addDependentFloater(dependent_floaterp, reposition); @@ -1107,7 +1070,7 @@ void LLFloater::addDependentFloater(LLViewHandle dependent, BOOL reposition) void LLFloater::removeDependentFloater(LLFloater* floaterp) { mDependents.erase(floaterp->getHandle()); - floaterp->mDependeeHandle = LLViewHandle::sDeadHandle; + floaterp->mDependeeHandle = LLHandle(); } // virtual @@ -1215,32 +1178,13 @@ void LLFloater::setFrontmost(BOOL take_focus) } } -// static -LLFloater* LLFloater::getFloaterByHandle(LLViewHandle handle) -{ - LLFloater* floater = NULL; - if (sFloaterMap.count(handle)) - { - floater = sFloaterMap[handle]; - } - if (floater && !floater->isDead()) - { - return floater; - } - else - { - return NULL; - } -} - //static void LLFloater::setEditModeEnabled(BOOL enable) { if (enable != sEditModeEnabled) { S32 count = 0; - std::map::iterator iter; - for(iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter) + for(handle_map_iter_t iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter) { LLFloater* floater = iter->second; if (!floater->isDead()) @@ -1255,41 +1199,6 @@ void LLFloater::setEditModeEnabled(BOOL enable) sEditModeEnabled = enable; } -//static -BOOL LLFloater::getEditModeEnabled() -{ - return sEditModeEnabled; -} - -//static -void LLFloater::show(LLFloater* floaterp) -{ - if (floaterp) - { - gFocusMgr.triggerFocusFlash(); - floaterp->open(); - if (floaterp->getHost()) - { - floaterp->getHost()->open(); - } - } -} - -//static -void LLFloater::hide(LLFloater* floaterp) -{ - if (floaterp) floaterp->close(); -} - -//static -BOOL LLFloater::visible(LLFloater* floaterp) -{ - if (floaterp) - { - return !floaterp->isMinimized() && floaterp->isInVisibleChain(); - } - return FALSE; -} // static void LLFloater::onClickMinimize(void *userdata) @@ -1316,9 +1225,9 @@ void LLFloater::onClickTearOff(void *userdata) self->open(); /* Flawfinder: ignore */ // only force position for floaters that don't have that data saved - if (self->mRectControl.empty()) + if (self->getRectControl().empty()) { - new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - LLFLOATER_HEADER_SIZE - 5, self->mRect.getWidth(), self->mRect.getHeight()); + new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - LLFLOATER_HEADER_SIZE - 5, self->getRect().getWidth(), self->getRect().getHeight()); self->setRect(new_rect); } gFloaterView->adjustToFitScreen(self, FALSE); @@ -1327,7 +1236,7 @@ void LLFloater::onClickTearOff(void *userdata) } else //Attach to parent. { - LLMultiFloater* new_host = (LLMultiFloater*)LLFloater::getFloaterByHandle(self->mLastHostHandle); + LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get(); if (new_host) { new_host->showFloater(self); @@ -1351,7 +1260,7 @@ void LLFloater::closeFocusedFloater() { LLFloater* focused_floater = NULL; - std::map::iterator iter; + handle_map_iter_t iter; for(iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter) { focused_floater = iter->second; @@ -1396,16 +1305,16 @@ void LLFloater::draw() if( getVisible() ) { // draw background - if( mBgVisible ) + if( isBackgroundVisible() ) { S32 left = LLPANEL_BORDER_WIDTH; - S32 top = mRect.getHeight() - LLPANEL_BORDER_WIDTH; - S32 right = mRect.getWidth() - LLPANEL_BORDER_WIDTH; + S32 top = getRect().getHeight() - LLPANEL_BORDER_WIDTH; + S32 right = getRect().getWidth() - LLPANEL_BORDER_WIDTH; S32 bottom = LLPANEL_BORDER_WIDTH; LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow"); F32 shadow_offset = (F32)LLUI::sConfigGroup->getS32("DropShadowFloater"); - if (!mBgOpaque) + if (!isBackgroundOpaque()) { shadow_offset *= 0.2f; shadow_color.mV[VALPHA] *= 0.5f; @@ -1415,13 +1324,13 @@ void LLFloater::draw() llround(shadow_offset)); // No transparent windows in simple UI - if (mBgOpaque) + if (isBackgroundOpaque()) { - gl_rect_2d( left, top, right, bottom, mBgColorOpaque ); + gl_rect_2d( left, top, right, bottom, getBackgroundColor() ); } else { - gl_rect_2d( left, top, right, bottom, mBgColorAlpha ); + gl_rect_2d( left, top, right, bottom, getTransparentColor() ); } if(gFocusMgr.childHasKeyboardFocus(this) && !getIsChrome() && !getTitle().empty()) @@ -1448,13 +1357,13 @@ void LLFloater::draw() // don't call LLPanel::draw() since we've implemented custom background rendering LLView::draw(); - if( mBgVisible ) + if( isBackgroundVisible() ) { // add in a border to improve spacialized visual aclarity ;) // use lines instead of gl_rect_2d so we can round the edges as per james' recommendation LLUI::setLineWidth(1.5f); LLColor4 outlineColor = gFocusMgr.childHasKeyboardFocus(this) ? LLUI::sColorsGroup->getColor("FloaterFocusBorderColor") : LLUI::sColorsGroup->getColor("FloaterUnfocusBorderColor"); - gl_rect_2d_offset_local(0, mRect.getHeight() + 1, mRect.getWidth() + 1, 0, outlineColor, -LLPANEL_BORDER_WIDTH, FALSE); + gl_rect_2d_offset_local(0, getRect().getHeight() + 1, getRect().getWidth() + 1, 0, outlineColor, -LLPANEL_BORDER_WIDTH, FALSE); LLUI::setLineWidth(1.f); } @@ -1468,7 +1377,7 @@ void LLFloater::draw() // when last host goes away if (mCanTearOff && !getHost()) { - LLFloater* old_host = gFloaterView->getFloaterByHandle(mLastHostHandle); + LLFloater* old_host = mLastHostHandle.get(); if (!old_host) { setCanTearOff(FALSE); @@ -1477,33 +1386,6 @@ void LLFloater::draw() } } -// virtual -void LLFloater::onOpen() -{ -} - -// virtual -void LLFloater::onClose(bool app_quitting) -{ - destroy(); -} - -// virtual -BOOL LLFloater::canClose() -{ - return TRUE; -} - -// virtual -BOOL LLFloater::canSaveAs() -{ - return FALSE; -} - -// virtual -void LLFloater::saveAs() -{ -} void LLFloater::setCanMinimize(BOOL can_minimize) { @@ -1572,28 +1454,28 @@ void LLFloater::setCanResize(BOOL can_resize) mResizeBar[0] = new LLResizeBar( "resizebar_left", this, - LLRect( 0, mRect.getHeight(), RESIZE_BAR_THICKNESS, 0), + LLRect( 0, getRect().getHeight(), RESIZE_BAR_THICKNESS, 0), mMinWidth, S32_MAX, LLResizeBar::LEFT ); addChild( mResizeBar[0] ); mResizeBar[1] = new LLResizeBar( "resizebar_top", this, - LLRect( 0, mRect.getHeight(), mRect.getWidth(), mRect.getHeight() - RESIZE_BAR_THICKNESS), + LLRect( 0, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_BAR_THICKNESS), mMinHeight, S32_MAX, LLResizeBar::TOP ); addChild( mResizeBar[1] ); mResizeBar[2] = new LLResizeBar( "resizebar_right", this, - LLRect( mRect.getWidth() - RESIZE_BAR_THICKNESS, mRect.getHeight(), mRect.getWidth(), 0), + LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0), mMinWidth, S32_MAX, LLResizeBar::RIGHT ); addChild( mResizeBar[2] ); mResizeBar[3] = new LLResizeBar( "resizebar_bottom", this, - LLRect( 0, RESIZE_BAR_THICKNESS, mRect.getWidth(), 0), + LLRect( 0, RESIZE_BAR_THICKNESS, getRect().getWidth(), 0), mMinHeight, S32_MAX, LLResizeBar::BOTTOM ); addChild( mResizeBar[3] ); @@ -1601,14 +1483,14 @@ void LLFloater::setCanResize(BOOL can_resize) // Resize handles (corners) mResizeHandle[0] = new LLResizeHandle( "Resize Handle", - LLRect( mRect.getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, mRect.getWidth(), 0), + LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0), mMinWidth, mMinHeight, LLResizeHandle::RIGHT_BOTTOM); addChild(mResizeHandle[0]); mResizeHandle[1] = new LLResizeHandle( "resize", - LLRect( mRect.getWidth() - RESIZE_HANDLE_WIDTH, mRect.getHeight(), mRect.getWidth(), mRect.getHeight() - RESIZE_HANDLE_HEIGHT), + LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, getRect().getHeight(), getRect().getWidth(), getRect().getHeight() - RESIZE_HANDLE_HEIGHT), mMinWidth, mMinHeight, LLResizeHandle::RIGHT_TOP ); @@ -1622,7 +1504,7 @@ void LLFloater::setCanResize(BOOL can_resize) addChild(mResizeHandle[2]); mResizeHandle[3] = new LLResizeHandle( "resize", - LLRect( 0, mRect.getHeight(), RESIZE_HANDLE_WIDTH, mRect.getHeight() - RESIZE_HANDLE_HEIGHT ), + LLRect( 0, getRect().getHeight(), RESIZE_HANDLE_WIDTH, getRect().getHeight() - RESIZE_HANDLE_HEIGHT ), mMinWidth, mMinHeight, LLResizeHandle::LEFT_TOP ); @@ -1659,15 +1541,15 @@ void LLFloater::updateButtons() { btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH, - mRect.getHeight() - CLOSE_BOX_FROM_TOP - (LLFLOATER_CLOSE_BOX_SIZE + 1) * button_count, + getRect().getHeight() - CLOSE_BOX_FROM_TOP - (LLFLOATER_CLOSE_BOX_SIZE + 1) * button_count, llround((F32)LLFLOATER_CLOSE_BOX_SIZE * mButtonScale), llround((F32)LLFLOATER_CLOSE_BOX_SIZE * mButtonScale)); } else { btn_rect.setLeftTopAndSize( - mRect.getWidth() - LLPANEL_BORDER_WIDTH - (LLFLOATER_CLOSE_BOX_SIZE + 1) * button_count, - mRect.getHeight() - CLOSE_BOX_FROM_TOP, + getRect().getWidth() - LLPANEL_BORDER_WIDTH - (LLFLOATER_CLOSE_BOX_SIZE + 1) * button_count, + getRect().getHeight() - CLOSE_BOX_FROM_TOP, llround((F32)LLFLOATER_CLOSE_BOX_SIZE * mButtonScale), llround((F32)LLFLOATER_CLOSE_BOX_SIZE * mButtonScale)); } @@ -1685,7 +1567,7 @@ void LLFloater::updateButtons() } } - mDragHandle->setMaxTitleWidth(mRect.getWidth() - (button_count * (LLFLOATER_CLOSE_BOX_SIZE + 1))); + mDragHandle->setMaxTitleWidth(getRect().getWidth() - (button_count * (LLFLOATER_CLOSE_BOX_SIZE + 1))); } void LLFloater::buildButtons() @@ -1697,15 +1579,15 @@ void LLFloater::buildButtons() { btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH, - mRect.getHeight() - CLOSE_BOX_FROM_TOP - (LLFLOATER_CLOSE_BOX_SIZE + 1) * (i + 1), + getRect().getHeight() - CLOSE_BOX_FROM_TOP - (LLFLOATER_CLOSE_BOX_SIZE + 1) * (i + 1), llround(LLFLOATER_CLOSE_BOX_SIZE * mButtonScale), llround(LLFLOATER_CLOSE_BOX_SIZE * mButtonScale)); } else { btn_rect.setLeftTopAndSize( - mRect.getWidth() - LLPANEL_BORDER_WIDTH - (LLFLOATER_CLOSE_BOX_SIZE + 1) * (i + 1), - mRect.getHeight() - CLOSE_BOX_FROM_TOP, + getRect().getWidth() - LLPANEL_BORDER_WIDTH - (LLFLOATER_CLOSE_BOX_SIZE + 1) * (i + 1), + getRect().getHeight() - CLOSE_BOX_FROM_TOP, llround(LLFLOATER_CLOSE_BOX_SIZE * mButtonScale), llround(LLFLOATER_CLOSE_BOX_SIZE * mButtonScale)); } @@ -1748,16 +1630,6 @@ LLFloaterView::LLFloaterView( const LLString& name, const LLRect& rect ) resetStartingFloaterPosition(); } -EWidgetType LLFloaterView::getWidgetType() const -{ - return WIDGET_TYPE_FLOATER_VIEW; -} - -LLString LLFloaterView::getWidgetTag() const -{ - return LL_FLOATER_VIEW_TAG; -} - // By default, adjust vertical. void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent) { @@ -1767,8 +1639,8 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent) // When reshaping this view, make the floaters follow their closest edge. void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent, BOOL adjust_vertical) { - S32 old_width = mRect.getWidth(); - S32 old_height = mRect.getHeight(); + S32 old_width = getRect().getWidth(); + S32 old_height = getRect().getHeight(); for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) { @@ -1822,7 +1694,7 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent, BOOL for(LLFloater::handle_set_iter_t dependent_it = floaterp->mDependents.begin(); dependent_it != floaterp->mDependents.end(); ++dependent_it) { - LLFloater* dependent_floaterp = getFloaterByHandle(*dependent_it); + LLFloater* dependent_floaterp = dependent_it->get(); if (dependent_floaterp) { dependent_floaterp->setFollows(follow_flags); @@ -1924,7 +1796,7 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF for(LLFloater::handle_set_iter_t dependent_it = reference_floater->mDependents.begin(); dependent_it != reference_floater->mDependents.end(); ++dependent_it) { - LLFloater* sibling = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* sibling = dependent_it->get(); // check for dependents within 10 pixels of base floater if (sibling && sibling != neighbor && @@ -1936,8 +1808,8 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF } S32 left_margin = llmax(0, base_rect.mLeft); - S32 right_margin = llmax(0, mRect.getWidth() - base_rect.mRight); - S32 top_margin = llmax(0, mRect.getHeight() - base_rect.mTop); + S32 right_margin = llmax(0, getRect().getWidth() - base_rect.mRight); + S32 top_margin = llmax(0, getRect().getHeight() - base_rect.mTop); S32 bottom_margin = llmax(0, base_rect.mBottom); // find position for floater in following order @@ -1946,22 +1818,22 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF { if (right_margin > width) { - new_rect.translate(base_rect.mRight - neighbor->mRect.mLeft, base_rect.mTop - neighbor->mRect.mTop); + new_rect.translate(base_rect.mRight - neighbor->getRect().mLeft, base_rect.mTop - neighbor->getRect().mTop); return new_rect; } else if (left_margin > width) { - new_rect.translate(base_rect.mLeft - neighbor->mRect.mRight, base_rect.mTop - neighbor->mRect.mTop); + new_rect.translate(base_rect.mLeft - neighbor->getRect().mRight, base_rect.mTop - neighbor->getRect().mTop); return new_rect; } else if (bottom_margin > height) { - new_rect.translate(base_rect.mLeft - neighbor->mRect.mLeft, base_rect.mBottom - neighbor->mRect.mTop); + new_rect.translate(base_rect.mLeft - neighbor->getRect().mLeft, base_rect.mBottom - neighbor->getRect().mTop); return new_rect; } else if (top_margin > height) { - new_rect.translate(base_rect.mLeft - neighbor->mRect.mLeft, base_rect.mTop - neighbor->mRect.mBottom); + new_rect.translate(base_rect.mLeft - neighbor->getRect().mLeft, base_rect.mTop - neighbor->getRect().mBottom); return new_rect; } @@ -1976,15 +1848,6 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF return new_rect; } -void LLFloaterView::setCycleMode(BOOL mode) -{ - mFocusCycleMode = mode; -} - -BOOL LLFloaterView::getCycleMode() -{ - return mFocusCycleMode; -} void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus) { @@ -2014,7 +1877,7 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus) for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); dependent_it != floater->mDependents.end(); ) { - LLFloater* sibling = LLFloater::getFloaterByHandle(*dependent_it); + LLFloater* sibling = dependent_it->get(); if (sibling) { floaters_to_move.push_back(sibling); @@ -2045,7 +1908,7 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus) for(LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin(); dependent_it != child->mDependents.end(); ) { - LLFloater* dependent = getFloaterByHandle(*dependent_it); + LLFloater* dependent = dependent_it->get(); if (dependent) { sendChildToFront(dependent); @@ -2086,7 +1949,7 @@ void LLFloaterView::highlightFocusedFloater() dependent_it != floater->mDependents.end(); ++dependent_it) { - LLFloater* dependent_floaterp = getFloaterByHandle(*dependent_it); + LLFloater* dependent_floaterp = dependent_it->get(); if (dependent_floaterp && gFocusMgr.childHasKeyboardFocus(dependent_floaterp)) { floater_or_dependent_has_focus = TRUE; @@ -2099,7 +1962,7 @@ void LLFloaterView::highlightFocusedFloater() for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin(); dependent_it != floater->mDependents.end(); ) { - LLFloater* dependent_floaterp = getFloaterByHandle(*dependent_it); + LLFloater* dependent_floaterp = dependent_it->get(); if (dependent_floaterp) { dependent_floaterp->setForeground(floater_or_dependent_has_focus); @@ -2260,42 +2123,40 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out if( floater->isResizable() ) { LLRect view_rect = floater->getRect(); - S32 view_width = view_rect.getWidth(); - S32 view_height = view_rect.getHeight(); + S32 old_width = view_rect.getWidth(); + S32 old_height = view_rect.getHeight(); S32 min_width; S32 min_height; floater->getResizeLimits( &min_width, &min_height ); // Make sure floater isn't already smaller than its min height/width? - S32 new_width = llmax( min_width, view_width ); - S32 new_height = llmax( min_height, view_height ); + S32 new_width = llmax( min_width, old_width ); + S32 new_height = llmax( min_height, old_height); - if( !allow_partial_outside - && ( (new_width > screen_width) - || (new_height > screen_height) ) ) + if((new_width > screen_width) || (new_height > screen_height)) { - // We have to force this window to be inside the screen. + // We have to make this window able to fit on screen new_width = llmin(new_width, screen_width); new_height = llmin(new_height, screen_height); - // Still respect minimum width/height + // ...while respecting minimum width/height new_width = llmax(new_width, min_width); new_height = llmax(new_height, min_height); floater->reshape( new_width, new_height, TRUE ); + if (floater->followsRight()) + { + floater->translate(old_width - new_width, 0); + } - // Make sure the damn thing is actually onscreen. - if (floater->translateIntoRect(snap_rect_local, FALSE)) + if (floater->followsTop()) { - floater->clearSnapTarget(); + floater->translate(0, old_height - new_height); } } - else if (!floater->isMinimized()) - { - floater->reshape(new_width, new_height, TRUE); - } } + // move window fully onscreen if (floater->translateIntoRect( snap_rect_local, allow_partial_outside )) { floater->clearSnapTarget(); @@ -2328,9 +2189,9 @@ void LLFloaterView::draw() } } -const LLRect LLFloaterView::getSnapRect() const +LLRect LLFloaterView::getSnapRect() const { - LLRect snap_rect = mRect; + LLRect snap_rect = getRect(); snap_rect.mBottom += mSnapOffsetBottom; return snap_rect; @@ -2397,23 +2258,6 @@ void LLFloaterView::syncFloaterTabOrder() } } -LLFloater* LLFloaterView::getFloaterByHandle(LLViewHandle handle) -{ - if (handle == LLViewHandle::sDeadHandle) - { - return NULL; - } - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) - { - LLView* viewp = *child_it; - if (((LLFloater*)viewp)->getHandle() == handle) - { - return (LLFloater*)viewp; - } - } - return NULL; -} - LLFloater* LLFloaterView::getParentFloater(LLView* viewp) { LLView* parentp = viewp->getParent(); @@ -2479,13 +2323,13 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) LLMultiFloater::LLMultiFloater() : mTabContainer(NULL), - mTabPos(LLTabContainerCommon::TOP), + mTabPos(LLTabContainer::TOP), mAutoResize(TRUE) { } -LLMultiFloater::LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos) : +LLMultiFloater::LLMultiFloater(LLTabContainer::TabPosition tab_pos) : mTabContainer(NULL), mTabPos(tab_pos), mAutoResize(TRUE) @@ -2496,7 +2340,7 @@ LLMultiFloater::LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos) : LLMultiFloater::LLMultiFloater(const LLString &name) : LLFloater(name), mTabContainer(NULL), - mTabPos(LLTabContainerCommon::TOP), + mTabPos(LLTabContainer::TOP), mAutoResize(FALSE) { } @@ -2508,16 +2352,16 @@ LLMultiFloater::LLMultiFloater( BOOL auto_resize) : LLFloater(name, rect, name), mTabContainer(NULL), - mTabPos(LLTabContainerCommon::TOP), + mTabPos(LLTabContainer::TOP), mAutoResize(auto_resize) { mTabContainer = new LLTabContainer("Preview Tabs", - LLRect(LLPANEL_BORDER_WIDTH, mRect.getHeight() - LLFLOATER_HEADER_SIZE, mRect.getWidth() - LLPANEL_BORDER_WIDTH, 0), + LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0), mTabPos, - NULL, - NULL); + FALSE, + FALSE); mTabContainer->setFollowsAll(); - if (mResizable) + if (isResizable()) { mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH); } @@ -2536,12 +2380,12 @@ LLMultiFloater::LLMultiFloater( mAutoResize(auto_resize) { mTabContainer = new LLTabContainer("Preview Tabs", - LLRect(LLPANEL_BORDER_WIDTH, mRect.getHeight() - LLFLOATER_HEADER_SIZE, mRect.getWidth() - LLPANEL_BORDER_WIDTH, 0), - mTabPos, - NULL, - NULL); + LLRect(LLPANEL_BORDER_WIDTH, getRect().getHeight() - LLFLOATER_HEADER_SIZE, getRect().getWidth() - LLPANEL_BORDER_WIDTH, 0), + mTabPos, + FALSE, + FALSE); mTabContainer->setFollowsAll(); - if (mResizable && mTabPos == LLTabContainerCommon::BOTTOM) + if (isResizable() && mTabPos == LLTabContainer::BOTTOM) { mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH); } @@ -2550,21 +2394,6 @@ LLMultiFloater::LLMultiFloater( } -LLMultiFloater::~LLMultiFloater() -{ -} - -// virtual -EWidgetType LLMultiFloater::getWidgetType() const -{ - return WIDGET_TYPE_MULTI_FLOATER; -} - -// virtual -LLString LLMultiFloater::getWidgetTag() const -{ - return LL_MULTI_FLOATER_TAG; -} void LLMultiFloater::open() /* Flawfinder: ignore */ { @@ -2584,7 +2413,7 @@ void LLMultiFloater::onClose(bool app_quitting) { if(closeAllFloaters() == TRUE) { - LLFloater::onClose(app_quitting ? true : false); + LLFloater::onClose(app_quitting); }//else not all tabs could be closed... } @@ -2635,16 +2464,18 @@ BOOL LLMultiFloater::closeAllFloaters() void LLMultiFloater::growToFit(S32 content_width, S32 content_height) { - S32 new_width = llmax(mRect.getWidth(), content_width + LLPANEL_BORDER_WIDTH * 2); - S32 new_height = llmax(mRect.getHeight(), content_height + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT); + S32 new_width = llmax(getRect().getWidth(), content_width + LLPANEL_BORDER_WIDTH * 2); + S32 new_height = llmax(getRect().getHeight(), content_height + LLFLOATER_HEADER_SIZE + TABCNTR_HEADER_HEIGHT); - if (isMinimized()) - { - mPreviousRect.setLeftTopAndSize(mPreviousRect.mLeft, mPreviousRect.mTop, new_width, new_height); - } + if (isMinimized()) + { + LLRect newrect; + newrect.setLeftTopAndSize(getExpandedRect().mLeft, getExpandedRect().mTop, new_width, new_height); + setExpandedRect(newrect); + } else { - S32 old_height = mRect.getHeight(); + S32 old_height = getRect().getHeight(); reshape(new_width, new_height); // keep top left corner in same position translate(0, old_height - new_height); @@ -2729,7 +2560,7 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, } floaterp->setHost(this); - if (mMinimized) + if (isMinimized()) { floaterp->setVisible(FALSE); } @@ -2912,7 +2743,7 @@ void LLMultiFloater::onTabSelected(void* userdata, bool from_click) void LLMultiFloater::setCanResize(BOOL can_resize) { LLFloater::setCanResize(can_resize); - if (mResizable && mTabContainer->getTabPosition() == LLTabContainer::BOTTOM) + if (isResizable() && mTabContainer->getTabPosition() == LLTabContainer::BOTTOM) { mTabContainer->setRightTabBtnOffset(RESIZE_HANDLE_WIDTH); } @@ -2955,20 +2786,23 @@ void LLMultiFloater::updateResizeLimits() } setResizeLimits(new_min_width, new_min_height); - S32 cur_height = mRect.getHeight(); - S32 new_width = llmax(mRect.getWidth(), new_min_width); - S32 new_height = llmax(mRect.getHeight(), new_min_height); + S32 cur_height = getRect().getHeight(); + S32 new_width = llmax(getRect().getWidth(), new_min_width); + S32 new_height = llmax(getRect().getHeight(), new_min_height); if (isMinimized()) { - mPreviousRect.setLeftTopAndSize(mPreviousRect.mLeft, mPreviousRect.mTop, llmax(mPreviousRect.getWidth(), new_width), llmax(mPreviousRect.getHeight(), new_height)); + const LLRect& expanded = getExpandedRect(); + LLRect newrect; + newrect.setLeftTopAndSize(expanded.mLeft, expanded.mTop, llmax(expanded.getWidth(), new_width), llmax(expanded.getHeight(), new_height)); + setExpandedRect(newrect); } else { reshape(new_width, new_height); // make sure upper left corner doesn't move - translate(0, cur_height - mRect.getHeight()); + translate(0, cur_height - getRect().getHeight()); // make sure this window is visible on screen when it has been modified // (tab added, etc) diff --git a/linden/indra/llui/llfloater.h b/linden/indra/llui/llfloater.h index 56b0e6e..534af16 100644 --- a/linden/indra/llui/llfloater.h +++ b/linden/indra/llui/llfloater.h @@ -112,8 +112,8 @@ public: void initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory, BOOL open = TRUE); /*virtual*/ void userSetShape(const LLRect& new_rect); - /*virtual*/ BOOL canSnapTo(LLView* other_view); - /*virtual*/ void snappedTo(LLView* snap_view); + /*virtual*/ BOOL canSnapTo(const LLView* other_view); + /*virtual*/ void snappedTo(const LLView* snap_view); /*virtual*/ void setFocus( BOOL b ); /*virtual*/ void setIsChrome(BOOL is_chrome); @@ -122,16 +122,14 @@ public: virtual void init(const LLString& title, BOOL resizable, S32 min_width, S32 min_height, BOOL drag_on_left, BOOL minimizable, BOOL close_btn); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_FLOATER; } + virtual LLString getWidgetTag() const { return LL_FLOATER_TAG; }; virtual void open(); /* Flawfinder: ignore */ // If allowed, close the floater cleanly, releasing focus. // app_quitting is passed to onClose() below. virtual void close(bool app_quitting = false); - - void setAutoFocus(BOOL focus) { mAutoFocus = focus; setFocus(focus); } // Release keyboard and mouse focus void releaseFocus(); @@ -142,18 +140,18 @@ public: void applyRectControl(); - LLMultiFloater* getHost() { return (LLMultiFloater*)LLFloater::getFloaterByHandle(mHostHandle); } + LLMultiFloater* getHost() { return (LLMultiFloater*)mHostHandle.get(); } void setTitle( const LLString& title ); - const LLString& getTitle() const; + const LLString& getTitle() const; void setShortTitle( const LLString& short_title ); LLString getShortTitle(); virtual void setMinimized(BOOL b); void moveResizeHandlesToFront(); void addDependentFloater(LLFloater* dependent, BOOL reposition = TRUE); - void addDependentFloater(LLViewHandle dependent_handle, BOOL reposition = TRUE); - LLFloater* getDependee() { return (LLFloater*)LLFloater::getFloaterByHandle(mDependeeHandle); } - void removeDependentFloater(LLFloater* dependent); + void addDependentFloater(LLHandle dependent_handle, BOOL reposition = TRUE); + LLFloater* getDependee() { return (LLFloater*)mDependeeHandle.get(); } + void removeDependentFloater(LLFloater* dependent); BOOL isMinimized() { return mMinimized; } BOOL isFrontmost(); BOOL isDependent() { return !mDependeeHandle.isDead(); } @@ -167,10 +165,9 @@ public: void setResizeLimits( S32 min_width, S32 min_height ); void getResizeLimits( S32* min_width, S32* min_height ) { *min_width = mMinWidth; *min_height = mMinHeight; } - bool isMinimizeable() const{ return mButtonsEnabled[BUTTON_MINIMIZE]; } // Does this window have a close button, NOT can we close it right now. - bool isCloseable() const{ return (mButtonsEnabled[BUTTON_CLOSE] ? true : false); } + bool isCloseable() const{ return (mButtonsEnabled[BUTTON_CLOSE]); } bool isDragOnLeft() const{ return mDragOnLeft; } S32 getMinWidth() const{ return mMinWidth; } S32 getMinHeight() const{ return mMinHeight; } @@ -181,29 +178,28 @@ public: virtual void draw(); - // does nothing by default - virtual void onOpen(); + virtual void onOpen() {} // Call destroy() to free memory, or setVisible(FALSE) to keep it // If app_quitting, you might not want to save your visibility. // Defaults to destroy(). - virtual void onClose(bool app_quitting); + virtual void onClose(bool app_quitting) { destroy(); } - // Defaults to true. - virtual BOOL canClose(); + virtual BOOL canClose() { return TRUE; } virtual void setVisible(BOOL visible); void setFrontmost(BOOL take_focus = TRUE); // Defaults to false. - virtual BOOL canSaveAs(); + virtual BOOL canSaveAs() const { return FALSE; } - // Defaults to no-op. - virtual void saveAs(); + virtual void saveAs() {} - void setSnapTarget(LLViewHandle handle) { mSnappedTo = handle; } + void setSnapTarget(LLHandle handle) { mSnappedTo = handle; } void clearSnapTarget() { mSnappedTo.markDead(); } - LLViewHandle getSnapTarget() { return mSnappedTo; } + LLHandle getSnapTarget() { return mSnappedTo; } + + LLHandle getHandle() { return mHandle; } static void closeFocusedFloater(); @@ -214,39 +210,39 @@ public: static void setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; } static void setEditModeEnabled(BOOL enable); - static BOOL getEditModeEnabled(); + static BOOL getEditModeEnabled() { return sEditModeEnabled; } static LLMultiFloater* getFloaterHost() {return sHostp; } - static void show(LLFloater* floaterp); - static void hide(LLFloater* floaterp); - static BOOL visible(LLFloater* floaterp); - - static LLFloater* getFloaterByHandle(LLViewHandle handle); - protected: - // Don't call this directly. You probably want to call close(). JC - void destroy(); + virtual void bringToFront(S32 x, S32 y); - virtual void setVisibleAndFrontmost(BOOL take_focus=TRUE); + virtual void setVisibleAndFrontmost(BOOL take_focus=TRUE); + + void setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized + const LLRect& getExpandedRect() const { return mExpandedRect; } + + void setAutoFocus(BOOL focus) { mAutoFocus = focus; } // whether to automatically take focus when opened + LLDragHandle* getDragHandle() const { return mDragHandle; } + + void destroy() { die(); } // Don't call this directly. You probably want to call close(). JC + +private: + void setForeground(BOOL b); // called only by floaterview void cleanupHandles(); // remove handles to dead floaters void createMinimizeButton(); void updateButtons(); void buildButtons(); -protected: -// static LLViewerImage* sBackgroundImage; -// static LLViewerImage* sShadowImage; - + LLRect mExpandedRect; LLDragHandle* mDragHandle; LLResizeBar* mResizeBar[4]; LLResizeHandle* mResizeHandle[4]; LLButton *mMinimizeButton; BOOL mCanTearOff; BOOL mMinimized; - LLRect mPreviousRect; BOOL mForeground; - LLViewHandle mDependeeHandle; + LLHandle mDependeeHandle; LLString mShortTitle; BOOL mFirstLook; // TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible. @@ -255,25 +251,24 @@ protected: S32 mMinWidth; S32 mMinHeight; - BOOL mAutoFocus; BOOL mEditing; - typedef std::set handle_set_t; - typedef std::set::iterator handle_set_iter_t; + typedef std::set > handle_set_t; + typedef std::set >::iterator handle_set_iter_t; handle_set_t mDependents; bool mDragOnLeft; BOOL mButtonsEnabled[BUTTON_COUNT]; LLButton* mButtons[BUTTON_COUNT]; F32 mButtonScale; - - LLViewHandle mSnappedTo; + BOOL mAutoFocus; + LLHandle mSnappedTo; - LLViewHandle mHostHandle; - LLViewHandle mLastHostHandle; + LLHandle mHostHandle; + LLHandle mLastHostHandle; - static BOOL sEditModeEnabled; static LLMultiFloater* sHostp; + static BOOL sEditModeEnabled; static LLString sButtonActiveImageNames[BUTTON_COUNT]; static LLString sButtonInactiveImageNames[BUTTON_COUNT]; static LLString sButtonPressedImageNames[BUTTON_COUNT]; @@ -282,15 +277,18 @@ protected: typedef void (*click_callback)(void *); static click_callback sButtonCallbacks[BUTTON_COUNT]; - typedef std::map handle_map_t; - typedef std::map::iterator handle_map_iter_t; + typedef std::map, LLFloater*> handle_map_t; + typedef std::map, LLFloater*>::iterator handle_map_iter_t; static handle_map_t sFloaterMap; - std::vector mMinimizedHiddenChildren; + std::vector > mMinimizedHiddenChildren; BOOL mHasBeenDraggedWhileMinimized; S32 mPreviousMinimizedBottom; S32 mPreviousMinimizedLeft; + +private: + LLRootHandle mHandle; }; ///////////////////////////////////////////////////////////// @@ -302,14 +300,14 @@ class LLFloaterView : public LLUICtrl public: LLFloaterView( const LLString& name, const LLRect& rect ); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_FLOATER_VIEW; } + virtual LLString getWidgetTag() const { return LL_FLOATER_VIEW_TAG; } /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); void reshape(S32 width, S32 height, BOOL called_from_parent, BOOL adjust_vertical); /*virtual*/ void draw(); - /*virtual*/ const LLRect getSnapRect() const; + /*virtual*/ LLRect getSnapRect() const; void refresh(); void getNewFloaterPosition( S32* left, S32* top ); @@ -325,8 +323,8 @@ public: void pushVisibleAll(BOOL visible, const skip_list_t& skip_list = skip_list_t()); void popVisibleAll(const skip_list_t& skip_list = skip_list_t()); - void setCycleMode(BOOL mode); - BOOL getCycleMode(); + void setCycleMode(BOOL mode) { mFocusCycleMode = mode; } + BOOL getCycleMode() const { return mFocusCycleMode; } void bringToFront( LLFloater* child, BOOL give_focus = TRUE ); void highlightFocusedFloater(); void unhighlightFocusedFloater(); @@ -342,10 +340,6 @@ public: LLFloater* getFocusedFloater(); void syncFloaterTabOrder(); - // Get a floater based the handle. If this returns NULL, it is up - // to the caller to discard the handle. - LLFloater* getFloaterByHandle(LLViewHandle handle); - // Returns z order of child provided. 0 is closest, larger numbers // are deeper in the screen. If there is no such child, the return // value is not defined. @@ -361,15 +355,16 @@ private: S32 mSnapOffsetBottom; }; +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLMultiFloater&oldid=81376 class LLMultiFloater : public LLFloater { public: LLMultiFloater(); - LLMultiFloater(LLTabContainerCommon::TabPosition tab_pos); + LLMultiFloater(LLTabContainer::TabPosition tab_pos); LLMultiFloater(const LLString& name); LLMultiFloater(const LLString& name, const LLRect& rect, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE); LLMultiFloater(const LLString& name, const LLString& rect_control, LLTabContainer::TabPosition tab_pos = LLTabContainer::TOP, BOOL auto_resize = TRUE); - virtual ~LLMultiFloater(); + virtual ~LLMultiFloater() {}; virtual BOOL postBuild(); /*virtual*/ void open(); /* Flawfinder: ignore */ @@ -377,12 +372,12 @@ public: /*virtual*/ void draw(); /*virtual*/ void setVisible(BOOL visible); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); - /*virtual*/ EWidgetType getWidgetType() const; - /*virtual*/ LLString getWidgetTag() const; + /*virtual*/ EWidgetType getWidgetType() const { return WIDGET_TYPE_MULTI_FLOATER; } + /*virtual*/ LLString getWidgetTag() const { return LL_MULTI_FLOATER_TAG; }; virtual void setCanResize(BOOL can_resize); virtual void growToFit(S32 content_width, S32 content_height); - virtual void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainerCommon::eInsertionPoint insertion_point = LLTabContainerCommon::END); + virtual void addFloater(LLFloater* floaterp, BOOL select_added_floater, LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); virtual void showFloater(LLFloater* floaterp); virtual void removeFloater(LLFloater* floaterp); @@ -400,7 +395,7 @@ public: virtual void setFloaterFlashing(LLFloater* floaterp, BOOL flashing); virtual BOOL closeAllFloaters(); //Returns FALSE if the floater could not be closed due to pending confirmation dialogs - void setTabContainer(LLTabContainerCommon* tab_container) { if (!mTabContainer) mTabContainer = tab_container; } + void setTabContainer(LLTabContainer* tab_container) { if (!mTabContainer) mTabContainer = tab_container; } static void onTabSelected(void* userdata, bool); virtual void updateResizeLimits(); @@ -414,15 +409,56 @@ protected: BOOL mCanResize; }; - LLTabContainerCommon* mTabContainer; + LLTabContainer* mTabContainer; - typedef std::map floater_data_map_t; + typedef std::map, LLFloaterData> floater_data_map_t; floater_data_map_t mFloaterDataMap; - LLTabContainerCommon::TabPosition mTabPos; + LLTabContainer::TabPosition mTabPos; BOOL mAutoResize; }; +// visibility policy specialized for floaters +template<> +class VisibilityPolicy +{ +public: + // visibility methods + static bool visible(LLFloater* instance, const LLSD& key) + { + if (instance) + { + return !instance->isMinimized() && instance->isInVisibleChain(); + } + return FALSE; + } + + static void show(LLFloater* instance, const LLSD& key) + { + if (instance) + { + instance->open(); + if (instance->getHost()) + { + instance->getHost()->open(); + } + } + } + + static void hide(LLFloater* instance, const LLSD& key) + { + if (instance) instance->close(); + } +}; + + +// singleton implementation for floaters (provides visibility policy) +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=79410 + +template class LLFloaterSingleton : public LLUISingleton > +{ +}; + extern LLFloaterView* gFloaterView; diff --git a/linden/indra/llui/llfocusmgr.cpp b/linden/indra/llui/llfocusmgr.cpp index efca3d8..0634513 100644 --- a/linden/indra/llui/llfocusmgr.cpp +++ b/linden/indra/llui/llfocusmgr.cpp @@ -57,12 +57,8 @@ LLFocusMgr::LLFocusMgr() { } -LLFocusMgr::~LLFocusMgr() -{ - mFocusHistory.clear(); -} -void LLFocusMgr::releaseFocusIfNeeded( LLView* view ) +void LLFocusMgr::releaseFocusIfNeeded( const LLView* view ) { if( childHasMouseCapture( view ) ) { @@ -146,7 +142,7 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock) if (focus_subtree) { - mFocusHistory[focus_subtree->mViewHandle] = mKeyboardFocus ? mKeyboardFocus->mViewHandle : LLViewHandle::sDeadHandle; + mFocusHistory[focus_subtree->getHandle()] = mKeyboardFocus ? mKeyboardFocus->getHandle() : LLHandle(); } } @@ -156,10 +152,6 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock) } } -void LLFocusMgr::setDefaultKeyboardFocus(LLUICtrl* default_focus) -{ - mDefaultKeyboardFocus = default_focus; -} // Returns TRUE is parent or any descedent of parent has keyboard focus. BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const @@ -177,7 +169,7 @@ BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const } // Returns TRUE is parent or any descedent of parent is the mouse captor. -BOOL LLFocusMgr::childHasMouseCapture( LLView* parent ) +BOOL LLFocusMgr::childHasMouseCapture( const LLView* parent ) const { if( mMouseCaptor && mMouseCaptor->isView() ) { @@ -194,7 +186,7 @@ BOOL LLFocusMgr::childHasMouseCapture( LLView* parent ) return FALSE; } -void LLFocusMgr::removeKeyboardFocusWithoutCallback( LLView* focus ) +void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLView* focus ) { // should be ok to unlock here, as you have to know the locked view // in order to unlock it @@ -253,7 +245,7 @@ void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor ) } } -void LLFocusMgr::removeMouseCaptureWithoutCallback( LLMouseHandler* captor ) +void LLFocusMgr::removeMouseCaptureWithoutCallback( const LLMouseHandler* captor ) { //if (mFocusLocked) //{ @@ -269,7 +261,7 @@ void LLFocusMgr::removeMouseCaptureWithoutCallback( LLMouseHandler* captor ) } -BOOL LLFocusMgr::childIsTopCtrl( LLView* parent ) +BOOL LLFocusMgr::childIsTopCtrl( const LLView* parent ) const { LLView* top_view = (LLView*)mTopCtrl; while( top_view ) @@ -304,7 +296,7 @@ void LLFocusMgr::setTopCtrl( LLUICtrl* new_top ) } } -void LLFocusMgr::removeTopCtrlWithoutCallback( LLUICtrl* top_view ) +void LLFocusMgr::removeTopCtrlWithoutCallback( const LLUICtrl* top_view ) { if( mTopCtrl == top_view ) { @@ -325,12 +317,12 @@ void LLFocusMgr::unlockFocus() mLockedView = NULL; } -F32 LLFocusMgr::getFocusFlashAmt() +F32 LLFocusMgr::getFocusFlashAmt() const { return clamp_rescale(getFocusTime(), 0.f, FOCUS_FADE_TIME, mFocusWeight, 0.f); } -LLColor4 LLFocusMgr::getFocusColor() +LLColor4 LLFocusMgr::getFocusColor() const { LLColor4 focus_color = lerp(LLUI::sColorsGroup->getColor( "FocusColor" ), LLColor4::white, getFocusFlashAmt()); // de-emphasize keyboard focus when app has lost focus (to avoid typing into wrong window problem) @@ -362,15 +354,15 @@ void LLFocusMgr::setAppHasFocus(BOOL focus) mAppHasFocus = focus; } -LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) +LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const { if (subtree_root) { - focus_history_map_t::iterator found_it = mFocusHistory.find(subtree_root->mViewHandle); + focus_history_map_t::const_iterator found_it = mFocusHistory.find(subtree_root->getHandle()); if (found_it != mFocusHistory.end()) { // found last focus for this subtree - return static_cast(LLView::getViewByHandle(found_it->second)); + return static_cast(found_it->second.get()); } } return NULL; @@ -380,6 +372,6 @@ void LLFocusMgr::clearLastFocusForGroup(LLView* subtree_root) { if (subtree_root) { - mFocusHistory.erase(subtree_root->mViewHandle); + mFocusHistory.erase(subtree_root->getHandle()); } } diff --git a/linden/indra/llui/llfocusmgr.h b/linden/indra/llui/llfocusmgr.h index 3bd5b35..842c874 100644 --- a/linden/indra/llui/llfocusmgr.h +++ b/linden/indra/llui/llfocusmgr.h @@ -45,48 +45,48 @@ class LLFocusMgr { public: LLFocusMgr(); - ~LLFocusMgr(); + ~LLFocusMgr() { mFocusHistory.clear(); } // Mouse Captor void setMouseCapture(LLMouseHandler* new_captor); // new_captor = NULL to release the mouse. - LLMouseHandler* getMouseCapture() { return mMouseCaptor; } - void removeMouseCaptureWithoutCallback( LLMouseHandler* captor ); - BOOL childHasMouseCapture( LLView* parent ); + LLMouseHandler* getMouseCapture() const { return mMouseCaptor; } + void removeMouseCaptureWithoutCallback( const LLMouseHandler* captor ); + BOOL childHasMouseCapture( const LLView* parent ) const; // Keyboard Focus void setKeyboardFocus(LLUICtrl* new_focus, BOOL lock = FALSE); // new_focus = NULL to release the focus. LLUICtrl* getKeyboardFocus() const { return mKeyboardFocus; } LLUICtrl* getLastKeyboardFocus() const { return mLastKeyboardFocus; } BOOL childHasKeyboardFocus( const LLView* parent ) const; - void removeKeyboardFocusWithoutCallback( LLView* focus ); + void removeKeyboardFocusWithoutCallback( const LLView* focus ); F32 getFocusTime() const { return mFocusTimer.getElapsedTimeF32(); } - F32 getFocusFlashAmt(); - LLColor4 getFocusColor(); + F32 getFocusFlashAmt() const; + LLColor4 getFocusColor() const; void triggerFocusFlash(); - BOOL getAppHasFocus() { return mAppHasFocus; } + BOOL getAppHasFocus() const { return mAppHasFocus; } void setAppHasFocus(BOOL focus); - LLUICtrl* getLastFocusForGroup(LLView* subtree_root); + LLUICtrl* getLastFocusForGroup(LLView* subtree_root) const; void clearLastFocusForGroup(LLView* subtree_root); // If setKeyboardFocus(NULL) is called, and there is a non-NULL default // keyboard focus view, focus goes there. JC - void setDefaultKeyboardFocus(LLUICtrl* default_focus); + void setDefaultKeyboardFocus(LLUICtrl* default_focus) { mDefaultKeyboardFocus = default_focus; } LLUICtrl* getDefaultKeyboardFocus() const { return mDefaultKeyboardFocus; } // Top View void setTopCtrl(LLUICtrl* new_top); LLUICtrl* getTopCtrl() const { return mTopCtrl; } - void removeTopCtrlWithoutCallback( LLUICtrl* top_view ); - BOOL childIsTopCtrl( LLView* parent ); + void removeTopCtrlWithoutCallback( const LLUICtrl* top_view ); + BOOL childIsTopCtrl( const LLView* parent ) const; // All Three - void releaseFocusIfNeeded( LLView* top_view ); + void releaseFocusIfNeeded( const LLView* top_view ); void lockFocus(); void unlockFocus(); - BOOL focusLocked() { return mLockedView != NULL; } + BOOL focusLocked() const { return mLockedView != NULL; } -protected: +private: LLUICtrl* mLockedView; // Mouse Captor @@ -105,7 +105,7 @@ protected: BOOL mAppHasFocus; - typedef std::map focus_history_map_t; + typedef std::map, LLHandle > focus_history_map_t; focus_history_map_t mFocusHistory; #ifdef _DEBUG @@ -119,3 +119,4 @@ extern LLFocusMgr gFocusMgr; #endif // LL_LLFOCUSMGR_H + diff --git a/linden/indra/llui/lliconctrl.cpp b/linden/indra/llui/lliconctrl.cpp index 79982c6..6a1d77c 100644 --- a/linden/indra/llui/lliconctrl.cpp +++ b/linden/indra/llui/lliconctrl.cpp @@ -91,8 +91,8 @@ void LLIconCtrl::draw() if( mImagep.notNull() ) { mImagep->draw(0, 0, - mRect.getWidth(), mRect.getHeight(), - mColor ); + getRect().getWidth(), getRect().getHeight(), + mColor ); } LLUICtrl::draw(); diff --git a/linden/indra/llui/lliconctrl.h b/linden/indra/llui/lliconctrl.h index f767b3c..b0c191f 100644 --- a/linden/indra/llui/lliconctrl.h +++ b/linden/indra/llui/lliconctrl.h @@ -69,7 +69,7 @@ public: virtual LLXMLNodePtr getXML(bool save_children = true) const; static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); -protected: +private: LLColor4 mColor; LLString mImageName; LLUUID mImageID; diff --git a/linden/indra/llui/llkeywords.cpp b/linden/indra/llui/llkeywords.cpp index 1d157d2..d5d0d23 100644 --- a/linden/indra/llui/llkeywords.cpp +++ b/linden/indra/llui/llkeywords.cpp @@ -41,7 +41,7 @@ const U32 KEYWORD_FILE_CURRENT_VERSION = 2; -inline BOOL LLKeywordToken::isHead(const llwchar* s) +inline BOOL LLKeywordToken::isHead(const llwchar* s) const { // strncmp is much faster than string compare BOOL res = TRUE; diff --git a/linden/indra/llui/llkeywords.h b/linden/indra/llui/llkeywords.h index d5d7302..61c3c57 100644 --- a/linden/indra/llui/llkeywords.h +++ b/linden/indra/llui/llkeywords.h @@ -56,11 +56,12 @@ public: { } - S32 getLength() { return mToken.size(); } - BOOL isHead(const llwchar* s); - const LLColor3& getColor() { return mColor; } - TOKEN_TYPE getType() { return mType; } - const LLWString& getToolTip() { return mToolTip; } + S32 getLength() const { return mToken.size(); } + BOOL isHead(const llwchar* s) const; + const LLWString& getToken() const { return mToken; } + const LLColor3& getColor() const { return mColor; } + TOKEN_TYPE getType() const { return mType; } + const LLWString& getToolTip() const { return mToolTip; } #ifdef _DEBUG void dump(); @@ -68,10 +69,8 @@ public: private: TOKEN_TYPE mType; -public: LLWString mToken; LLColor3 mColor; -private: LLWString mToolTip; }; @@ -82,30 +81,31 @@ public: ~LLKeywords(); BOOL loadFromFile(const LLString& filename); - BOOL isLoaded() { return mLoaded; } + BOOL isLoaded() const { return mLoaded; } void findSegments(std::vector *seg_list, const LLWString& text, const LLColor4 &defaultColor ); -#ifdef _DEBUG - void dump(); -#endif - // Add the token as described void addToken(LLKeywordToken::TOKEN_TYPE type, const LLString& key, const LLColor3& color, const LLString& tool_tip = LLString::null); + typedef std::map word_token_map_t; + typedef word_token_map_t::const_iterator keyword_iterator_t; + keyword_iterator_t begin() const { return mWordTokenMap.begin(); } + keyword_iterator_t end() const { return mWordTokenMap.end(); } + +#ifdef _DEBUG + void dump(); +#endif + private: LLColor3 readColor(const LLString& s); void insertSegment(std::vector *seg_list, LLTextSegment* new_segment, S32 text_len, const LLColor4 &defaultColor); -private: - BOOL mLoaded; -public: - typedef std::map word_token_map_t; + BOOL mLoaded; word_token_map_t mWordTokenMap; -private: typedef std::deque token_list_t; token_list_t mLineTokenList; token_list_t mDelimiterTokenList; diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index b091bb7..1c96bc4 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp @@ -81,44 +81,6 @@ const S32 PREEDIT_STANDOUT_GAP = 1; const S32 PREEDIT_STANDOUT_POSITION = 2; const S32 PREEDIT_STANDOUT_THICKNESS = 2; -// This is a friend class of and is only used by LLLineEditor -class LLLineEditorRollback -{ -public: - LLLineEditorRollback( LLLineEditor* ed ) - : - mCursorPos( ed->mCursorPos ), - mScrollHPos( ed->mScrollHPos ), - mIsSelecting( ed->mIsSelecting ), - mSelectionStart( ed->mSelectionStart ), - mSelectionEnd( ed->mSelectionEnd ) - { - mText = ed->getText(); - } - - void doRollback( LLLineEditor* ed ) - { - ed->mCursorPos = mCursorPos; - ed->mScrollHPos = mScrollHPos; - ed->mIsSelecting = mIsSelecting; - ed->mSelectionStart = mSelectionStart; - ed->mSelectionEnd = mSelectionEnd; - ed->mText = mText; - ed->mPrevText = mText; - } - - LLString getText() { return mText; } - -private: - LLString mText; - S32 mCursorPos; - S32 mScrollHPos; - BOOL mIsSelecting; - S32 mSelectionStart; - S32 mSelectionEnd; -}; - - // // Member functions // @@ -190,7 +152,7 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect, setFocusLostCallback(focus_lost_callback); mMinHPixels = mBorderThickness + UI_LINEEDITOR_H_PAD + mBorderLeft; - mMaxHPixels = mRect.getWidth() - mMinHPixels - mBorderThickness - mBorderRight; + mMaxHPixels = getRect().getWidth() - mMinHPixels - mBorderThickness - mBorderRight; mScrollTimer.reset(); @@ -200,7 +162,7 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect, // Scalable UI somehow made these rectangles off-by-one. // I don't know why. JC - LLRect border_rect(0, mRect.getHeight()-1, mRect.getWidth()-1, 0); + LLRect border_rect(0, getRect().getHeight()-1, getRect().getWidth()-1, 0); mBorder = new LLViewBorder( "line ed border", border_rect, border_bevel, border_style, mBorderThickness ); addChild( mBorder ); mBorder->setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP|FOLLOWS_BOTTOM); @@ -219,17 +181,6 @@ LLLineEditor::~LLLineEditor() } } -//virtual -EWidgetType LLLineEditor::getWidgetType() const -{ - return WIDGET_TYPE_LINE_EDITOR; -} - -//virtual -LLString LLLineEditor::getWidgetTag() const -{ - return LL_LINE_EDITOR_TAG; -} void LLLineEditor::onFocusReceived() { @@ -269,18 +220,6 @@ void LLLineEditor::onCommit() selectAll(); } -// virtual -BOOL LLLineEditor::isDirty() const -{ - return ( mText.getString() != mPrevText ); -} - -// virtual -void LLLineEditor::resetDirty() -{ - mPrevText = mText.getString(); -} - // line history support void LLLineEditor::updateHistory() @@ -306,12 +245,7 @@ void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent) { LLUICtrl::reshape(width, height, called_from_parent ); - mMaxHPixels = mRect.getWidth() - 2 * (mBorderThickness + UI_LINEEDITOR_H_PAD) + 1 - mBorderRight; -} - -void LLLineEditor::setEnableLineHistory( BOOL enabled ) -{ - mHaveHistory = enabled; + mMaxHPixels = getRect().getWidth() - 2 * (mBorderThickness + UI_LINEEDITOR_H_PAD) + 1 - mBorderRight; } void LLLineEditor::setEnabled(BOOL enabled) @@ -330,16 +264,12 @@ void LLLineEditor::setMaxTextLength(S32 max_text_length) void LLLineEditor::setBorderWidth(S32 left, S32 right) { - mBorderLeft = llclamp(left, 0, mRect.getWidth()); - mBorderRight = llclamp(right, 0, mRect.getWidth()); + mBorderLeft = llclamp(left, 0, getRect().getWidth()); + mBorderRight = llclamp(right, 0, getRect().getWidth()); mMinHPixels = mBorderThickness + UI_LINEEDITOR_H_PAD + mBorderLeft; - mMaxHPixels = mRect.getWidth() - mMinHPixels - mBorderThickness - mBorderRight; + mMaxHPixels = getRect().getWidth() - mMinHPixels - mBorderThickness - mBorderRight; } -void LLLineEditor::setLabel(const LLStringExplicit &new_label) -{ - mLabel = new_label; -} void LLLineEditor::setText(const LLStringExplicit &new_text) { @@ -451,12 +381,11 @@ void LLLineEditor::setCursorToEnd() deselect(); } -BOOL LLLineEditor::canDeselect() +BOOL LLLineEditor::canDeselect() const { return hasSelection(); } - void LLLineEditor::deselect() { mSelectionStart = 0; @@ -481,7 +410,7 @@ void LLLineEditor::endSelection() } } -BOOL LLLineEditor::canSelectAll() +BOOL LLLineEditor::canSelectAll() const { return TRUE; } @@ -554,7 +483,7 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask) BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask) { - if (x < mBorderLeft || x > (mRect.getWidth() - mBorderRight)) + if (x < mBorderLeft || x > (getRect().getWidth() - mBorderRight)) { return LLUICtrl::handleMouseDown(x, y, mask); } @@ -634,7 +563,7 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; - if (!hasMouseCapture() && (x < mBorderLeft || x > (mRect.getWidth() - mBorderRight))) + if (!hasMouseCapture() && (x < mBorderLeft || x > (getRect().getWidth() - mBorderRight))) { return LLUICtrl::handleHover(x, y, mask); } @@ -705,7 +634,7 @@ BOOL LLLineEditor::handleMouseUp(S32 x, S32 y, MASK mask) handled = TRUE; } - if (!handled && (x < mBorderLeft || x > (mRect.getWidth() - mBorderRight))) + if (!handled && (x < mBorderLeft || x > (getRect().getWidth() - mBorderRight))) { return LLUICtrl::handleMouseUp(x, y, mask); } @@ -856,11 +785,6 @@ BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) switch( key ) { case KEY_LEFT: - if (mIgnoreArrowKeys) - { - handled = FALSE; - break; - } if( 0 < getCursor() ) { S32 cursorPos = getCursor() - 1; @@ -877,11 +801,6 @@ BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) break; case KEY_RIGHT: - if (mIgnoreArrowKeys) - { - handled = FALSE; - break; - } if( getCursor() < mText.length()) { S32 cursorPos = getCursor() + 1; @@ -899,22 +818,12 @@ BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) case KEY_PAGE_UP: case KEY_HOME: - if (mIgnoreArrowKeys) - { - handled = FALSE; - break; - } extendSelection( 0 ); break; case KEY_PAGE_DOWN: case KEY_END: { - if (mIgnoreArrowKeys) - { - handled = FALSE; - break; - } S32 len = mText.length(); if( len ) { @@ -962,7 +871,7 @@ void LLLineEditor::deleteSelection() } } -BOOL LLLineEditor::canCut() +BOOL LLLineEditor::canCut() const { return !mReadOnly && !mDrawAsterixes && hasSelection(); } @@ -996,7 +905,7 @@ void LLLineEditor::cut() } } -BOOL LLLineEditor::canCopy() +BOOL LLLineEditor::canCopy() const { return !mDrawAsterixes && hasSelection(); } @@ -1013,7 +922,7 @@ void LLLineEditor::copy() } } -BOOL LLLineEditor::canPaste() +BOOL LLLineEditor::canPaste() const { return !mReadOnly && gClipboard.canPasteString(); } @@ -1148,8 +1057,9 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) break; case KEY_LEFT: - if (!mIgnoreArrowKeys - && mask != MASK_ALT) + if (mIgnoreArrowKeys && mask == MASK_NONE) + break; + if ((mask & MASK_ALT) == 0) { if( hasSelection() ) { @@ -1174,8 +1084,9 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) break; case KEY_RIGHT: - if (!mIgnoreArrowKeys - && mask != MASK_ALT) + if (mIgnoreArrowKeys && mask == MASK_NONE) + break; + if ((mask & MASK_ALT) == 0) { if (hasSelection()) { @@ -1428,7 +1339,7 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_pare } -BOOL LLLineEditor::canDoDelete() +BOOL LLLineEditor::canDoDelete() const { return ( !mReadOnly && (!mPassDelete || (hasSelection() || (getCursor() < mText.length()))) ); } @@ -1490,7 +1401,7 @@ void LLLineEditor::draw() } // draw rectangle for the background - LLRect background( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 ); background.stretch( -mBorderThickness ); LLColor4 bg_color = mReadOnlyBgColor; @@ -1521,7 +1432,7 @@ void LLLineEditor::draw() LLColor4 text_color; if (!mReadOnly) { - if (!mTentative) + if (!getTentative()) { text_color = mFgColor; } @@ -1846,7 +1757,7 @@ BOOL LLLineEditor::prevalidateFloat(const LLWString &str) if( 0 < len ) { // May be a comma or period, depending on the locale - char decimal_point = gResMgr->getDecimalPoint(); + llwchar decimal_point = (llwchar)gResMgr->getDecimalPoint(); S32 i = 0; @@ -1895,7 +1806,7 @@ BOOL LLLineEditor::postvalidateFloat(const LLString &str) } // May be a comma or period, depending on the locale - char decimal_point = gResMgr->getDecimalPoint(); + llwchar decimal_point = (llwchar)gResMgr->getDecimalPoint(); for( ; i < len; i++ ) { @@ -2366,18 +2277,6 @@ void LLLineEditor::setColorParameters(LLXMLNodePtr node) } } -void LLLineEditor::setValue(const LLSD& value ) -{ - setText(value.asString()); -} - -LLSD LLLineEditor::getValue() const -{ - LLString str = getText(); - LLSD ret(str); - return ret; -} - BOOL LLLineEditor::setTextArg( const LLString& key, const LLStringExplicit& text ) { mText.setArg(key, text); @@ -2492,7 +2391,7 @@ BOOL LLLineEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect if (control) { LLRect control_rect_screen; - localRectToScreen(mRect, &control_rect_screen); + localRectToScreen(getRect(), &control_rect_screen); LLUI::screenRectToGL(control_rect_screen, control); } @@ -2522,21 +2421,21 @@ BOOL LLLineEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect { S32 query_local = findPixelNearestPos(query - getCursor()); S32 query_screen_x, query_screen_y; - localPointToScreen(query_local, mRect.getHeight() / 2, &query_screen_x, &query_screen_y); + localPointToScreen(query_local, getRect().getHeight() / 2, &query_screen_x, &query_screen_y); LLUI::screenPointToGL(query_screen_x, query_screen_y, &coord->mX, &coord->mY); } if (bounds) { S32 preedit_left_local = findPixelNearestPos(llmax(preedit_left_column, mScrollHPos) - getCursor()); - S32 preedit_right_local = llmin(findPixelNearestPos(preedit_right_column - getCursor()), mRect.getWidth() - mBorderThickness); + S32 preedit_right_local = llmin(findPixelNearestPos(preedit_right_column - getCursor()), getRect().getWidth() - mBorderThickness); if (preedit_left_local > preedit_right_local) { // Is this condition possible? preedit_right_local = preedit_left_local; } - LLRect preedit_rect_local(preedit_left_local, mRect.getHeight(), preedit_right_local, 0); + LLRect preedit_rect_local(preedit_left_local, getRect().getHeight(), preedit_right_local, 0); LLRect preedit_rect_screen; localRectToScreen(preedit_rect_local, &preedit_rect_screen); LLUI::screenRectToGL(preedit_rect_screen, bounds); @@ -2620,7 +2519,7 @@ LLSearchEditor::LLSearchEditor(const LLString& name, LLUICtrl(name, rect, TRUE, NULL, userdata), mSearchCallback(search_callback) { - LLRect search_edit_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect search_edit_rect(0, getRect().getHeight(), getRect().getWidth(), 0); mSearchEdit = new LLLineEditor("search edit", search_edit_rect, LLString::null, @@ -2656,55 +2555,6 @@ LLSearchEditor::LLSearchEditor(const LLString& name, mSearchEdit->setBorderWidth(0, btn_width); } -LLSearchEditor::~LLSearchEditor() -{ -} - -//virtual -EWidgetType LLSearchEditor::getWidgetType() const -{ - return WIDGET_TYPE_SEARCH_EDITOR; -} - -//virtual -LLString LLSearchEditor::getWidgetTag() const -{ - return LL_SEARCH_EDITOR_TAG; -} - -//virtual -void LLSearchEditor::setValue(const LLSD& value ) -{ - mSearchEdit->setValue(value); -} - -//virtual -LLSD LLSearchEditor::getValue() const -{ - return mSearchEdit->getValue(); -} - -//virtual -BOOL LLSearchEditor::setTextArg( const LLString& key, const LLStringExplicit& text ) -{ - return mSearchEdit->setTextArg(key, text); -} - -//virtual -BOOL LLSearchEditor::setLabelArg( const LLString& key, const LLStringExplicit& text ) -{ - return mSearchEdit->setLabelArg(key, text); -} - -//virtual -void LLSearchEditor::clear() -{ - if (mSearchEdit) - { - mSearchEdit->clear(); - } -} - void LLSearchEditor::draw() { @@ -2713,10 +2563,6 @@ void LLSearchEditor::draw() LLUICtrl::draw(); } -void LLSearchEditor::setText(const LLStringExplicit &new_text) -{ - mSearchEdit->setText(new_text); -} //static void LLSearchEditor::onSearchEdit(LLLineEditor* caller, void* user_data ) diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h index 6d328e5..ba3c697 100644 --- a/linden/indra/llui/lllineeditor.h +++ b/linden/indra/llui/lllineeditor.h @@ -1,6 +1,15 @@ /** * @file lllineeditor.h - * @brief LLLineEditor base class + * @brief Text editor widget to let users enter/edit a single line. + * + * Features: + * Text entry of a single line (text, delete, left and right arrow, insert, return). + * Callbacks either on every keystroke or just on the return key. + * Focus (allow multiple text entry widgets) + * Clipboard (cut, copy, and paste) + * Horizontal scrolling to allow strings longer than widget size allows + * Pre-validation (limit which keys can be used) + * Optional line history so previous entries can be recalled by CTRL UP/DOWN * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -29,19 +38,6 @@ * $/LicenseInfo$ */ -// Text editor widget to let users enter/edit a single line. -// -// -// Features: -// Text entry of a single line (text, delete, left and right arrow, insert, return). -// Callbacks either on every keystroke or just on the return key. -// Focus (allow multiple text entry widgets) -// Clipboard (cut, copy, and paste) -// Horizontal scrolling to allow strings longer than widget size allows -// Pre-validation (limit which keys can be used) -// Optional line history so previous entries can be recalled by CTRL UP/DOWN - - #ifndef LL_LLLINEEDITOR_H #define LL_LLLINEEDITOR_H @@ -61,13 +57,10 @@ class LLButton; typedef BOOL (*LLLinePrevalidateFunc)(const LLWString &wstr); -// -// Classes -// + class LLLineEditor : public LLUICtrl, public LLEditMenuHandler, protected LLPreeditor { - friend class LLLineEditorRollback; public: LLLineEditor(const LLString& name, @@ -85,8 +78,8 @@ public: S32 border_thickness = 1); virtual ~LLLineEditor(); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_LINE_EDITOR; } + virtual LLString getWidgetTag() const { return LL_LINE_EDITOR_TAG; }; virtual LLXMLNodePtr getXML(bool save_children = true) const; void setColorParameters(LLXMLNodePtr node); static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); @@ -102,22 +95,22 @@ public: // LLEditMenuHandler overrides virtual void cut(); - virtual BOOL canCut(); + virtual BOOL canCut() const; virtual void copy(); - virtual BOOL canCopy(); + virtual BOOL canCopy() const; virtual void paste(); - virtual BOOL canPaste(); + virtual BOOL canPaste() const; virtual void doDelete(); - virtual BOOL canDoDelete(); + virtual BOOL canDoDelete() const; virtual void selectAll(); - virtual BOOL canSelectAll(); + virtual BOOL canSelectAll() const; virtual void deselect(); - virtual BOOL canDeselect(); + virtual BOOL canDeselect() const; // view overrides virtual void draw(); @@ -133,16 +126,16 @@ public: virtual void setRect(const LLRect& rect); virtual BOOL acceptsTextInput() const; virtual void onCommit(); - virtual BOOL isDirty() const; // Returns TRUE if the user has changed value at all - virtual void resetDirty(); // Clear dirty state + virtual BOOL isDirty() const { return mText.getString() != mPrevText; } // Returns TRUE if user changed value at all + virtual void resetDirty() { mPrevText = mText.getString(); } // Clear dirty state // assumes UTF8 text - virtual void setValue(const LLSD& value ); - virtual LLSD getValue() const; + virtual void setValue(const LLSD& value ) { setText(value.asString()); } + virtual LLSD getValue() const { return LLSD(getText()); } virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ); virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); - void setLabel(const LLStringExplicit &new_label); + void setLabel(const LLStringExplicit &new_label) { mLabel = new_label; } void setText(const LLStringExplicit &new_text); const LLString& getText() const { return mText.getString(); } @@ -179,7 +172,6 @@ public: void setIgnoreArrowKeys(BOOL b) { mIgnoreArrowKeys = b; } void setIgnoreTab(BOOL b) { mIgnoreTab = b; } void setPassDelete(BOOL b) { mPassDelete = b; } - void setDrawAsterixes(BOOL b); // get the cursor position of the beginning/end of the prev/next word in the text @@ -216,23 +208,24 @@ public: static BOOL postvalidateFloat(const LLString &str); // line history support: - void setEnableLineHistory( BOOL enabled ); // switches line history on or off + void setEnableLineHistory( BOOL enabled ) { mHaveHistory = enabled; } // switches line history on or off void updateHistory(); // stores current line in history -protected: +private: + // private helper classes void removeChar(); void addChar(const llwchar c); void setCursorAtLocalPos(S32 local_mouse_x); - S32 findPixelNearestPos(S32 cursor_offset = 0) const; void reportBadKeystroke(); - BOOL handleSpecialKey(KEY key, MASK mask); BOOL handleSelectionKey(KEY key, MASK mask); BOOL handleControlKey(KEY key, MASK mask); S32 handleCommitKey(KEY key, MASK mask); -protected: + // + // private data members + // void updateAllowingLanguageInput(); BOOL hasPreeditString() const; // Implementation (overrides) of LLPreeditor @@ -308,13 +301,53 @@ protected: LLWString mPreeditOverwrittenWString; std::vector mPreeditPositions; LLPreeditor::standouts_t mPreeditStandouts; -}; - + // private helper class + class LLLineEditorRollback + { + public: + LLLineEditorRollback( LLLineEditor* ed ) + : + mCursorPos( ed->mCursorPos ), + mScrollHPos( ed->mScrollHPos ), + mIsSelecting( ed->mIsSelecting ), + mSelectionStart( ed->mSelectionStart ), + mSelectionEnd( ed->mSelectionEnd ) + { + mText = ed->getText(); + } + + void doRollback( LLLineEditor* ed ) + { + ed->mCursorPos = mCursorPos; + ed->mScrollHPos = mScrollHPos; + ed->mIsSelecting = mIsSelecting; + ed->mSelectionStart = mSelectionStart; + ed->mSelectionEnd = mSelectionEnd; + ed->mText = mText; + ed->mPrevText = mText; + } + + LLString getText() { return mText; } + + private: + LLString mText; + S32 mCursorPos; + S32 mScrollHPos; + BOOL mIsSelecting; + S32 mSelectionStart; + S32 mSelectionEnd; + }; // end class LLLineEditorRollback + +}; // end class LLLineEditor + + + +/* + * @brief A line editor with a button to clear it and a callback to call on every edit event. + */ class LLSearchEditor : public LLUICtrl { -friend class LLLineEditorRollback; - public: LLSearchEditor(const LLString& name, const LLRect& rect, @@ -322,34 +355,34 @@ public: void (*search_callback)(const LLString& search_string, void* user_data), void* userdata); - virtual ~LLSearchEditor(); + virtual ~LLSearchEditor() {} /*virtual*/ void draw(); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SEARCH_EDITOR; } + virtual LLString getWidgetTag() const { return LL_SEARCH_EDITOR_TAG; } static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - void setText(const LLStringExplicit &new_text); + void setText(const LLStringExplicit &new_text) { mSearchEdit->setText(new_text); } void setSearchCallback(void (*search_callback)(const LLString& search_string, void* user_data), void* data) { mSearchCallback = search_callback; mCallbackUserData = data; } // LLUICtrl interface - virtual void setValue(const LLSD& value ); - virtual LLSD getValue() const; - virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ); - virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); - virtual void clear(); + virtual void setValue(const LLSD& value ) { mSearchEdit->setValue(value); } + virtual LLSD getValue() const { return mSearchEdit->getValue(); } + virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ) { return mSearchEdit->setTextArg( key, text); } + virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ) { return mSearchEdit->setLabelArg(key, text); } + virtual void clear() { if (mSearchEdit) mSearchEdit->clear(); } -protected: - LLLineEditor* mSearchEdit; - LLButton* mClearSearchButton; +private: + static void onSearchEdit(LLLineEditor* caller, void* user_data ); + static void onClearSearch(void* user_data); + LLLineEditor* mSearchEdit; + class LLButton* mClearSearchButton; void (*mSearchCallback)(const LLString& search_string, void* user_data); - static void onSearchEdit(LLLineEditor* caller, void* user_data ); - static void onClearSearch(void* user_data); }; #endif // LL_LINEEDITOR_ diff --git a/linden/indra/llui/llmemberlistener.h b/linden/indra/llui/llmemberlistener.h index 02aff17..6f4ba8b 100644 --- a/linden/indra/llui/llmemberlistener.h +++ b/linden/indra/llui/llmemberlistener.h @@ -2,6 +2,32 @@ * @file llmemberlistener.h * @brief Listener class which registers itself with its parent view * + * + * Example usage: + * + * (in header) + * + * class T { + * class LLDoTest : public LLMemberListener + * { + * bool handleEvent(LLPointer event, const LLSD& userdata); + * }; + * LLDoTest mDoTest; + * } + * + * (in cpp) + * + * T::T() { + * mDoTest.registerListener(this, "T.Test"); + * } + * + * T::LLDoTest::handleEvent(LLPointer event, const LLSD& userdata) + * { + * T *self = mPtr; + * ... + * } + * + * * $LicenseInfo:firstyear=2006&license=viewergpl$ * * Copyright (c) 2006-2008, Linden Research, Inc. @@ -34,7 +60,6 @@ #include "llevent.h" -// T *mPtr is the object that this listener manipulates template class LLMemberListener : public LLSimpleListener { @@ -51,32 +76,10 @@ public: // This is what you have to override to handle this event virtual bool handleEvent(LLPointer event, const LLSD& userdata) = 0; - T *mPtr; +protected: + T *mPtr; // The object that this listener manipulates LLString mRegisteredName; }; -// Example usage: - -// (in header) - -// class T { -// class LLDoTest : public LLMemberListener -// { -// bool handleEvent(LLPointer event, const LLSD& userdata); -// }; -// LLDoTest mDoTest; -// } - -// (in cpp) - -// T::T() { -// mDoTest.registerListener(this, "T.Test"); -// } -// -// T::LLDoTest::handleEvent(LLPointer event, const LLSD& userdata) -// { -// T *self = mPtr; -// ... -// } #endif // LL_LLMEMBERLISTENER_H diff --git a/linden/indra/llui/llmenugl.cpp b/linden/indra/llui/llmenugl.cpp index a56b090..4a12870 100644 --- a/linden/indra/llui/llmenugl.cpp +++ b/linden/indra/llui/llmenugl.cpp @@ -47,6 +47,7 @@ #include "llmath.h" #include "llgl.h" +#include "llglimmediate.h" #include "llfocusmgr.h" #include "llfont.h" #include "llcoord.h" @@ -112,12 +113,11 @@ LLColor4 LLMenuItemGL::sEnabledColor( 0.0f, 0.0f, 0.0f, 1.0f ); LLColor4 LLMenuItemGL::sDisabledColor( 0.5f, 0.5f, 0.5f, 1.0f ); LLColor4 LLMenuItemGL::sHighlightBackground( 0.0f, 0.0f, 0.7f, 1.0f ); LLColor4 LLMenuItemGL::sHighlightForeground( 1.0f, 1.0f, 1.0f, 1.0f ); -BOOL LLMenuItemGL::sDropShadowText = TRUE; LLColor4 LLMenuGL::sDefaultBackgroundColor( 0.25f, 0.25f, 0.25f, 0.75f ); BOOL LLMenuGL::sKeyboardMode = FALSE; -LLViewHandle LLMenuHolderGL::sItemLastSelectedHandle; +LLHandle LLMenuHolderGL::sItemLastSelectedHandle; LLFrameTimer LLMenuHolderGL::sItemActivationTimer; //LLColor4 LLMenuGL::sBackgroundColor( 0.8f, 0.8f, 0.0f, 1.0f ); @@ -199,7 +199,7 @@ BOOL LLMenuItemGL::handleKey(KEY key, MASK mask, BOOL called_from_parent) if( called_from_parent ) { // Downward traversal - if (mEnabled) + if (getEnabled()) { handled = childrenHandleKey( key, mask ) != NULL; } @@ -215,7 +215,7 @@ BOOL LLMenuItemGL::handleKey(KEY key, MASK mask, BOOL called_from_parent) BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask) { - if( mEnabled && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) + if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) { doIt(); return TRUE; @@ -225,15 +225,10 @@ BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask) BOOL LLMenuItemGL::handleHover(S32 x, S32 y, MASK mask) { - mGotHover = TRUE; + setHover(TRUE); getWindow()->setCursor(UI_CURSOR_ARROW); return TRUE; } - -void LLMenuItemGL::setBriefItem(BOOL b) -{ - mBriefItem = b; -} // This function checks to see if the accelerator key is already in use; // if not, it will be added to the list @@ -282,7 +277,7 @@ BOOL LLMenuItemGL::addToAcceleratorList(std::list *listp) // This function appends the character string representation of // the current accelerator key and mask to the provided string. -void LLMenuItemGL::appendAcceleratorString( LLString& st ) +void LLMenuItemGL::appendAcceleratorString( LLString& st ) const { // break early if this is a silly thing to do. if( KEY_NONE == mAcceleratorKey ) @@ -332,52 +327,14 @@ void LLMenuItemGL::setJumpKey(KEY key) mJumpKey = LLStringOps::toUpper((char)key); } -KEY LLMenuItemGL::getJumpKey() -{ - return mJumpKey; -} - - -// set the font used by all of the menu objects -void LLMenuItemGL::setFont(LLFontGL* font) -{ - mFont = font; -} - -// returns the height in pixels for the current font. -U32 LLMenuItemGL::getNominalHeight( void ) -{ - return llround(mFont->getLineHeight()) + MENU_ITEM_PADDING; -} - -// functions to control the color scheme -void LLMenuItemGL::setEnabledColor( const LLColor4& color ) -{ - sEnabledColor = color; -} - -void LLMenuItemGL::setDisabledColor( const LLColor4& color ) -{ - sDisabledColor = color; -} - -void LLMenuItemGL::setHighlightBGColor( const LLColor4& color ) -{ - sHighlightBackground = color; -} -void LLMenuItemGL::setHighlightFGColor( const LLColor4& color ) -{ - sHighlightForeground = color; +// virtual +U32 LLMenuItemGL::getNominalHeight( void ) const +{ + return llround(mFont->getLineHeight()) + MENU_ITEM_PADDING; } -// change the label -void LLMenuItemGL::setLabel( const LLStringExplicit& label ) -{ - mLabel = label; -} - // Get the parent menu for this item LLMenuGL* LLMenuItemGL::getMenu() { @@ -388,7 +345,7 @@ LLMenuGL* LLMenuItemGL::getMenu() // getNominalWidth() - returns the normal width of this control in // pixels - this is used for calculating the widest item, as well as // for horizontal arrangement. -U32 LLMenuItemGL::getNominalWidth( void ) +U32 LLMenuItemGL::getNominalWidth( void ) const { U32 width; @@ -442,17 +399,6 @@ void LLMenuItemGL::doIt( void ) mHighlight = highlight; } -// determine if this object represents an active sub-menu -BOOL LLMenuItemGL::isActive( void ) const -{ - return FALSE; -} - -// determine if this object represents an open sub-menu -BOOL LLMenuItemGL::isOpen( void ) const -{ - return FALSE; -} BOOL LLMenuItemGL::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) { @@ -490,7 +436,7 @@ BOOL LLMenuItemGL::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) BOOL LLMenuItemGL::handleMouseUp( S32 x, S32 y, MASK ) { - if (mEnabled) + if (getEnabled()) { // switch to mouse navigation mode LLMenuGL::setKeyboardMode(FALSE); @@ -504,7 +450,7 @@ BOOL LLMenuItemGL::handleMouseUp( S32 x, S32 y, MASK ) BOOL LLMenuItemGL::handleMouseDown( S32 x, S32 y, MASK ) { - if (mEnabled) + if (getEnabled()) { // switch to mouse navigation mode LLMenuGL::setKeyboardMode(FALSE); @@ -512,10 +458,7 @@ BOOL LLMenuItemGL::handleMouseDown( S32 x, S32 y, MASK ) setHighlight(TRUE); return TRUE; } - else - { - return FALSE; - } + return FALSE; } @@ -528,14 +471,14 @@ void LLMenuItemGL::draw( void ) // let disabled items be highlighted, just don't draw them as such if( getEnabled() && getHighlight() && !mBriefItem) { - glColor4fv( sHighlightBackground.mV ); - gl_rect_2d( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + gGL.color4fv( sHighlightBackground.mV ); + gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 ); } LLColor4 color; U8 font_style = mStyle; - if (LLMenuItemGL::sDropShadowText && getEnabled() && !mDrawTextDisabled ) + if (getEnabled() && !mDrawTextDisabled ) { font_style |= LLFontGL::DROP_SHADOW_SOFT; } @@ -570,12 +513,12 @@ void LLMenuItemGL::draw( void ) LLFontGL::LEFT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL, FALSE ); if( !mDrawAccelLabel.empty() ) { - mFont->render( mDrawAccelLabel.getWString(), 0, (F32)mRect.mRight - (F32)RIGHT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color, + mFont->render( mDrawAccelLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color, LLFontGL::RIGHT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL, FALSE ); } if( !mDrawBranchLabel.empty() ) { - mFont->render( mDrawBranchLabel.getWString(), 0, (F32)mRect.mRight - (F32)RIGHT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color, + mFont->render( mDrawBranchLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color, LLFontGL::RIGHT, LLFontGL::BOTTOM, font_style, S32_MAX, S32_MAX, NULL, FALSE ); } } @@ -595,7 +538,7 @@ void LLMenuItemGL::draw( void ) } // clear got hover every frame - mGotHover = FALSE; + setHover(FALSE); } BOOL LLMenuItemGL::setLabelArg( const LLString& key, const LLStringExplicit& text ) @@ -628,7 +571,7 @@ public: virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); - virtual U32 getNominalHeight( void ) { return SEPARATOR_HEIGHT_PIXELS; } + virtual U32 getNominalHeight( void ) const { return SEPARATOR_HEIGHT_PIXELS; } }; LLMenuItemSeparatorGL::LLMenuItemSeparatorGL( const LLString &name ) : @@ -638,42 +581,42 @@ LLMenuItemSeparatorGL::LLMenuItemSeparatorGL( const LLString &name ) : void LLMenuItemSeparatorGL::draw( void ) { - glColor4fv( sDisabledColor.mV ); - const S32 y = mRect.getHeight() / 2; + gGL.color4fv( getDisabledColor().mV ); + const S32 y = getRect().getHeight() / 2; const S32 PAD = 6; - gl_line_2d( PAD, y, mRect.getWidth() - PAD, y ); + gl_line_2d( PAD, y, getRect().getWidth() - PAD, y ); } BOOL LLMenuItemSeparatorGL::handleMouseDown(S32 x, S32 y, MASK mask) { LLMenuGL* parent_menu = getMenu(); - if (y > mRect.getHeight() / 2) + if (y > getRect().getHeight() / 2) { - return parent_menu->handleMouseDown(x + mRect.mLeft, mRect.mTop + 1, mask); + return parent_menu->handleMouseDown(x + getRect().mLeft, getRect().mTop + 1, mask); } else { - return parent_menu->handleMouseDown(x + mRect.mLeft, mRect.mBottom - 1, mask); + return parent_menu->handleMouseDown(x + getRect().mLeft, getRect().mBottom - 1, mask); } } BOOL LLMenuItemSeparatorGL::handleMouseUp(S32 x, S32 y, MASK mask) { LLMenuGL* parent_menu = getMenu(); - if (y > mRect.getHeight() / 2) + if (y > getRect().getHeight() / 2) { - return parent_menu->handleMouseUp(x + mRect.mLeft, mRect.mTop + 1, mask); + return parent_menu->handleMouseUp(x + getRect().mLeft, getRect().mTop + 1, mask); } else { - return parent_menu->handleMouseUp(x + mRect.mLeft, mRect.mBottom - 1, mask); + return parent_menu->handleMouseUp(x + getRect().mLeft, getRect().mBottom - 1, mask); } } BOOL LLMenuItemSeparatorGL::handleHover(S32 x, S32 y, MASK mask) { LLMenuGL* parent_menu = getMenu(); - if (y > mRect.getHeight() / 2) + if (y > getRect().getHeight() / 2) { parent_menu->highlightPrevItem(this, FALSE); return FALSE; @@ -711,24 +654,13 @@ LLMenuItemVerticalSeparatorGL::LLMenuItemVerticalSeparatorGL( void ) //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuItemTearOffGL -// -// This class represents a separator. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LLMenuItemTearOffGL::LLMenuItemTearOffGL(LLViewHandle parent_floater_handle) : +LLMenuItemTearOffGL::LLMenuItemTearOffGL(LLHandle parent_floater_handle) : LLMenuItemGL("tear off", TEAROFF_SEPARATOR_LABEL), mParentHandle(parent_floater_handle) { } -EWidgetType LLMenuItemTearOffGL::getWidgetType() const -{ - return WIDGET_TYPE_TEAROFF_MENU; -} - -LLString LLMenuItemTearOffGL::getWidgetTag() const -{ - return LL_MENU_ITEM_TEAR_OFF_GL_TAG; -} void LLMenuItemTearOffGL::doIt() { @@ -747,7 +679,7 @@ void LLMenuItemTearOffGL::doIt() getMenu()->arrange(); - LLFloater* parent_floater = LLFloater::getFloaterByHandle(mParentHandle); + LLFloater* parent_floater = mParentHandle.get(); LLFloater* tear_off_menu = LLTearOffMenu::create(getMenu()); if (tear_off_menu) @@ -768,27 +700,31 @@ void LLMenuItemTearOffGL::doIt() void LLMenuItemTearOffGL::draw() { // disabled items can be highlighted, but shouldn't render as such - if( getEnabled() && getHighlight() && !mBriefItem) + if( getEnabled() && getHighlight() && !isBriefItem()) { - glColor4fv( sHighlightBackground.mV ); - gl_rect_2d( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + gGL.color4fv( getHighlightBGColor().mV ); + gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 ); } - if (mEnabled) + if (getEnabled()) { - glColor4fv( sEnabledColor.mV ); + gGL.color4fv( getEnabledColor().mV ); } else { - glColor4fv( sDisabledColor.mV ); + gGL.color4fv( getDisabledColor().mV ); } - const S32 y = mRect.getHeight() / 3; + const S32 y = getRect().getHeight() / 3; const S32 PAD = 6; - gl_line_2d( PAD, y, mRect.getWidth() - PAD, y ); - gl_line_2d( PAD, y * 2, mRect.getWidth() - PAD, y * 2 ); + gl_line_2d( PAD, y, getRect().getWidth() - PAD, y ); + gl_line_2d( PAD, y * 2, getRect().getWidth() - PAD, y * 2 ); +} + +U32 LLMenuItemTearOffGL::getNominalHeight( void ) const +{ + return TEAROFF_SEPARATOR_HEIGHT_PIXELS; } -U32 LLMenuItemTearOffGL::getNominalHeight( void ) { return TEAROFF_SEPARATOR_HEIGHT_PIXELS; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuItemBlankGL @@ -799,22 +735,16 @@ U32 LLMenuItemTearOffGL::getNominalHeight( void ) { return TEAROFF_SEPARATOR_HEI class LLMenuItemBlankGL : public LLMenuItemGL { public: - LLMenuItemBlankGL( void ); - + LLMenuItemBlankGL( void ) : LLMenuItemGL( "", "" ) + { + setEnabled(FALSE); + } virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_BLANK; } virtual LLString getWidgetTag() const { return LL_MENU_ITEM_BLANK_GL_TAG; } - - // doIt() - do the primary funcationality of the menu item. virtual void doIt( void ) {} - virtual void draw( void ) {} }; -LLMenuItemBlankGL::LLMenuItemBlankGL( void ) -: LLMenuItemGL( "", "" ) -{ - mEnabled = FALSE; -} ///============================================================================ /// Class LLMenuItemCallGL @@ -905,7 +835,7 @@ void LLMenuItemCallGL::setEnabledControl(LLString enabled_control, LLView *conte } else { - context->addBoolControl(enabled_control, mEnabled); + context->addBoolControl(enabled_control, getEnabled()); control = context->findControl(enabled_control); control->registerListener(this, "ENABLED"); } @@ -925,7 +855,7 @@ void LLMenuItemCallGL::setVisibleControl(LLString enabled_control, LLView *conte } else { - context->addBoolControl(enabled_control, mEnabled); + context->addBoolControl(enabled_control, getEnabled()); control = context->findControl(enabled_control); control->registerListener(this, "VISIBLE"); } @@ -989,16 +919,6 @@ void LLMenuItemCallGL::doIt( void ) LLMenuItemGL::doIt(); } -EWidgetType LLMenuItemCallGL::getWidgetType() const -{ - return WIDGET_TYPE_MENU_ITEM_CALL; -} - -LLString LLMenuItemCallGL::getWidgetTag() const -{ - return LL_MENU_ITEM_CALL_GL_TAG; -} - void LLMenuItemCallGL::buildDrawLabel( void ) { LLPointer fired_event = new LLEvent(this); @@ -1018,7 +938,7 @@ void LLMenuItemCallGL::buildDrawLabel( void ) BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask ) { - if( (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) + if( (!gKeyboard->getKeyRepeated(key) || getAllowKeyRepeat()) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) ) { LLPointer fired_event = new LLEvent(this); fireEvent(fired_event, "on_build"); @@ -1026,7 +946,7 @@ BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask ) { setEnabled( mEnabledCallback( mUserData ) ); } - if( !mEnabled ) + if( !getEnabled() ) { if( mOnDisabledCallback ) { @@ -1127,20 +1047,10 @@ LLXMLNodePtr LLMenuItemCheckGL::getXML(bool save_children) const return node; } -EWidgetType LLMenuItemCheckGL::getWidgetType() const -{ - return WIDGET_TYPE_MENU_ITEM_CHECK; -} - -LLString LLMenuItemCheckGL::getWidgetTag() const -{ - return LL_MENU_ITEM_CHECK_GL_TAG; -} - // called to rebuild the draw label void LLMenuItemCheckGL::buildDrawLabel( void ) { - if(mChecked || (mCheckCallback && mCheckCallback( mUserData ) ) ) + if(mChecked || (mCheckCallback && mCheckCallback( getUserData() ) ) ) { mDrawBoolLabel = BOOLEAN_TRUE_PREFIX; } @@ -1216,23 +1126,13 @@ LLView* LLMenuItemBranchGL::getChildByName(const LLString& name, BOOL recurse) c return mBranch; } // Always recurse on branches - return mBranch->getChildByName(name, recurse); -} - -EWidgetType LLMenuItemBranchGL::getWidgetType() const -{ - return WIDGET_TYPE_MENU_ITEM_BRANCH; -} - -LLString LLMenuItemBranchGL::getWidgetTag() const -{ - return LL_MENU_ITEM_BRANCH_GL_TAG; + return mBranch->getChild(name, recurse); } // virtual BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask) { - if (mEnabled) + if (getEnabled()) { // switch to mouse navigation mode LLMenuGL::setKeyboardMode(FALSE); @@ -1335,18 +1235,11 @@ BOOL LLMenuItemBranchGL::handleUnicodeChar(llwchar uni_char, BOOL called_from_pa } -// set the hover status (called by it's menu) void LLMenuItemBranchGL::setHighlight( BOOL highlight ) { if (highlight == getHighlight()) return; - // make sure only yourself is highlighted - if (highlight) - { - getMenu()->clearHoverItem(); - } - - BOOL auto_open = mEnabled && (!mBranch->getVisible() || mBranch->getTornOff()); + BOOL auto_open = getEnabled() && (!mBranch->getVisible() || mBranch->getTornOff()); // torn off menus don't open sub menus on hover unless they have focus if (getMenu()->getTornOff() && !((LLFloater*)getMenu()->getParent())->hasFocus()) { @@ -1357,8 +1250,7 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight ) { auto_open = FALSE; } - - mHighlight = highlight; + LLMenuItemGL::setHighlight(highlight); if( highlight ) { if(auto_open) @@ -1380,11 +1272,6 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight ) } } -void LLMenuItemBranchGL::setEnabledSubMenus(BOOL enabled) -{ - mBranch->setEnabledSubMenus(enabled); -} - void LLMenuItemBranchGL::draw() { LLMenuItemGL::draw(); @@ -1394,18 +1281,6 @@ void LLMenuItemBranchGL::draw() } } -// determine if this object is active -// which, for branching menus, means the branch is open and has "focus" -BOOL LLMenuItemBranchGL::isActive( void ) const -{ - return isOpen() && mBranch->getHighlightedItem(); -} - -BOOL LLMenuItemBranchGL::isOpen( void ) const -{ - return mBranch->isOpen(); -} - void LLMenuItemBranchGL::updateBranchParent(LLView* parentp) { if (mBranch->getParent() == NULL) @@ -1478,8 +1353,8 @@ void LLMenuItemBranchGL::openMenu() LLRect rect = mBranch->getRect(); // calculate root-view relative position for branch menu - S32 left = mRect.mRight; - S32 top = mRect.mTop - mRect.mBottom; + S32 left = getRect().mRight; + S32 top = getRect().mTop - getRect().mBottom; localPointToOtherView(left, top, &left, &top, mBranch->getParent()); @@ -1505,7 +1380,7 @@ void LLMenuItemBranchGL::openMenu() if( x - menu_region_rect.mLeft > menu_region_width - rect.getWidth() ) { // move sub-menu over to left side - delta_x = llmax(-x, (-1 * (rect.getWidth() + mRect.getWidth()))); + delta_x = llmax(-x, (-1 * (rect.getWidth() + getRect().getWidth()))); } mBranch->translate( delta_x, delta_y ); mBranch->setVisible( TRUE ); @@ -1536,7 +1411,7 @@ public: // returns the normal width of this control in pixels - this is // used for calculating the widest item, as well as for horizontal // arrangement. - virtual U32 getNominalWidth( void ); + virtual U32 getNominalWidth( void ) const; // called to rebuild the draw label virtual void buildDrawLabel( void ); @@ -1570,10 +1445,10 @@ LLMenuItemBranchDownGL::LLMenuItemBranchDownGL( const LLString& name, // returns the normal width of this control in pixels - this is used // for calculating the widest item, as well as for horizontal // arrangement. -U32 LLMenuItemBranchDownGL::getNominalWidth( void ) +U32 LLMenuItemBranchDownGL::getNominalWidth( void ) const { U32 width = LEFT_PAD_PIXELS + LEFT_WIDTH_PIXELS + RIGHT_PAD_PIXELS; - width += mFont->getWidth( mLabel.getWString().c_str() ); + width += getFont()->getWidth( mLabel.getWString().c_str() ); return width; } @@ -1588,32 +1463,33 @@ void LLMenuItemBranchDownGL::buildDrawLabel( void ) void LLMenuItemBranchDownGL::openMenu( void ) { - if( mBranch->getVisible() && !mBranch->getTornOff() ) + LLMenuGL* branch = getBranch(); + if( branch->getVisible() && !branch->getTornOff() ) { - mBranch->setVisible( FALSE ); + branch->setVisible( FALSE ); } else { - if (mBranch->getTornOff()) + if (branch->getTornOff()) { - gFloaterView->bringToFront((LLFloater*)mBranch->getParent()); + gFloaterView->bringToFront((LLFloater*)branch->getParent()); } else { // We're showing the drop-down menu, so patch up its labels/rects - mBranch->arrange(); + branch->arrange(); - LLRect rect = mBranch->getRect(); + LLRect rect = branch->getRect(); S32 left = 0; - S32 top = mRect.mBottom; - localPointToOtherView(left, top, &left, &top, mBranch->getParent()); + S32 top = getRect().mBottom; + localPointToOtherView(left, top, &left, &top, branch->getParent()); rect.setLeftTopAndSize( left, top, rect.getWidth(), rect.getHeight() ); - mBranch->setRect( rect ); + branch->setRect( rect ); S32 x = 0; S32 y = 0; - mBranch->localPointToScreen( 0, 0, &x, &y ); + branch->localPointToScreen( 0, 0, &x, &y ); S32 delta_x = 0; LLCoordScreen window_size; @@ -1625,13 +1501,11 @@ void LLMenuItemBranchDownGL::openMenu( void ) { delta_x = (window_width - rect.getWidth()) - x; } - mBranch->translate( delta_x, 0 ); + branch->translate( delta_x, 0 ); setHighlight(TRUE); - mBranch->setVisible( TRUE ); + branch->setVisible( TRUE ); } - - } } @@ -1640,21 +1514,18 @@ void LLMenuItemBranchDownGL::setHighlight( BOOL highlight ) { if (highlight == getHighlight()) return; - if (highlight) - { - getMenu()->clearHoverItem(); - } - mHighlight = highlight; + //NOTE: Purposely calling all the way to the base to bypass auto-open. + LLMenuItemGL::setHighlight(highlight); if( !highlight) { - if (mBranch->getTornOff()) + if (getBranch()->getTornOff()) { - ((LLFloater*)mBranch->getParent())->setFocus(FALSE); - mBranch->clearHoverItem(); + ((LLFloater*)getBranch()->getParent())->setFocus(FALSE); + getBranch()->clearHoverItem(); } else { - mBranch->setVisible( FALSE ); + getBranch()->setVisible( FALSE ); } } } @@ -1684,8 +1555,8 @@ BOOL LLMenuItemBranchDownGL::handleMouseUp( S32 x, S32 y, MASK mask ) BOOL LLMenuItemBranchDownGL::handleAcceleratorKey(KEY key, MASK mask) { - BOOL branch_visible = mBranch->getVisible(); - BOOL handled = mBranch->handleAcceleratorKey(key, mask); + BOOL branch_visible = getBranch()->getVisible(); + BOOL handled = getBranch()->handleAcceleratorKey(key, mask); if (handled && !branch_visible && getVisible()) { // flash this menu entry because we triggered an invisible menu item @@ -1697,7 +1568,7 @@ BOOL LLMenuItemBranchDownGL::handleAcceleratorKey(KEY key, MASK mask) BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) { - BOOL menu_open = mBranch->getVisible(); + BOOL menu_open = getBranch()->getVisible(); // don't do keyboard navigation of top-level menus unless in keyboard mode, or menu expanded if (getHighlight() && getMenu()->getVisible() && (isActive() || LLMenuGL::getKeyboardMode())) { @@ -1738,7 +1609,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_ { doIt(); } - mBranch->highlightNextItem(NULL); + getBranch()->highlightNextItem(NULL); return TRUE; } else if (key == KEY_UP) @@ -1750,7 +1621,7 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_ { doIt(); } - mBranch->highlightPrevItem(NULL); + getBranch()->highlightPrevItem(NULL); return TRUE; } } @@ -1761,19 +1632,19 @@ BOOL LLMenuItemBranchDownGL::handleKeyHere(KEY key, MASK mask, BOOL called_from_ void LLMenuItemBranchDownGL::draw( void ) { //FIXME: try removing this - if (mBranch->getVisible() && !mBranch->getTornOff()) + if (getBranch()->getVisible() && !getBranch()->getTornOff()) { setHighlight(TRUE); } if( getHighlight() ) { - glColor4fv( sHighlightBackground.mV ); - gl_rect_2d( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + gGL.color4fv( getHighlightBGColor().mV ); + gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 ); } - U8 font_style = mStyle; - if (LLMenuItemGL::sDropShadowText && getEnabled() && !mDrawTextDisabled ) + U8 font_style = getFontStyle(); + if (getEnabled() && !getDrawTextDisabled() ) { font_style |= LLFontGL::DROP_SHADOW_SOFT; } @@ -1781,17 +1652,17 @@ void LLMenuItemBranchDownGL::draw( void ) LLColor4 color; if (getHighlight()) { - color = sHighlightForeground; + color = getHighlightFGColor(); } - else if( mEnabled ) + else if( getEnabled() ) { - color = sEnabledColor; + color = getEnabledColor(); } else { - color = sDisabledColor; + color = getDisabledColor(); } - mFont->render( mLabel.getWString(), 0, (F32)mRect.getWidth() / 2.f, (F32)LABEL_BOTTOM_PAD_PIXELS, color, + getFont()->render( mLabel.getWString(), 0, (F32)getRect().getWidth() / 2.f, (F32)LABEL_BOTTOM_PAD_PIXELS, color, LLFontGL::HCENTER, LLFontGL::BOTTOM, font_style ); @@ -1800,19 +1671,19 @@ void LLMenuItemBranchDownGL::draw( void ) { LLString upper_case_label = mLabel.getString(); LLString::toUpper(upper_case_label); - std::string::size_type offset = upper_case_label.find(mJumpKey); + std::string::size_type offset = upper_case_label.find(getJumpKey()); if (offset != std::string::npos) { - S32 x_offset = llround((F32)mRect.getWidth() / 2.f - mFont->getWidthF32(mLabel.getString(), 0, S32_MAX) / 2.f); - S32 x_begin = x_offset + mFont->getWidth(mLabel, 0, offset); - S32 x_end = x_offset + mFont->getWidth(mLabel, 0, offset + 1); + S32 x_offset = llround((F32)getRect().getWidth() / 2.f - getFont()->getWidthF32(mLabel.getString(), 0, S32_MAX) / 2.f); + S32 x_begin = x_offset + getFont()->getWidth(mLabel, 0, offset); + S32 x_end = x_offset + getFont()->getWidth(mLabel, 0, offset + 1); gl_line_2d(x_begin, LABEL_BOTTOM_PAD_PIXELS, x_end, LABEL_BOTTOM_PAD_PIXELS); } } // reset every frame so that we only show highlight // when we get hover events on that frame - mGotHover = FALSE; + setHover(FALSE); } ///============================================================================ @@ -1820,7 +1691,7 @@ void LLMenuItemBranchDownGL::draw( void ) ///============================================================================ // Default constructor -LLMenuGL::LLMenuGL( const LLString& name, const LLString& label, LLViewHandle parent_floater_handle ) +LLMenuGL::LLMenuGL( const LLString& name, const LLString& label, LLHandle parent_floater_handle ) : LLUICtrl( name, LLRect(), FALSE, NULL, NULL ), mBackgroundColor( sDefaultBackgroundColor ), mBgVisible( TRUE ), @@ -1845,7 +1716,7 @@ LLMenuGL::LLMenuGL( const LLString& name, const LLString& label, LLViewHandle pa setTabStop(FALSE); } -LLMenuGL::LLMenuGL( const LLString& label, LLViewHandle parent_floater_handle ) +LLMenuGL::LLMenuGL( const LLString& label, LLHandle parent_floater_handle ) : LLUICtrl( label, LLRect(), FALSE, NULL, NULL ), mBackgroundColor( sDefaultBackgroundColor ), mBgVisible( TRUE ), @@ -1879,7 +1750,7 @@ LLMenuGL::~LLMenuGL( void ) mJumpKeys.clear(); } -void LLMenuGL::setCanTearOff(BOOL tear_off, LLViewHandle parent_floater_handle ) +void LLMenuGL::setCanTearOff(BOOL tear_off, LLHandle parent_floater_handle ) { if (tear_off && mTearOffItem == NULL) { @@ -2317,29 +2188,13 @@ LLView* LLMenuGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa return menu; } -// control the color scheme -void LLMenuGL::setDefaultBackgroundColor( const LLColor4& color ) -{ - sDefaultBackgroundColor = color; -} - -void LLMenuGL::setBackgroundColor( const LLColor4& color ) -{ - mBackgroundColor = color; -} - -LLColor4 LLMenuGL::getBackgroundColor() -{ - return mBackgroundColor; -} - // rearrange the child rects so they fit the shape of the menu. void LLMenuGL::arrange( void ) { // calculate the height & width, and set our rect based on that // information. - LLRect initial_rect = mRect; + const LLRect& initial_rect = getRect(); U32 width = 0, height = MENU_ITEM_PADDING; @@ -2349,8 +2204,9 @@ void LLMenuGL::arrange( void ) { const LLRect menu_region_rect = LLMenuGL::sMenuContainer ? LLMenuGL::sMenuContainer->getMenuRect() : LLRect(0, S32_MAX, S32_MAX, 0); - U32 max_width = menu_region_rect.getWidth(); - U32 max_height = menu_region_rect.getHeight(); + // torn off menus are not constrained to the size of the screen + U32 max_width = getTornOff() ? U32_MAX : menu_region_rect.getWidth(); + U32 max_height = getTornOff() ? U32_MAX : menu_region_rect.getHeight(); // *FIX: create the item first and then ask for its dimensions? S32 spillover_item_width = PLAIN_PAD_PIXELS + LLFontGL::sSansSerif->getWidth( "More" ); S32 spillover_item_height = llround(LLFontGL::sSansSerif->getLineHeight()) + MENU_ITEM_PADDING; @@ -2429,8 +2285,7 @@ void LLMenuGL::arrange( void ) } } - mRect.mRight = mRect.mLeft + width; - mRect.mTop = mRect.mBottom + height; + setRect(LLRect(getRect().mLeft, getRect().mBottom + height, getRect().mLeft + width, getRect().mBottom)); S32 cur_height = (S32)llmin(max_height, height); S32 cur_width = 0; @@ -2622,8 +2477,7 @@ void LLMenuGL::empty( void ) // Adjust rectangle of the menu void LLMenuGL::setLeftAndBottom(S32 left, S32 bottom) { - mRect.mLeft = left; - mRect.mBottom = bottom; + setRect(LLRect(left, getRect().mTop, getRect().mRight, bottom)); arrange(); } @@ -2953,7 +2807,7 @@ BOOL LLMenuGL::handleKey( KEY key, MASK mask, BOOL called_from_parent ) BOOL handled = FALSE; // Pass down even if not visible - if( mEnabled && called_from_parent ) + if( getEnabled() && called_from_parent ) { for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) { @@ -2981,7 +2835,7 @@ BOOL LLMenuGL::handleKey( KEY key, MASK mask, BOOL called_from_parent ) BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask) { // don't handle if not enabled - if(!mEnabled) + if(!getEnabled()) { return FALSE; } @@ -3080,7 +2934,7 @@ void LLMenuGL::draw( void ) { if (mDropShadowed && !mTornOff) { - gl_drop_shadow(0, mRect.getHeight(), mRect.getWidth(), 0, + gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, LLUI::sColorsGroup->getColor("ColorDropShadow"), LLUI::sConfigGroup->getS32("DropShadowFloater") ); } @@ -3089,14 +2943,14 @@ void LLMenuGL::draw( void ) if( mBgVisible ) { - gl_rect_2d( 0, mRect.getHeight(), mRect.getWidth(), 0, mBackgroundColor ); + gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0, mBackgroundColor ); } LLView::draw(); } void LLMenuGL::drawBackground(LLMenuItemGL* itemp, LLColor4& color) { - glColor4fv( color.mV ); + gGL.color4fv( color.mV ); LLRect item_rect = itemp->getRect(); gl_rect_2d( 0, item_rect.getHeight(), item_rect.getWidth(), 0); } @@ -3139,7 +2993,7 @@ LLMenuGL* LLMenuGL::getChildMenuByName(const LLString& name, BOOL recurse) const return (LLMenuGL*)view; } } - llwarns << "Child Menu " << name << " not found in menu " << mName << llendl; + llwarns << "Child Menu " << name << " not found in menu " << getName() << llendl; return NULL; } @@ -3254,7 +3108,7 @@ void LLPieMenuBranch::buildDrawLabel( void ) if(mEnabledCallback) { setEnabled(mEnabledCallback(mUserData)); - mDrawTextDisabled = FALSE; + setDrawTextDisabled(FALSE); } else { @@ -3273,7 +3127,7 @@ void LLPieMenuBranch::buildDrawLabel( void ) break; } } - mDrawTextDisabled = !any_enabled; + setDrawTextDisabled(!any_enabled); setEnabled(TRUE); } @@ -3334,20 +3188,6 @@ LLPieMenu::LLPieMenu(const LLString& name) setCanTearOff(FALSE); } -// virtual -LLPieMenu::~LLPieMenu() -{ } - - -EWidgetType LLPieMenu::getWidgetType() const -{ - return WIDGET_TYPE_PIE_MENU; -} - -LLString LLPieMenu::getWidgetTag() const -{ - return LL_PIE_MENU_TAG; -} void LLPieMenu::initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory) { @@ -3621,8 +3461,8 @@ void LLPieMenu::draw() mHoverItem = NULL; } - F32 width = (F32) mRect.getWidth(); - F32 height = (F32) mRect.getHeight(); + F32 width = (F32) getRect().getWidth(); + F32 height = (F32) getRect().getHeight(); mCurRadius = PIE_SCALE_FACTOR * llmax( width/2, height/2 ); mOuterRingAlpha = mUseInfiniteRadius ? 0.f : 1.f; @@ -3637,9 +3477,9 @@ void LLPieMenu::draw() F32 center_y = height/2; S32 steps = 100; - glPushMatrix(); + gGL.pushMatrix(); { - glTranslatef(center_x, center_y, 0.f); + gGL.translatef(center_x, center_y, 0.f); F32 line_width = LLUI::sConfigGroup->getF32("PieMenuLineWidth"); LLColor4 line_color = LLUI::sColorsGroup->getColor("PieMenuLineColor"); @@ -3678,16 +3518,16 @@ void LLPieMenu::draw() gl_washer_spokes_2d( mCurRadius, (F32)PIE_CENTER_SIZE, 8, line_color, outer_color ); // inner circle - glColor4fv( line_color.mV ); + gGL.color4fv( line_color.mV ); gl_circle_2d( 0, 0, (F32)PIE_CENTER_SIZE, steps, FALSE ); // outer circle - glColor4fv( outer_color.mV ); + gGL.color4fv( outer_color.mV ); gl_circle_2d( 0, 0, mCurRadius, steps, FALSE ); LLUI::setLineWidth(1.0f); } - glPopMatrix(); + gGL.popMatrix(); mHoverThisFrame = FALSE; @@ -3696,16 +3536,16 @@ void LLPieMenu::draw() void LLPieMenu::drawBackground(LLMenuItemGL* itemp, LLColor4& color) { - F32 width = (F32) mRect.getWidth(); - F32 height = (F32) mRect.getHeight(); + F32 width = (F32) getRect().getWidth(); + F32 height = (F32) getRect().getHeight(); F32 center_x = width/2; F32 center_y = height/2; S32 steps = 100; - glColor4fv( color.mV ); - glPushMatrix(); + gGL.color4fv( color.mV ); + gGL.pushMatrix(); { - glTranslatef(center_x - itemp->getRect().mLeft, center_y - itemp->getRect().mBottom, 0.f); + gGL.translatef(center_x - itemp->getRect().mLeft, center_y - itemp->getRect().mBottom, 0.f); item_list_t::iterator item_iter; S32 i = 0; @@ -3725,7 +3565,7 @@ void LLPieMenu::drawBackground(LLMenuItemGL* itemp, LLColor4& color) i++; } } - glPopMatrix(); + gGL.popMatrix(); } // virtual @@ -3790,7 +3630,8 @@ void LLPieMenu::arrange() // TODO: Compute actual bounding rect for menu - mRect.setOriginAndSize(mRect.mLeft, mRect.mBottom, rect_width, rect_height ); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast(getRect()).setOriginAndSize(getRect().mLeft, getRect().mBottom, rect_width, rect_height ); // place items around a circle, with item 0 at positive X, // rotating counter-clockwise @@ -3827,8 +3668,8 @@ LLMenuItemGL *LLPieMenu::pieItemFromXY(S32 x, S32 y) // An arc of the pie menu is 45 degrees const F32 ARC_DEG = 45.f; - S32 delta_x = x - mRect.getWidth() / 2; - S32 delta_y = y - mRect.getHeight() / 2; + S32 delta_x = x - getRect().getWidth() / 2; + S32 delta_y = y - getRect().getHeight() / 2; // circle safe zone in the center S32 dist_squared = delta_x*delta_x + delta_y*delta_y; @@ -3838,7 +3679,7 @@ LLMenuItemGL *LLPieMenu::pieItemFromXY(S32 x, S32 y) } // infinite radius is only used with right clicks - S32 radius = llmax( mRect.getWidth()/2, mRect.getHeight()/2 ); + S32 radius = llmax( getRect().getWidth()/2, getRect().getHeight()/2 ); if (!(mUseInfiniteRadius && mRightMouseDown) && dist_squared > radius * radius) { return NULL; @@ -3876,8 +3717,8 @@ S32 LLPieMenu::pieItemIndexFromXY(S32 x, S32 y) // An arc of the pie menu is 45 degrees const F32 ARC_DEG = 45.f; // correct for non-square pixels - S32 delta_x = x - mRect.getWidth() / 2; - S32 delta_y = y - mRect.getHeight() / 2; + S32 delta_x = x - getRect().getWidth() / 2; + S32 delta_y = y - getRect().getHeight() / 2; // circle safe zone in the center if (delta_x*delta_x + delta_y*delta_y < PIE_CENTER_SIZE*PIE_CENTER_SIZE) @@ -3900,8 +3741,8 @@ S32 LLPieMenu::pieItemIndexFromXY(S32 x, S32 y) void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) { - S32 width = mRect.getWidth(); - S32 height = mRect.getHeight(); + S32 width = getRect().getWidth(); + S32 height = getRect().getHeight(); const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect(); @@ -3911,40 +3752,45 @@ void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) S32 local_x, local_y; parent_view->screenPointToLocal(x, y, &local_x, &local_y); - mRect.setCenterAndSize(local_x, local_y, width, height); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast(getRect()).setCenterAndSize(local_x, local_y, width, height); arrange(); // Adjust the pie rectangle to keep it on screen - if (mRect.mLeft < menu_region_rect.mLeft) + if (getRect().mLeft < menu_region_rect.mLeft) { - //mShiftHoriz = menu_region_rect.mLeft - mRect.mLeft; - //mRect.translate( mShiftHoriz, 0 ); - mRect.translate( menu_region_rect.mLeft - mRect.mLeft, 0 ); + //mShiftHoriz = menu_region_rect.mLeft - getRect().mLeft; + //getRect().translate( mShiftHoriz, 0 ); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast(getRect()).translate( menu_region_rect.mLeft - getRect().mLeft, 0 ); moved = TRUE; } - if (mRect.mRight > menu_region_rect.mRight) + if (getRect().mRight > menu_region_rect.mRight) { - //mShiftHoriz = menu_region_rect.mRight - mRect.mRight; - //mRect.translate( mShiftHoriz, 0); - mRect.translate( menu_region_rect.mRight - mRect.mRight, 0 ); + //mShiftHoriz = menu_region_rect.mRight - getRect().mRight; + //getRect().translate( mShiftHoriz, 0); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast(getRect()).translate( menu_region_rect.mRight - getRect().mRight, 0 ); moved = TRUE; } - if (mRect.mBottom < menu_region_rect.mBottom) + if (getRect().mBottom < menu_region_rect.mBottom) { - //mShiftVert = menu_region_rect.mBottom - mRect.mBottom; - //mRect.translate( 0, mShiftVert ); - mRect.translate( 0, menu_region_rect.mBottom - mRect.mBottom ); + //mShiftVert = menu_region_rect.mBottom - getRect().mBottom; + //getRect().translate( 0, mShiftVert ); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast(getRect()).translate( 0, menu_region_rect.mBottom - getRect().mBottom ); moved = TRUE; } - if (mRect.mTop > menu_region_rect.mTop) + if (getRect().mTop > menu_region_rect.mTop) { - //mShiftVert = menu_region_rect.mTop - mRect.mTop; - //mRect.translate( 0, mShiftVert ); - mRect.translate( 0, menu_region_rect.mTop - mRect.mTop ); + //mShiftVert = menu_region_rect.mTop - getRect().mTop; + //getRect().translate( 0, mShiftVert ); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast(getRect()).translate( 0, menu_region_rect.mTop - getRect().mTop ); moved = TRUE; } @@ -3953,8 +3799,8 @@ void LLPieMenu::show(S32 x, S32 y, BOOL mouse_down) if (moved) { LLCoordGL center; - center.mX = (mRect.mLeft + mRect.mRight) / 2; - center.mY = (mRect.mTop + mRect.mBottom) / 2; + center.mX = (getRect().mLeft + getRect().mRight) / 2; + center.mY = (getRect().mTop + getRect().mBottom) / 2; LLUI::setCursorPositionLocal(getParent(), center.mX, center.mY); } @@ -4066,7 +3912,7 @@ LLView* LLMenuBarGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory LLMenuBarGL *menubar = new LLMenuBarGL(name); - LLViewHandle parent_handle = LLViewHandle::sDeadHandle; + LLHandle parent_handle; if (parent->getWidgetType() == WIDGET_TYPE_FLOATER) { parent_handle = ((LLFloater*)parent)->getHandle(); @@ -4246,7 +4092,7 @@ BOOL LLMenuBarGL::jumpKeysActive() void LLMenuBarGL::arrange( void ) { U32 pos = 0; - LLRect rect( 0, mRect.getHeight(), 0, 0 ); + LLRect rect( 0, getRect().getHeight(), 0, 0 ); item_list_t::const_iterator item_iter; for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) { @@ -4398,25 +4244,12 @@ LLMenuHolderGL::LLMenuHolderGL(const LLString& name, const LLRect& rect, BOOL mo mCanHide = TRUE; } -LLMenuHolderGL::~LLMenuHolderGL() -{ -} - -EWidgetType LLMenuHolderGL::getWidgetType() const -{ - return WIDGET_TYPE_MENU_HOLDER; -} - -LLString LLMenuHolderGL::getWidgetTag() const -{ - return LL_MENU_HOLDER_GL_TAG; -} void LLMenuHolderGL::draw() { LLView::draw(); // now draw last selected item as overlay - LLMenuItemGL* selecteditem = (LLMenuItemGL*)LLView::getViewByHandle(sItemLastSelectedHandle); + LLMenuItemGL* selecteditem = (LLMenuItemGL*)sItemLastSelectedHandle.get(); if (selecteditem && sItemActivationTimer.getStarted() && sItemActivationTimer.getElapsedTimeF32() < ACTIVATE_HIGHLIGHT_TIME) { // make sure toggle items, for example, show the proper state when fading out @@ -4426,10 +4259,10 @@ void LLMenuHolderGL::draw() selecteditem->localRectToOtherView(selecteditem->getLocalRect(), &item_rect, this); F32 interpolant = sItemActivationTimer.getElapsedTimeF32() / ACTIVATE_HIGHLIGHT_TIME; - F32 alpha = lerp(LLMenuItemGL::sHighlightBackground.mV[VALPHA], 0.f, interpolant); - LLColor4 bg_color(LLMenuItemGL::sHighlightBackground.mV[VRED], - LLMenuItemGL::sHighlightBackground.mV[VGREEN], - LLMenuItemGL::sHighlightBackground.mV[VBLUE], + F32 alpha = lerp(LLMenuItemGL::getHighlightBGColor().mV[VALPHA], 0.f, interpolant); + LLColor4 bg_color(LLMenuItemGL::getHighlightBGColor().mV[VRED], + LLMenuItemGL::getHighlightBGColor().mV[VGREEN], + LLMenuItemGL::getHighlightBGColor().mV[VBLUE], alpha); LLUI::pushMatrix(); @@ -4466,7 +4299,7 @@ BOOL LLMenuHolderGL::handleRightMouseDown( S32 x, S32 y, MASK mask ) void LLMenuHolderGL::reshape(S32 width, S32 height, BOOL called_from_parent) { - if (width != mRect.getWidth() || height != mRect.getHeight()) + if (width != getRect().getWidth() || height != getRect().getHeight()) { hideMenus(); } @@ -4486,10 +4319,6 @@ BOOL LLMenuHolderGL::hasVisibleMenu() const return FALSE; } -const LLRect LLMenuHolderGL::getMenuRect() const -{ - return getLocalRect(); -} BOOL LLMenuHolderGL::hideMenus() { @@ -4522,7 +4351,7 @@ BOOL LLMenuHolderGL::hideMenus() void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item) { - sItemLastSelectedHandle = item->mViewHandle; + sItemLastSelectedHandle = item->getHandle(); sItemActivationTimer.start(); } @@ -4532,20 +4361,24 @@ void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item) LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : LLFloater(menup->getName(), LLRect(0, 100, 100, 0), menup->getLabel(), FALSE, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, FALSE, FALSE) { + // flag menu as being torn off + menup->setTornOff(TRUE); + // update menu layout as torn off menu (no spillover menus) + menup->arrange(); + LLRect rect; menup->localRectToOtherView(LLRect(-1, menup->getRect().getHeight(), menup->getRect().getWidth() + 3, 0), &rect, gFloaterView); + // make sure this floater is big enough for menu mTargetHeight = (F32)(rect.getHeight() + LLFLOATER_HEADER_SIZE + 5); reshape(rect.getWidth(), rect.getHeight()); setRect(rect); - mOldParent = menup->getParent(); - mOldParent->removeChild(menup); + // attach menu to floater menup->setFollowsAll(); + mOldParent = menup->getParent(); addChild(menup); menup->setVisible(TRUE); menup->translate(-menup->getRect().mLeft + 1, -menup->getRect().mBottom + 1); - - menup->setTornOff(TRUE); menup->setDropShadowed(FALSE); mMenu = menup; @@ -4554,19 +4387,16 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : mMenu->highlightNextItem(NULL); } -LLTearOffMenu::~LLTearOffMenu() -{ -} void LLTearOffMenu::draw() { - mMenu->setBackgroundVisible(mBgOpaque); + mMenu->setBackgroundVisible(isBackgroundOpaque()); mMenu->arrange(); - if (mRect.getHeight() != mTargetHeight) + if (getRect().getHeight() != mTargetHeight) { // animate towards target height - reshape(mRect.getWidth(), llceil(lerp((F32)mRect.getHeight(), mTargetHeight, LLCriticalDamp::getInterpolant(0.05f)))); + reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLCriticalDamp::getInterpolant(0.05f)))); } else { @@ -4667,23 +4497,3 @@ void LLTearOffMenu::onClose(bool app_quitting) destroy(); } -///============================================================================ -/// Class LLEditMenuHandlerMgr -///============================================================================ -LLEditMenuHandlerMgr& LLEditMenuHandlerMgr::getInstance() -{ - static LLEditMenuHandlerMgr instance; - return instance; -} - -LLEditMenuHandlerMgr::LLEditMenuHandlerMgr() -{ -} - -LLEditMenuHandlerMgr::~LLEditMenuHandlerMgr() -{ -} - -///============================================================================ -/// Local function definitions -///============================================================================ diff --git a/linden/indra/llui/llmenugl.h b/linden/indra/llui/llmenugl.h index 9274101..4e5ac69 100644 --- a/linden/indra/llui/llmenugl.h +++ b/linden/indra/llui/llmenugl.h @@ -44,8 +44,6 @@ #include "lluistring.h" #include "llview.h" -class LLMenuItemGL; -class LLMenuHolderGL; extern S32 MENU_BAR_HEIGHT; extern S32 MENU_BAR_WIDTH; @@ -77,13 +75,19 @@ typedef void (*label_callback)(LLString&,void*); // The LLMenuItemGL represents a single menu item in a menu. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLFontGL; -class LLMenuGL; - - class LLMenuItemGL : public LLView { public: + // static functions to control the global color scheme. + static void setEnabledColor( const LLColor4& color ) { sEnabledColor = color; } + static const LLColor4& getEnabledColor() { return sEnabledColor; } + static void setDisabledColor( const LLColor4& color ) { sDisabledColor = color; } + static const LLColor4& getDisabledColor() { return sDisabledColor; } + static void setHighlightBGColor( const LLColor4& color ) { sHighlightBackground = color; } + static const LLColor4& getHighlightBGColor() { return sHighlightBackground; } + static void setHighlightFGColor( const LLColor4& color ) { sHighlightForeground = color; } + static const LLColor4& getHighlightFGColor() { return sHighlightForeground; } + LLMenuItemGL( const LLString& name, const LLString& label, KEY key = KEY_NONE, MASK = MASK_NONE ); virtual void setValue(const LLSD& value) { setLabel(value.asString()); } @@ -99,44 +103,38 @@ public: virtual BOOL handleAcceleratorKey(KEY key, MASK mask); - BOOL getHighlight() const { return mHighlight; } - void setJumpKey(KEY key); - KEY getJumpKey(); + KEY getJumpKey() const { return mJumpKey; } // set the font used by this item. - void setFont(LLFontGL* font); + void setFont(const LLFontGL* font) { mFont = font; } + const LLFontGL* getFont() const { return mFont; } void setFontStyle(U8 style) { mStyle = style; } + U8 getFontStyle() const { return mStyle; } // returns the height in pixels for the current font. - virtual U32 getNominalHeight( void ); - - // functions to control the color scheme - static void setEnabledColor( const LLColor4& color ); - static void setDisabledColor( const LLColor4& color ); - static void setHighlightBGColor( const LLColor4& color ); - static void setHighlightFGColor( const LLColor4& color ); + virtual U32 getNominalHeight( void ) const; // Marks item as not needing space for check marks or accelerator keys - virtual void setBriefItem(BOOL brief); + virtual void setBriefItem(BOOL brief) { mBriefItem = brief; } + virtual BOOL isBriefItem() const { return mBriefItem; } virtual BOOL addToAcceleratorList(std::list *listp); void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; } - - // return the name label - LLString getLabel( void ) const { return mLabel.getString(); } + BOOL getAllowKeyRepeat() const { return mAllowKeyRepeat; } // change the label - void setLabel( const LLStringExplicit& label ); + void setLabel( const LLStringExplicit& label ) { mLabel = label; } + LLString getLabel( void ) const { return mLabel.getString(); } virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); // Get the parent menu for this item - virtual LLMenuGL* getMenu(); + virtual class LLMenuGL* getMenu(); // returns the normal width of this control in pixels - this is // used for calculating the widest item, as well as for horizontal // arrangement. - virtual U32 getNominalWidth( void ); + virtual U32 getNominalWidth( void ) const; // buildDrawLabel() - constructs the string used during the draw() // function. This reduces the overall string manipulation, but can @@ -155,14 +153,14 @@ public: // doIt() - do the primary funcationality of the menu item. virtual void doIt( void ); - // set the hover status (called by it's menu) virtual void setHighlight( BOOL highlight ); + virtual BOOL getHighlight() const { return mHighlight; } // determine if this represents an active sub-menu - virtual BOOL isActive( void ) const; + virtual BOOL isActive( void ) const { return FALSE; } // determine if this represents an open sub-menu - virtual BOOL isOpen( void ) const; + virtual BOOL isOpen( void ) const { return FALSE; } virtual void setEnabledSubMenus(BOOL enable){}; @@ -172,24 +170,20 @@ public: virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask ); virtual void draw( void ); - BOOL getHover() { return mGotHover; } + BOOL getHover() const { return mGotHover; } + void setDrawTextDisabled(BOOL disabled) { mDrawTextDisabled = disabled; } BOOL getDrawTextDisabled() const { return mDrawTextDisabled; } protected: + void setHover(BOOL hover) { mGotHover = hover; } + // This function appends the character string representation of // the current accelerator key and mask to the provided string. - void appendAcceleratorString( LLString& st ); - -public: - static LLColor4 sEnabledColor; - static LLColor4 sDisabledColor; - static LLColor4 sHighlightBackground; - static LLColor4 sHighlightForeground; - -protected: - static BOOL sDropShadowText; + void appendAcceleratorString( LLString& st ) const; + KEY mAcceleratorKey; + MASK mAcceleratorMask; // mLabel contains the actual label specified by the user. LLUIString mLabel; @@ -200,12 +194,15 @@ protected: LLUIString mDrawAccelLabel; LLUIString mDrawBranchLabel; + BOOL mHighlight; +private: + static LLColor4 sEnabledColor; + static LLColor4 sDisabledColor; + static LLColor4 sHighlightBackground; + static LLColor4 sHighlightForeground; + // Keyboard and mouse variables - KEY mJumpKey; - KEY mAcceleratorKey; - MASK mAcceleratorMask; BOOL mAllowKeyRepeat; - BOOL mHighlight; BOOL mGotHover; // If true, suppress normal space for check marks on the left and accelerator @@ -213,10 +210,11 @@ protected: BOOL mBriefItem; // Font for this item - LLFontGL* mFont; - + const LLFontGL* mFont; U8 mStyle; BOOL mDrawTextDisabled; + + KEY mJumpKey; }; @@ -229,14 +227,6 @@ protected: class LLMenuItemCallGL : public LLMenuItemGL { -protected: - menu_callback mCallback; - // mEnabledCallback should return TRUE if the item should be enabled - enabled_callback mEnabledCallback; - label_callback mLabelCallback; - void* mUserData; - on_disabled_callback mOnDisabledCallback; - public: // normal constructor LLMenuItemCallGL( const LLString& name, @@ -277,8 +267,8 @@ public: virtual LLString getType() const { return "call"; } - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_CALL; } + virtual LLString getWidgetTag() const { return LL_MENU_ITEM_CALL_GL_TAG; } void setEnabledControl(LLString enabled_control, LLView *context); void setVisibleControl(LLString enabled_control, LLView *context); @@ -302,6 +292,14 @@ public: //virtual void draw(); virtual bool handleEvent(LLPointer event, const LLSD& userdata); + +private: + menu_callback mCallback; + // mEnabledCallback should return TRUE if the item should be enabled + enabled_callback mEnabledCallback; + label_callback mLabelCallback; + void* mUserData; + on_disabled_callback mOnDisabledCallback; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -310,17 +308,13 @@ public: // The LLMenuItemCheckGL is an extension of the LLMenuItemCallGL // class, by allowing another method to be specified which determines // if the menu item should consider itself checked as true or not. Be -// careful that the check callback provided - it needs to be VERY +// careful that the provided callback is fast - it needs to be VERY // FUCKING EFFICIENT, because it may need to be checked a lot. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLMenuItemCheckGL : public LLMenuItemCallGL { -protected: - check_callback mCheckCallback; - BOOL mChecked; - public: LLMenuItemCheckGL( const LLString& name, const LLString& label, @@ -348,8 +342,8 @@ public: void setCheckedControl(LLString checked_control, LLView *context); virtual void setValue(const LLSD& value) { mChecked = value.asBoolean(); } - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_CHECK; } + virtual LLString getWidgetTag() const { return LL_MENU_ITEM_CHECK_GL_TAG; } virtual LLString getType() const { return "check"; } @@ -358,8 +352,9 @@ public: virtual bool handleEvent(LLPointer event, const LLSD& userdata); - // LLView Functionality - //virtual void draw( void ); +private: + check_callback mCheckCallback; + BOOL mChecked; }; @@ -372,9 +367,6 @@ public: class LLMenuItemToggleGL : public LLMenuItemGL { -protected: - BOOL* mToggle; - public: LLMenuItemToggleGL( const LLString& name, const LLString& label, BOOL* toggle, @@ -394,6 +386,9 @@ public: // LLView Functionality //virtual void draw( void ); + +private: + BOOL* mToggle; }; @@ -408,16 +403,14 @@ public: // it in the appendMenu() method. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLMenuArrowGL; -class LLMenuItemBranchGL; -class LLMenuItemTearOffGL; - class LLMenuGL : public LLUICtrl +// TODO: The menu and menu item classes share a great deal of functionality and perhaps should be united. +// I think it may make the most sense to make LLMenuGL be a subclass of LLMenuItemGL. -MG { public: - LLMenuGL( const LLString& name, const LLString& label, LLViewHandle parent_floater = LLViewHandle::sDeadHandle ); - LLMenuGL( const LLString& label, LLViewHandle parent_floater = LLViewHandle::sDeadHandle ); + LLMenuGL( const LLString& name, const LLString& label, LLHandle parent_floater = LLHandle()); + LLMenuGL( const LLString& label, LLHandle parent_floater = LLHandle() ); virtual ~LLMenuGL( void ); virtual LLXMLNodePtr getXML(bool save_children = true) const; static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); @@ -446,11 +439,12 @@ public: const LLString& getLabel( void ) const { return mLabel.getString(); } void setLabel(const LLStringExplicit& label) { mLabel = label; } - static void setDefaultBackgroundColor( const LLColor4& color ); - void setBackgroundColor( const LLColor4& color ); - LLColor4 getBackgroundColor(); + // background colors + static void setDefaultBackgroundColor( const LLColor4& color ) { sDefaultBackgroundColor = color; } + void setBackgroundColor( const LLColor4& color ) { mBackgroundColor = color; } + const LLColor4& getBackgroundColor() const { return mBackgroundColor; } void setBackgroundVisible( BOOL b ) { mBgVisible = b; } - void setCanTearOff(BOOL tear_off, LLViewHandle parent_floater_handle = LLViewHandle::sDeadHandle); + void setCanTearOff(BOOL tear_off, LLHandle parent_floater_handle = LLHandle()); // Add the menu item to this menu. virtual BOOL append( LLMenuItemGL* item ); @@ -524,7 +518,7 @@ public: BOOL getCanTearOff() { return mTearOffItem != NULL; } - KEY getJumpKey() { return mJumpKey; } + KEY getJumpKey() const { return mJumpKey; } void setJumpKey(KEY key) { mJumpKey = key; } static void setKeyboardMode(BOOL mode) { sKeyboardMode = mode; } @@ -532,40 +526,42 @@ public: static void onFocusLost(LLView* old_focus); - static LLMenuHolderGL* sMenuContainer; + static class LLMenuHolderGL* sMenuContainer; protected: void createSpilloverBranch(); void cleanupSpilloverBranch(); -protected: + // TODO: create accessor methods for these? + typedef std::list< LLMenuItemGL* > item_list_t; + item_list_t mItems; + typedef std::map navigation_key_map_t; + navigation_key_map_t mJumpKeys; + S32 mLastMouseX; + S32 mLastMouseY; + S32 mMouseVelX; + S32 mMouseVelY; + BOOL mHorizontalLayout; + BOOL mKeepFixedSize; + +private: static LLColor4 sDefaultBackgroundColor; static BOOL sKeyboardMode; LLColor4 mBackgroundColor; BOOL mBgVisible; - typedef std::list< LLMenuItemGL* > item_list_t; - item_list_t mItems; - typedef std::map navigation_key_map_t; - navigation_key_map_t mJumpKeys; LLMenuItemGL* mParentMenuItem; LLUIString mLabel; BOOL mDropShadowed; // Whether to drop shadow - BOOL mHorizontalLayout; - BOOL mKeepFixedSize; BOOL mHasSelection; LLFrameTimer mFadeTimer; - S32 mLastMouseX; - S32 mLastMouseY; - S32 mMouseVelX; - S32 mMouseVelY; BOOL mTornOff; - LLMenuItemTearOffGL* mTearOffItem; - LLMenuItemBranchGL* mSpilloverBranch; + class LLMenuItemTearOffGL* mTearOffItem; + class LLMenuItemBranchGL* mSpilloverBranch; LLMenuGL* mSpilloverMenu; - LLViewHandle mParentFloaterHandle; + LLHandle mParentFloaterHandle; KEY mJumpKey; -}; +}; // end class LLMenuGL @@ -578,20 +574,15 @@ protected: class LLMenuItemBranchGL : public LLMenuItemGL { -protected: - LLMenuGL* mBranch; - public: LLMenuItemBranchGL( const LLString& name, const LLString& label, LLMenuGL* branch, KEY key = KEY_NONE, MASK mask = MASK_NONE ); virtual LLXMLNodePtr getXML(bool save_children = true) const; - virtual LLView* getChildByName(const LLString& name, BOOL recurse) const; - - virtual LLString getType() const { return "menu"; } + virtual LLString getType() const { return "menu"; } - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_ITEM_BRANCH; } + virtual LLString getWidgetTag() const { return LL_MENU_ITEM_BRANCH_GL_TAG; } virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); @@ -615,9 +606,9 @@ public: virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); - virtual BOOL isActive() const; + virtual BOOL isActive() const { return isOpen() && mBranch->getHighlightedItem(); } - virtual BOOL isOpen() const; + virtual BOOL isOpen() const { return mBranch->isOpen(); } LLMenuGL *getBranch() const { return mBranch; } @@ -628,11 +619,16 @@ public: virtual void draw(); - virtual void setEnabledSubMenus(BOOL enabled); + virtual void setEnabledSubMenus(BOOL enabled) { mBranch->setEnabledSubMenus(enabled); } virtual void openMenu(); -}; +protected: + virtual LLView* getChildByName(const LLString& name, BOOL recurse) const; + +private: + LLMenuGL* mBranch; +}; // end class LLMenuItemBranchGL @@ -647,10 +643,10 @@ class LLPieMenu public: LLPieMenu(const LLString& name, const LLString& label); LLPieMenu(const LLString& name); - virtual ~LLPieMenu(); + virtual ~LLPieMenu() {} - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_PIE_MENU; } + virtual LLString getWidgetTag() const { return LL_PIE_MENU_TAG; } void initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory); @@ -682,11 +678,10 @@ public: void show(S32 x, S32 y, BOOL mouse_down); void hide(BOOL item_selected); -protected: +private: LLMenuItemGL *pieItemFromXY(S32 x, S32 y); S32 pieItemIndexFromXY(S32 x, S32 y); -private: // These cause menu items to be spuriously selected by right-clicks // near the window edge at low frame rates. I don't think they are // needed unless you shift the menu position in the draw() function. JC @@ -703,6 +698,7 @@ private: BOOL mRightMouseDown; }; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuBarGL // @@ -711,10 +707,6 @@ private: class LLMenuBarGL : public LLMenuGL { -protected: - std::list mAccelerators; - BOOL mAltKeyTrigger; - public: LLMenuBarGL( const LLString& name ); virtual ~LLMenuBarGL(); @@ -748,9 +740,11 @@ public: void resetMenuTrigger() { mAltKeyTrigger = FALSE; } -protected: +private: void checkMenuTrigger(); + std::list mAccelerators; + BOOL mAltKeyTrigger; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -763,10 +757,10 @@ class LLMenuHolderGL : public LLPanel public: LLMenuHolderGL(); LLMenuHolderGL(const LLString& name, const LLRect& rect, BOOL mouse_opaque, U32 follows = FOLLOWS_NONE); - virtual ~LLMenuHolderGL(); + virtual ~LLMenuHolderGL() {} - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MENU_HOLDER; } + virtual LLString getWidgetTag() const { return LL_MENU_HOLDER_GL_TAG; } virtual BOOL hideMenus(); void reshape(S32 width, S32 height, BOOL called_from_parent); @@ -777,13 +771,13 @@ public: virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); - virtual const LLRect getMenuRect() const; + virtual const LLRect getMenuRect() const { return getLocalRect(); } virtual BOOL hasVisibleMenu() const; static void setActivatedItem(LLMenuItemGL* item); -protected: - static LLViewHandle sItemLastSelectedHandle; +private: + static LLHandle sItemLastSelectedHandle; static LLFrameTimer sItemActivationTimer; BOOL mCanHide; @@ -793,12 +787,13 @@ protected: // Class LLTearOffMenu // // Floater that hosts a menu +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLTearOffMenu&oldid=81344 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTearOffMenu : public LLFloater { public: static LLTearOffMenu* create(LLMenuGL* menup); - virtual ~LLTearOffMenu(); + virtual ~LLTearOffMenu() {} virtual void onClose(bool app_quitting); virtual void draw(void); virtual void onFocusReceived(); @@ -807,10 +802,9 @@ public: virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); virtual void translate(S32 x, S32 y); -protected: +private: LLTearOffMenu(LLMenuGL* menup); -protected: LLView* mOldParent; LLMenuGL* mMenu; F32 mTargetHeight; @@ -825,19 +819,19 @@ protected: class LLMenuItemTearOffGL : public LLMenuItemGL { public: - LLMenuItemTearOffGL( LLViewHandle parent_floater_handle = (LLViewHandle)LLViewHandle::sDeadHandle ); + LLMenuItemTearOffGL( LLHandle parent_floater_handle = LLHandle()); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TEAROFF_MENU; } + virtual LLString getWidgetTag() const { return LL_MENU_ITEM_TEAR_OFF_GL_TAG; } - virtual LLString getType() const { return "tearoff_menu"; } + virtual LLString getType() const { return "tearoff_menu"; } virtual void doIt(void); virtual void draw(void); - virtual U32 getNominalHeight(); + virtual U32 getNominalHeight() const; -protected: - LLViewHandle mParentHandle; +private: + LLHandle mParentHandle; }; @@ -845,11 +839,13 @@ protected: class LLEditMenuHandlerMgr { public: - LLEditMenuHandlerMgr& getInstance(); - virtual ~LLEditMenuHandlerMgr(); -protected: - LLEditMenuHandlerMgr(); - + LLEditMenuHandlerMgr& getInstance() { + static LLEditMenuHandlerMgr instance; + return instance; + } + virtual ~LLEditMenuHandlerMgr() {} +private: + LLEditMenuHandlerMgr() {}; }; #endif // LL_LLMENUGL_H diff --git a/linden/indra/llui/llmodaldialog.cpp b/linden/indra/llui/llmodaldialog.cpp index ff4858f..392c122 100644 --- a/linden/indra/llui/llmodaldialog.cpp +++ b/linden/indra/llui/llmodaldialog.cpp @@ -74,10 +74,10 @@ LLModalDialog::~LLModalDialog() void LLModalDialog::open() /* Flawfinder: ignore */ { // SJB: Hack! Make sure we don't ever host a modal dialog - LLMultiFloater* thost = LLFloater::sHostp; - LLFloater::sHostp = NULL; + LLMultiFloater* thost = LLFloater::getFloaterHost(); + LLFloater::setFloaterHost(NULL); LLFloater::open(); - LLFloater::sHostp = thost; + LLFloater::setFloaterHost(thost); } void LLModalDialog::reshape(S32 width, S32 height, BOOL called_from_parent) @@ -157,14 +157,18 @@ void LLModalDialog::setVisible( BOOL visible ) BOOL LLModalDialog::handleMouseDown(S32 x, S32 y, MASK mask) { - if (!LLFloater::handleMouseDown(x, y, mask)) + if (mModal) { - if (mModal) + if (!LLFloater::handleMouseDown(x, y, mask)) { // Click was outside the panel make_ui_sound("UISndInvalidOp"); } } + else + { + LLFloater::handleMouseDown(x, y, mask); + } return TRUE; } @@ -247,7 +251,7 @@ void LLModalDialog::draw() LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow"); S32 shadow_lines = LLUI::sConfigGroup->getS32("DropShadowFloater"); - gl_drop_shadow( 0, mRect.getHeight(), mRect.getWidth(), 0, + gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0, shadow_color, shadow_lines); LLFloater::draw(); @@ -276,11 +280,7 @@ void LLModalDialog::draw() void LLModalDialog::centerOnScreen() { LLVector2 window_size = LLUI::getWindowSize(); - - S32 dialog_left = (llround(window_size.mV[VX]) - mRect.getWidth()) / 2; - S32 dialog_bottom = (llround(window_size.mV[VY]) - mRect.getHeight()) / 2; - - translate( dialog_left - mRect.mLeft, dialog_bottom - mRect.mBottom ); + centerWithin(LLRect(0, 0, llround(window_size.mV[VX]), llround(window_size.mV[VY]))); } @@ -319,3 +319,4 @@ void LLModalDialog::onAppFocusGained() } + diff --git a/linden/indra/llui/llmodaldialog.h b/linden/indra/llui/llmodaldialog.h index 342a0f6..dd82b25 100644 --- a/linden/indra/llui/llmodaldialog.h +++ b/linden/indra/llui/llmodaldialog.h @@ -40,7 +40,7 @@ class LLModalDialog; // By default, a ModalDialog is modal, i.e. no other window can have focus // However, for the sake of code reuse and simplicity, if mModal == false, // the dialog behaves like a normal floater - +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLModalDialog&oldid=81385 class LLModalDialog : public LLFloater { public: @@ -67,6 +67,8 @@ public: /*virtual*/ void setVisible(BOOL visible); /*virtual*/ void draw(); + BOOL isModal() const { return mModal; } + static void onAppFocusLost(); static void onAppFocusGained(); @@ -75,9 +77,9 @@ public: protected: void centerOnScreen(); -protected: +private: LLFrameTimer mVisibleTime; - BOOL mModal; // do not change this after creation! + const BOOL mModal; static std::list sModalStack; // Top of stack is currently being displayed }; diff --git a/linden/indra/llui/llmultislider.cpp b/linden/indra/llui/llmultislider.cpp new file mode 100644 index 0000000..d0c9002 --- /dev/null +++ b/linden/indra/llui/llmultislider.cpp @@ -0,0 +1,677 @@ +/** + * @file llmultisldr.cpp + * @brief LLMultiSlider base class + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llmultislider.h" +#include "llui.h" + +#include "llgl.h" +#include "llwindow.h" +#include "llfocusmgr.h" +#include "llkeyboard.h" // for the MASK constants +#include "llcontrol.h" +#include "llimagegl.h" + +#include + +const S32 MULTI_THUMB_WIDTH = 8; +const S32 MULTI_TRACK_HEIGHT = 6; +const F32 FLOAT_THRESHOLD = 0.00001f; +const S32 EXTRA_TRIANGLE_WIDTH = 2; +const S32 EXTRA_TRIANGLE_HEIGHT = -2; + +S32 LLMultiSlider::mNameCounter = 0; + +LLMultiSlider::LLMultiSlider( + const LLString& name, + const LLRect& rect, + void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata), + void* callback_userdata, + F32 initial_value, + F32 min_value, + F32 max_value, + F32 increment, + S32 max_sliders, + BOOL allow_overlap, + BOOL draw_track, + BOOL use_triangle, + const LLString& control_name) + : + LLUICtrl( name, rect, TRUE, on_commit_callback, callback_userdata, + FOLLOWS_LEFT | FOLLOWS_TOP), + + mInitialValue( initial_value ), + mMinValue( min_value ), + mMaxValue( max_value ), + mIncrement( increment ), + mMaxNumSliders(max_sliders), + mAllowOverlap(allow_overlap), + mDrawTrack(draw_track), + mUseTriangle(use_triangle), + mMouseOffset( 0 ), + mDragStartThumbRect( 0, getRect().getHeight(), MULTI_THUMB_WIDTH, 0 ), + mTrackColor( LLUI::sColorsGroup->getColor( "MultiSliderTrackColor" ) ), + mThumbOutlineColor( LLUI::sColorsGroup->getColor( "MultiSliderThumbOutlineColor" ) ), + mThumbCenterColor( LLUI::sColorsGroup->getColor( "MultiSliderThumbCenterColor" ) ), + mThumbCenterSelectedColor( LLUI::sColorsGroup->getColor( "MultiSliderThumbCenterSelectedColor" ) ), + mDisabledThumbColor(LLUI::sColorsGroup->getColor( "MultiSliderDisabledThumbColor" ) ), + mTriangleColor(LLUI::sColorsGroup->getColor( "MultiSliderTriangleColor" ) ), + mMouseDownCallback( NULL ), + mMouseUpCallback( NULL ) +{ + mValue.emptyMap(); + mCurSlider = LLString::null; + + // properly handle setting the starting thumb rect + // do it this way to handle both the operating-on-settings + // and standalone ways of using this + setControlName(control_name, NULL); + setValue(getValue()); +} + +EWidgetType LLMultiSlider::getWidgetType() const +{ + return WIDGET_TYPE_MULTI_SLIDER_BAR; +} + +LLString LLMultiSlider::getWidgetTag() const +{ + return LL_MULTI_SLIDER_TAG; +} + +void LLMultiSlider::setSliderValue(const LLString& name, F32 value, BOOL from_event) +{ + // exit if not there + if(!mValue.has(name)) { + return; + } + + value = llclamp( value, mMinValue, mMaxValue ); + + // Round to nearest increment (bias towards rounding down) + value -= mMinValue; + value += mIncrement/2.0001f; + value -= fmod(value, mIncrement); + F32 newValue = mMinValue + value; + + // now, make sure no overlap + // if we want that + if(!mAllowOverlap) { + bool hit = false; + + // look at the current spot + // and see if anything is there + LLSD::map_iterator mIt = mValue.beginMap(); + for(;mIt != mValue.endMap(); mIt++) { + + F32 testVal = (F32)mIt->second.asReal() - newValue; + if(testVal > -FLOAT_THRESHOLD && testVal < FLOAT_THRESHOLD && + mIt->first != name) { + hit = true; + break; + } + } + + // if none found, stop + if(hit) { + return; + } + } + + + // now set it in the map + mValue[name] = newValue; + + // set the control if it's the current slider and not from an event + if (!from_event && name == mCurSlider) + { + setControlValue(mValue); + } + + F32 t = (newValue - mMinValue) / (mMaxValue - mMinValue); + + S32 left_edge = MULTI_THUMB_WIDTH/2; + S32 right_edge = getRect().getWidth() - (MULTI_THUMB_WIDTH/2); + + S32 x = left_edge + S32( t * (right_edge - left_edge) ); + mThumbRects[name].mLeft = x - (MULTI_THUMB_WIDTH/2); + mThumbRects[name].mRight = x + (MULTI_THUMB_WIDTH/2); +} + +void LLMultiSlider::setValue(const LLSD& value) +{ + // only do if it's a map + if(value.isMap()) { + + // add each value... the first in the map becomes the current + LLSD::map_const_iterator mIt = value.beginMap(); + mCurSlider = mIt->first; + + for(; mIt != value.endMap(); mIt++) { + setSliderValue(mIt->first, (F32)mIt->second.asReal(), TRUE); + } + } +} + +F32 LLMultiSlider::getSliderValue(const LLString& name) const +{ + return (F32)mValue[name].asReal(); +} + +void LLMultiSlider::setCurSlider(const LLString& name) +{ + if(mValue.has(name)) { + mCurSlider = name; + } +} + +const LLString& LLMultiSlider::addSlider() +{ + return addSlider(mInitialValue); +} + +const LLString& LLMultiSlider::addSlider(F32 val) +{ + std::stringstream newName; + F32 initVal = val; + + if(mValue.size() >= mMaxNumSliders) { + return LLString::null; + } + + // create a new name + newName << "sldr" << mNameCounter; + mNameCounter++; + + bool foundOne = findUnusedValue(initVal); + if(!foundOne) { + return LLString::null; + } + + // add a new thumb rect + mThumbRects[newName.str()] = LLRect( 0, getRect().getHeight(), MULTI_THUMB_WIDTH, 0 ); + + // add the value and set the current slider to this one + mValue.insert(newName.str(), initVal); + mCurSlider = newName.str(); + + // move the slider + setSliderValue(mCurSlider, initVal, TRUE); + + return mCurSlider; +} + +bool LLMultiSlider::findUnusedValue(F32& initVal) +{ + bool firstTry = true; + + // find the first open slot starting with + // the initial value + while(true) { + + bool hit = false; + + // look at the current spot + // and see if anything is there + LLSD::map_iterator mIt = mValue.beginMap(); + for(;mIt != mValue.endMap(); mIt++) { + + F32 testVal = (F32)mIt->second.asReal() - initVal; + if(testVal > -FLOAT_THRESHOLD && testVal < FLOAT_THRESHOLD) { + hit = true; + break; + } + } + + // if we found one + if(!hit) { + break; + } + + // increment and wrap if need be + initVal += mIncrement; + if(initVal > mMaxValue) { + initVal = mMinValue; + } + + // stop if it's filled + if(initVal == mInitialValue && !firstTry) { + llwarns << "Whoa! Too many multi slider elements to add one to" << llendl; + return false; + } + + firstTry = false; + continue; + } + + return true; +} + + +void LLMultiSlider::deleteSlider(const LLString& name) +{ + // can't delete last slider + if(mValue.size() <= 0) { + return; + } + + // get rid of value from mValue and its thumb rect + mValue.erase(name); + mThumbRects.erase(name); + + // set to the last created + if(mValue.size() > 0) { + std::map::iterator mIt = mThumbRects.end(); + mIt--; + mCurSlider = mIt->first; + } +} + +void LLMultiSlider::clear() +{ + while(mThumbRects.size() > 0) { + deleteCurSlider(); + } + + LLUICtrl::clear(); +} + +BOOL LLMultiSlider::handleHover(S32 x, S32 y, MASK mask) +{ + if( gFocusMgr.getMouseCapture() == this ) + { + S32 left_edge = MULTI_THUMB_WIDTH/2; + S32 right_edge = getRect().getWidth() - (MULTI_THUMB_WIDTH/2); + + x += mMouseOffset; + x = llclamp( x, left_edge, right_edge ); + + F32 t = F32(x - left_edge) / (right_edge - left_edge); + setCurSliderValue(t * (mMaxValue - mMinValue) + mMinValue ); + onCommit(); + + getWindow()->setCursor(UI_CURSOR_ARROW); + lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (active)" << llendl; + } + else + { + getWindow()->setCursor(UI_CURSOR_ARROW); + lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl; + } + return TRUE; +} + +BOOL LLMultiSlider::handleMouseUp(S32 x, S32 y, MASK mask) +{ + BOOL handled = FALSE; + + if( gFocusMgr.getMouseCapture() == this ) + { + gFocusMgr.setMouseCapture( NULL ); + + if( mMouseUpCallback ) + { + mMouseUpCallback( this, mCallbackUserData ); + } + handled = TRUE; + make_ui_sound("UISndClickRelease"); + } + else + { + handled = TRUE; + } + + return handled; +} + +BOOL LLMultiSlider::handleMouseDown(S32 x, S32 y, MASK mask) +{ + // only do sticky-focus on non-chrome widgets + if (!getIsChrome()) + { + setFocus(TRUE); + } + if( mMouseDownCallback ) + { + mMouseDownCallback( this, mCallbackUserData ); + } + + if (MASK_CONTROL & mask) // if CTRL is modifying + { + setCurSliderValue(mInitialValue); + onCommit(); + } + else + { + // scroll through thumbs to see if we have a new one selected and select that one + std::map::iterator mIt = mThumbRects.begin(); + for(; mIt != mThumbRects.end(); mIt++) { + + // check if inside. If so, set current slider and continue + if(mIt->second.pointInRect(x,y)) { + mCurSlider = mIt->first; + break; + } + } + + // Find the offset of the actual mouse location from the center of the thumb. + if (mThumbRects[mCurSlider].pointInRect(x,y)) + { + mMouseOffset = (mThumbRects[mCurSlider].mLeft + MULTI_THUMB_WIDTH/2) - x; + } + else + { + mMouseOffset = 0; + } + + // Start dragging the thumb + // No handler needed for focus lost since this class has no state that depends on it. + gFocusMgr.setMouseCapture( this ); + mDragStartThumbRect = mThumbRects[mCurSlider]; + } + make_ui_sound("UISndClick"); + + return TRUE; +} + +BOOL LLMultiSlider::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) +{ + BOOL handled = FALSE; + if( getVisible() && getEnabled() && !called_from_parent ) + { + switch(key) + { + case KEY_UP: + case KEY_DOWN: + // eat up and down keys to be consistent + handled = TRUE; + break; + case KEY_LEFT: + setCurSliderValue(getCurSliderValue() - getIncrement()); + onCommit(); + handled = TRUE; + break; + case KEY_RIGHT: + setCurSliderValue(getCurSliderValue() + getIncrement()); + onCommit(); + handled = TRUE; + break; + default: + break; + } + } + return handled; +} + +void LLMultiSlider::draw() +{ + LLColor4 curThumbColor; + + std::map::iterator mIt; + std::map::iterator curSldrIt; + if( getVisible() ) + { + // Draw background and thumb. + + // drawing solids requires texturing be disabled + LLGLSNoTexture no_texture; + + LLRect rect(mDragStartThumbRect); + + F32 opacity = getEnabled() ? 1.f : 0.3f; + + // Track + LLUUID thumb_image_id; + thumb_image_id.set(LLUI::sAssetsGroup->getString("rounded_square.tga")); + LLPointer thumb_imagep(LLUI::sImageProvider->getUIImageByID(thumb_image_id)->getImage()); + + S32 height_offset = (getRect().getHeight() - MULTI_TRACK_HEIGHT) / 2; + LLRect track_rect(0, getRect().getHeight() - height_offset, getRect().getWidth(), height_offset ); + + + if(mDrawTrack) + { + track_rect.stretch(-1); + gl_draw_scaled_image_with_border(track_rect.mLeft, track_rect.mBottom, 16, 16, track_rect.getWidth(), track_rect.getHeight(), + thumb_imagep, mTrackColor % opacity); + } + + // if we're supposed to use a drawn triangle + // simple gl call for the triangle + if(mUseTriangle) { + + for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) { + + gl_triangle_2d( + mIt->second.mLeft - EXTRA_TRIANGLE_WIDTH, + mIt->second.mTop + EXTRA_TRIANGLE_HEIGHT, + mIt->second.mRight + EXTRA_TRIANGLE_WIDTH, + mIt->second.mTop + EXTRA_TRIANGLE_HEIGHT, + mIt->second.mLeft + mIt->second.getWidth() / 2, + mIt->second.mBottom - EXTRA_TRIANGLE_HEIGHT, + mTriangleColor, TRUE); + } + } + else if (!thumb_imagep) + { + // draw all the thumbs + curSldrIt = mThumbRects.end(); + for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) { + + // choose the color + curThumbColor = mThumbCenterColor; + if(mIt->first == mCurSlider) { + + curSldrIt = mIt; + continue; + //curThumbColor = mThumbCenterSelectedColor; + } + + // the draw command + gl_rect_2d(mIt->second, curThumbColor, TRUE); + } + + // now draw the current slider + if(curSldrIt != mThumbRects.end()) { + gl_rect_2d(curSldrIt->second, mThumbCenterSelectedColor, TRUE); + } + + // and draw the drag start + if (gFocusMgr.getMouseCapture() == this) + { + gl_rect_2d(mDragStartThumbRect, mThumbCenterColor % opacity, FALSE); + } + } + else if( gFocusMgr.getMouseCapture() == this ) + { + // draw drag start + gl_draw_scaled_image_with_border(mDragStartThumbRect.mLeft, + mDragStartThumbRect.mBottom, 16, 16, + mDragStartThumbRect.getWidth(), + mDragStartThumbRect.getHeight(), + thumb_imagep, mThumbCenterColor % 0.3f, TRUE); + + // draw the highlight + if (hasFocus()) + { + F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); + LLRect highlight_rect = mThumbRects[mCurSlider]; + highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt))); + gl_draw_scaled_image_with_border(highlight_rect.mLeft, + highlight_rect.mBottom, 16, 16, highlight_rect.getWidth(), + highlight_rect.getHeight(), + thumb_imagep, gFocusMgr.getFocusColor()); + } + + // draw the thumbs + curSldrIt = mThumbRects.end(); + for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) { + + // choose the color + curThumbColor = mThumbCenterColor; + if(mIt->first == mCurSlider) { + // don't draw now, draw last + curSldrIt = mIt; + continue; + } + + // the draw command + gl_draw_scaled_image_with_border( + mIt->second.mLeft, + mIt->second.mBottom, 16, 16, + mIt->second.getWidth(), + mIt->second.getHeight(), thumb_imagep, + curThumbColor, TRUE); + } + + // draw cur slider last + if(curSldrIt != mThumbRects.end()) { + gl_draw_scaled_image_with_border( + curSldrIt->second.mLeft, + curSldrIt->second.mBottom, 16, 16, + curSldrIt->second.getWidth(), + curSldrIt->second.getHeight(), thumb_imagep, + mThumbCenterSelectedColor, TRUE); + } + + } + else + { + // draw highlight + if (hasFocus()) + { + F32 lerp_amt = gFocusMgr.getFocusFlashAmt(); + LLRect highlight_rect = mThumbRects[mCurSlider]; + highlight_rect.stretch(llround(lerp(1.f, 3.f, lerp_amt))); + gl_draw_scaled_image_with_border(highlight_rect.mLeft, highlight_rect.mBottom, 16, 16, highlight_rect.getWidth(), highlight_rect.getHeight(), + thumb_imagep, gFocusMgr.getFocusColor()); + } + + // draw thumbs + curSldrIt = mThumbRects.end(); + for(mIt = mThumbRects.begin(); mIt != mThumbRects.end(); mIt++) { + + // choose the color + curThumbColor = mThumbCenterColor; + if(mIt->first == mCurSlider) { + curSldrIt = mIt; + continue; + //curThumbColor = mThumbCenterSelectedColor; + } + + // the draw command + gl_draw_scaled_image_with_border( + mIt->second.mLeft, + mIt->second.mBottom, 16, 16, + mIt->second.getWidth(), + mIt->second.getHeight(), thumb_imagep, + curThumbColor % opacity, TRUE); + } + + if(curSldrIt != mThumbRects.end()) { + gl_draw_scaled_image_with_border( + curSldrIt->second.mLeft, + curSldrIt->second.mBottom, 16, 16, + curSldrIt->second.getWidth(), + curSldrIt->second.getHeight(), thumb_imagep, + mThumbCenterSelectedColor % opacity, TRUE); + } + } + + LLUICtrl::draw(); + } +} + +// virtual +LLXMLNodePtr LLMultiSlider::getXML(bool save_children) const +{ + LLXMLNodePtr node = LLUICtrl::getXML(); + + node->createChild("initial_val", TRUE)->setFloatValue(getInitialValue()); + node->createChild("min_val", TRUE)->setFloatValue(getMinValue()); + node->createChild("max_val", TRUE)->setFloatValue(getMaxValue()); + node->createChild("increment", TRUE)->setFloatValue(getIncrement()); + + return node; +} + + +//static +LLView* LLMultiSlider::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) +{ + LLString name("multi_slider_bar"); + node->getAttributeString("name", name); + + LLRect rect; + createRect(node, rect, parent, LLRect()); + + F32 initial_value = 0.f; + node->getAttributeF32("initial_val", initial_value); + + F32 min_value = 0.f; + node->getAttributeF32("min_val", min_value); + + F32 max_value = 1.f; + node->getAttributeF32("max_val", max_value); + + F32 increment = 0.1f; + node->getAttributeF32("increment", increment); + + S32 max_sliders = 1; + node->getAttributeS32("max_sliders", max_sliders); + + BOOL allow_overlap = FALSE; + node->getAttributeBOOL("allow_overlap", allow_overlap); + + BOOL draw_track = TRUE; + node->getAttributeBOOL("draw_track", draw_track); + + BOOL use_triangle = FALSE; + node->getAttributeBOOL("use_triangle", use_triangle); + + LLMultiSlider* multiSlider = new LLMultiSlider(name, + rect, + NULL, + NULL, + initial_value, + min_value, + max_value, + increment, + max_sliders, + allow_overlap, + draw_track, + use_triangle); + + multiSlider->initFromXML(node, parent); + + return multiSlider; +} diff --git a/linden/indra/llui/llmultislider.h b/linden/indra/llui/llmultislider.h new file mode 100644 index 0000000..7cd5061 --- /dev/null +++ b/linden/indra/llui/llmultislider.h @@ -0,0 +1,129 @@ +/** + * @file llmultislider.h + * @brief A simple multislider + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_MULTI_SLIDER_H +#define LL_MULTI_SLIDER_H + +#include "lluictrl.h" +#include "v4color.h" + +class LLUICtrlFactory; + +class LLMultiSlider : public LLUICtrl +{ +public: + LLMultiSlider( + const LLString& name, + const LLRect& rect, + void (*on_commit_callback)(LLUICtrl* ctrl, void* userdata), + void* callback_userdata, + F32 initial_value, + F32 min_value, + F32 max_value, + F32 increment, + S32 max_sliders, + BOOL allow_overlap, + BOOL draw_track, + BOOL use_triangle, + const LLString& control_name = LLString::null ); + + virtual EWidgetType getWidgetType() const; + virtual LLString getWidgetTag() const; + virtual LLXMLNodePtr getXML(bool save_children = true) const; + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + + void setSliderValue(const LLString& name, F32 value, BOOL from_event = FALSE); + F32 getSliderValue(const LLString& name) const; + + const LLString& getCurSlider() const { return mCurSlider; } + F32 getCurSliderValue() const { return getSliderValue(mCurSlider); } + void setCurSlider(const LLString& name); + void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mCurSlider, val, from_event); } + + virtual void setValue(const LLSD& value); + virtual LLSD getValue() const { return mValue; } + + virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); } + virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); } + + F32 getInitialValue() const { return mInitialValue; } + F32 getMinValue() const { return mMinValue; } + F32 getMaxValue() const { return mMaxValue; } + F32 getIncrement() const { return mIncrement; } + void setMinValue(F32 min_value) { mMinValue = min_value; } + void setMaxValue(F32 max_value) { mMaxValue = max_value; } + void setIncrement(F32 increment) { mIncrement = increment; } + void setMouseDownCallback( void (*cb)(LLUICtrl* ctrl, void* userdata) ) { mMouseDownCallback = cb; } + void setMouseUpCallback( void (*cb)(LLUICtrl* ctrl, void* userdata) ) { mMouseUpCallback = cb; } + + bool findUnusedValue(F32& initVal); + const LLString& addSlider(); + const LLString& addSlider(F32 val); + void deleteSlider(const LLString& name); + void deleteCurSlider() { deleteSlider(mCurSlider); } + void clear(); + + virtual BOOL handleHover(S32 x, S32 y, MASK mask); + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); + virtual void draw(); + +protected: + LLSD mValue; + F32 mInitialValue; + F32 mMinValue; + F32 mMaxValue; + F32 mIncrement; + LLString mCurSlider; + static S32 mNameCounter; + + S32 mMaxNumSliders; + BOOL mAllowOverlap; + BOOL mDrawTrack; + BOOL mUseTriangle; /// hacked in toggle to use a triangle + + S32 mMouseOffset; + LLRect mDragStartThumbRect; + + std::map mThumbRects; + LLColor4 mTrackColor; + LLColor4 mThumbOutlineColor; + LLColor4 mThumbCenterColor; + LLColor4 mThumbCenterSelectedColor; + LLColor4 mDisabledThumbColor; + LLColor4 mTriangleColor; + + void (*mMouseDownCallback)(LLUICtrl* ctrl, void* userdata); + void (*mMouseUpCallback)(LLUICtrl* ctrl, void* userdata); +}; + +#endif // LL_LLSLIDER_H diff --git a/linden/indra/llui/llmultisliderctrl.cpp b/linden/indra/llui/llmultisliderctrl.cpp new file mode 100644 index 0000000..0d23dd7 --- /dev/null +++ b/linden/indra/llui/llmultisliderctrl.cpp @@ -0,0 +1,634 @@ +/** + * @file llmultisliderctrl.cpp + * @brief LLMultiSliderCtrl base class + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llmultisliderctrl.h" + +#include "audioengine.h" +#include "sound_ids.h" + +#include "llmath.h" +#include "llfontgl.h" +#include "llgl.h" +#include "llkeyboard.h" +#include "lllineeditor.h" +#include "llmultislider.h" +#include "llstring.h" +#include "lltextbox.h" +#include "llui.h" +#include "lluiconstants.h" +#include "llcontrol.h" +#include "llfocusmgr.h" +#include "llresmgr.h" + +const U32 MAX_STRING_LENGTH = 10; + + +LLMultiSliderCtrl::LLMultiSliderCtrl(const LLString& name, const LLRect& rect, + const LLString& label, + const LLFontGL* font, + S32 label_width, + S32 text_left, + BOOL show_text, + BOOL can_edit_text, + void (*commit_callback)(LLUICtrl*, void*), + void* callback_user_data, + F32 initial_value, F32 min_value, F32 max_value, F32 increment, + S32 max_sliders, BOOL allow_overlap, + BOOL draw_track, + BOOL use_triangle, + const LLString& control_which) + : LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data ), + mFont(font), + mShowText( show_text ), + mCanEditText( can_edit_text ), + mPrecision( 3 ), + mLabelBox( NULL ), + mLabelWidth( label_width ), + + mEditor( NULL ), + mTextBox( NULL ), + mTextEnabledColor( LLUI::sColorsGroup->getColor( "LabelTextColor" ) ), + mTextDisabledColor( LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ), + mSliderMouseUpCallback( NULL ), + mSliderMouseDownCallback( NULL ) +{ + S32 top = getRect().getHeight(); + S32 bottom = 0; + S32 left = 0; + + // Label + if( !label.empty() ) + { + if (label_width == 0) + { + label_width = font->getWidth(label); + } + LLRect label_rect( left, top, label_width, bottom ); + mLabelBox = new LLTextBox( "MultiSliderCtrl Label", label_rect, label.c_str(), font ); + addChild(mLabelBox); + } + + S32 slider_right = getRect().getWidth(); + if( show_text ) + { + slider_right = text_left - MULTI_SLIDERCTRL_SPACING; + } + + S32 slider_left = label_width ? label_width + MULTI_SLIDERCTRL_SPACING : 0; + LLRect slider_rect( slider_left, top, slider_right, bottom ); + mMultiSlider = new LLMultiSlider( + "multi_slider", + slider_rect, + LLMultiSliderCtrl::onSliderCommit, this, + initial_value, min_value, max_value, increment, + max_sliders, allow_overlap, draw_track, + use_triangle, + control_which ); + addChild( mMultiSlider ); + mCurValue = mMultiSlider->getCurSliderValue(); + + if( show_text ) + { + LLRect text_rect( text_left, top, getRect().getWidth(), bottom ); + if( can_edit_text ) + { + mEditor = new LLLineEditor( "MultiSliderCtrl Editor", text_rect, + "", font, + MAX_STRING_LENGTH, + &LLMultiSliderCtrl::onEditorCommit, NULL, NULL, this, + &LLLineEditor::prevalidateFloat ); + mEditor->setFollowsLeft(); + mEditor->setFollowsBottom(); + mEditor->setFocusReceivedCallback( &LLMultiSliderCtrl::onEditorGainFocus ); + mEditor->setIgnoreTab(TRUE); + // don't do this, as selecting the entire text is single clicking in some cases + // and double clicking in others + //mEditor->setSelectAllonFocusReceived(TRUE); + addChild(mEditor); + } + else + { + mTextBox = new LLTextBox( "MultiSliderCtrl Text", text_rect, "", font); + mTextBox->setFollowsLeft(); + mTextBox->setFollowsBottom(); + addChild(mTextBox); + } + } + + updateText(); +} + +LLMultiSliderCtrl::~LLMultiSliderCtrl() +{ + // Children all cleaned up by default view destructor. +} + +// static +void LLMultiSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata ) +{ + LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata; + llassert( caller == self->mEditor ); + + self->onFocusReceived(); +} + + +void LLMultiSliderCtrl::setValue(const LLSD& value) +{ + mMultiSlider->setValue(value); + mCurValue = mMultiSlider->getCurSliderValue(); + updateText(); +} + +void LLMultiSliderCtrl::setSliderValue(const LLString& name, F32 v, BOOL from_event) +{ + mMultiSlider->setSliderValue(name, v, from_event ); + mCurValue = mMultiSlider->getCurSliderValue(); + updateText(); +} + +void LLMultiSliderCtrl::setCurSlider(const LLString& name) +{ + mMultiSlider->setCurSlider(name); + mCurValue = mMultiSlider->getCurSliderValue(); +} + +BOOL LLMultiSliderCtrl::setLabelArg( const LLString& key, const LLString& text ) +{ + BOOL res = FALSE; + if (mLabelBox) + { + res = mLabelBox->setTextArg(key, text); + if (res && mLabelWidth == 0) + { + S32 label_width = mFont->getWidth(mLabelBox->getText()); + LLRect rect = mLabelBox->getRect(); + S32 prev_right = rect.mRight; + rect.mRight = rect.mLeft + label_width; + mLabelBox->setRect(rect); + + S32 delta = rect.mRight - prev_right; + rect = mMultiSlider->getRect(); + S32 left = rect.mLeft + delta; + left = llclamp(left, 0, rect.mRight-MULTI_SLIDERCTRL_SPACING); + rect.mLeft = left; + mMultiSlider->setRect(rect); + } + } + return res; +} + +const LLString& LLMultiSliderCtrl::addSlider() +{ + const LLString& name = mMultiSlider->addSlider(); + + // if it returns null, pass it on + if(name == LLString::null) { + return LLString::null; + } + + // otherwise, update stuff + mCurValue = mMultiSlider->getCurSliderValue(); + updateText(); + return name; +} + +const LLString& LLMultiSliderCtrl::addSlider(F32 val) +{ + const LLString& name = mMultiSlider->addSlider(val); + + // if it returns null, pass it on + if(name == LLString::null) { + return LLString::null; + } + + // otherwise, update stuff + mCurValue = mMultiSlider->getCurSliderValue(); + updateText(); + return name; +} + +void LLMultiSliderCtrl::deleteSlider(const LLString& name) +{ + mMultiSlider->deleteSlider(name); + mCurValue = mMultiSlider->getCurSliderValue(); + updateText(); +} + + +void LLMultiSliderCtrl::clear() +{ + setCurSliderValue(0.0f); + if( mEditor ) + { + mEditor->setText(LLString("")); + } + if( mTextBox ) + { + mTextBox->setText(LLString("")); + } + + // get rid of sliders + mMultiSlider->clear(); + +} + +BOOL LLMultiSliderCtrl::isMouseHeldDown() +{ + return gFocusMgr.getMouseCapture() == mMultiSlider; +} + +void LLMultiSliderCtrl::updateText() +{ + if( mEditor || mTextBox ) + { + LLLocale locale(LLLocale::USER_LOCALE); + + // Don't display very small negative values as -0.000 + F32 displayed_value = (F32)(floor(getCurSliderValue() * pow(10.0, (F64)mPrecision) + 0.5) / pow(10.0, (F64)mPrecision)); + + LLString format = llformat("%%.%df", mPrecision); + LLString text = llformat(format.c_str(), displayed_value); + if( mEditor ) + { + mEditor->setText( text ); + } + else + { + mTextBox->setText( text ); + } + } +} + +// static +void LLMultiSliderCtrl::onEditorCommit( LLUICtrl* caller, void *userdata ) +{ + LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata; + llassert( caller == self->mEditor ); + + BOOL success = FALSE; + F32 val = self->mCurValue; + F32 saved_val = self->mCurValue; + + LLString text = self->mEditor->getText(); + if( LLLineEditor::postvalidateFloat( text ) ) + { + LLLocale locale(LLLocale::USER_LOCALE); + val = (F32) atof( text.c_str() ); + if( self->mMultiSlider->getMinValue() <= val && val <= self->mMultiSlider->getMaxValue() ) + { + if( self->mValidateCallback ) + { + self->setCurSliderValue( val ); // set the value temporarily so that the callback can retrieve it. + if( self->mValidateCallback( self, self->mCallbackUserData ) ) + { + success = TRUE; + } + } + else + { + self->setCurSliderValue( val ); + success = TRUE; + } + } + } + + if( success ) + { + self->onCommit(); + } + else + { + if( self->getCurSliderValue() != saved_val ) + { + self->setCurSliderValue( saved_val ); + } + self->reportInvalidData(); + } + self->updateText(); +} + +// static +void LLMultiSliderCtrl::onSliderCommit( LLUICtrl* caller, void *userdata ) +{ + LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata; + //llassert( caller == self->mSlider ); + + BOOL success = FALSE; + F32 saved_val = self->mCurValue; + F32 new_val = self->mMultiSlider->getCurSliderValue(); + + if( self->mValidateCallback ) + { + self->mCurValue = new_val; // set the value temporarily so that the callback can retrieve it. + if( self->mValidateCallback( self, self->mCallbackUserData ) ) + { + success = TRUE; + } + } + else + { + self->mCurValue = new_val; + success = TRUE; + } + + if( success ) + { + self->onCommit(); + } + else + { + if( self->mCurValue != saved_val ) + { + self->setCurSliderValue( saved_val ); + } + self->reportInvalidData(); + } + self->updateText(); +} + +void LLMultiSliderCtrl::setEnabled(BOOL b) +{ + LLUICtrl::setEnabled( b ); + + if( mLabelBox ) + { + mLabelBox->setColor( b ? mTextEnabledColor : mTextDisabledColor ); + } + + mMultiSlider->setEnabled( b ); + + if( mEditor ) + { + mEditor->setEnabled( b ); + } + + if( mTextBox ) + { + mTextBox->setColor( b ? mTextEnabledColor : mTextDisabledColor ); + } +} + + +void LLMultiSliderCtrl::setTentative(BOOL b) +{ + if( mEditor ) + { + mEditor->setTentative(b); + } + LLUICtrl::setTentative(b); +} + + +void LLMultiSliderCtrl::onCommit() +{ + setTentative(FALSE); + + if( mEditor ) + { + mEditor->setTentative(FALSE); + } + + LLUICtrl::onCommit(); +} + + +void LLMultiSliderCtrl::setPrecision(S32 precision) +{ + if (precision < 0 || precision > 10) + { + llerrs << "LLMultiSliderCtrl::setPrecision - precision out of range" << llendl; + return; + } + + mPrecision = precision; + updateText(); +} + +void LLMultiSliderCtrl::setSliderMouseDownCallback( void (*slider_mousedown_callback)(LLUICtrl* caller, void* userdata) ) +{ + mSliderMouseDownCallback = slider_mousedown_callback; + mMultiSlider->setMouseDownCallback( LLMultiSliderCtrl::onSliderMouseDown ); +} + +// static +void LLMultiSliderCtrl::onSliderMouseDown(LLUICtrl* caller, void* userdata) +{ + LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata; + if( self->mSliderMouseDownCallback ) + { + self->mSliderMouseDownCallback( self, self->mCallbackUserData ); + } +} + + +void LLMultiSliderCtrl::setSliderMouseUpCallback( void (*slider_mouseup_callback)(LLUICtrl* caller, void* userdata) ) +{ + mSliderMouseUpCallback = slider_mouseup_callback; + mMultiSlider->setMouseUpCallback( LLMultiSliderCtrl::onSliderMouseUp ); +} + +// static +void LLMultiSliderCtrl::onSliderMouseUp(LLUICtrl* caller, void* userdata) +{ + LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata; + if( self->mSliderMouseUpCallback ) + { + self->mSliderMouseUpCallback( self, self->mCallbackUserData ); + } +} + +void LLMultiSliderCtrl::onTabInto() +{ + if( mEditor ) + { + mEditor->onTabInto(); + } +} + +void LLMultiSliderCtrl::reportInvalidData() +{ + make_ui_sound("UISndBadKeystroke"); +} + +//virtual +LLString LLMultiSliderCtrl::getControlName() const +{ + return mMultiSlider->getControlName(); +} + +// virtual +void LLMultiSliderCtrl::setControlName(const LLString& control_name, LLView* context) +{ + mMultiSlider->setControlName(control_name, context); +} + +// virtual +LLXMLNodePtr LLMultiSliderCtrl::getXML(bool save_children) const +{ + LLXMLNodePtr node = LLUICtrl::getXML(); + + node->createChild("show_text", TRUE)->setBoolValue(mShowText); + + node->createChild("can_edit_text", TRUE)->setBoolValue(mCanEditText); + + node->createChild("decimal_digits", TRUE)->setIntValue(mPrecision); + + if (mLabelBox) + { + node->createChild("label", TRUE)->setStringValue(mLabelBox->getText()); + } + + // TomY TODO: Do we really want to export the transient state of the slider? + node->createChild("value", TRUE)->setFloatValue(mCurValue); + + if (mMultiSlider) + { + node->createChild("initial_val", TRUE)->setFloatValue(mMultiSlider->getInitialValue()); + node->createChild("min_val", TRUE)->setFloatValue(mMultiSlider->getMinValue()); + node->createChild("max_val", TRUE)->setFloatValue(mMultiSlider->getMaxValue()); + node->createChild("increment", TRUE)->setFloatValue(mMultiSlider->getIncrement()); + } + addColorXML(node, mTextEnabledColor, "text_enabled_color", "LabelTextColor"); + addColorXML(node, mTextDisabledColor, "text_disabled_color", "LabelDisabledColor"); + + return node; +} + +LLView* LLMultiSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) +{ + LLString name("multi_slider"); + node->getAttributeString("name", name); + + LLString label; + node->getAttributeString("label", label); + + LLRect rect; + createRect(node, rect, parent, LLRect()); + + LLFontGL* font = LLView::selectFont(node); + + // HACK: Font might not be specified. + if (!font) + { + font = LLFontGL::sSansSerifSmall; + } + + S32 label_width = 0; + node->getAttributeS32("label_width", label_width); + + BOOL show_text = TRUE; + node->getAttributeBOOL("show_text", show_text); + + BOOL can_edit_text = FALSE; + node->getAttributeBOOL("can_edit_text", can_edit_text); + + BOOL allow_overlap = FALSE; + node->getAttributeBOOL("allow_overlap", allow_overlap); + + BOOL draw_track = TRUE; + node->getAttributeBOOL("draw_track", draw_track); + + BOOL use_triangle = FALSE; + node->getAttributeBOOL("use_triangle", use_triangle); + + F32 initial_value = 0.f; + node->getAttributeF32("initial_val", initial_value); + + F32 min_value = 0.f; + node->getAttributeF32("min_val", min_value); + + F32 max_value = 1.f; + node->getAttributeF32("max_val", max_value); + + F32 increment = 0.1f; + node->getAttributeF32("increment", increment); + + U32 precision = 3; + node->getAttributeU32("decimal_digits", precision); + + S32 max_sliders = 1; + node->getAttributeS32("max_sliders", max_sliders); + + + S32 text_left = 0; + if (show_text) + { + // calculate the size of the text box (log max_value is number of digits - 1 so plus 1) + if ( max_value ) + text_left = font->getWidth("0") * ( static_cast < S32 > ( log10 ( max_value ) ) + precision + 1 ); + + if ( increment < 1.0f ) + text_left += font->getWidth("."); // (mostly) take account of decimal point in value + + if ( min_value < 0.0f || max_value < 0.0f ) + text_left += font->getWidth("-"); // (mostly) take account of minus sign + + // padding to make things look nicer + text_left += 8; + } + + LLUICtrlCallback callback = NULL; + + if (label.empty()) + { + label.assign(node->getTextContents()); + } + + LLMultiSliderCtrl* slider = new LLMultiSliderCtrl(name, + rect, + label, + font, + label_width, + rect.getWidth() - text_left, + show_text, + can_edit_text, + callback, + NULL, + initial_value, + min_value, + max_value, + increment, + max_sliders, + allow_overlap, + draw_track, + use_triangle); + + slider->setPrecision(precision); + + slider->initFromXML(node, parent); + + slider->updateText(); + + return slider; +} diff --git a/linden/indra/llui/llmultisliderctrl.h b/linden/indra/llui/llmultisliderctrl.h new file mode 100644 index 0000000..90f43df --- /dev/null +++ b/linden/indra/llui/llmultisliderctrl.h @@ -0,0 +1,160 @@ +/** + * @file llmultisliderctrl.h + * @brief LLMultiSliderCtrl base class + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_MULTI_SLIDERCTRL_H +#define LL_MULTI_SLIDERCTRL_H + +#include "lluictrl.h" +#include "v4color.h" +#include "llmultislider.h" +#include "lltextbox.h" +#include "llrect.h" + +// +// Constants +// +const S32 MULTI_SLIDERCTRL_SPACING = 4; // space between label, slider, and text +const S32 MULTI_SLIDERCTRL_HEIGHT = 16; + +// +// Classes +// +class LLFontGL; +class LLLineEditor; +class LLSlider; + + +class LLMultiSliderCtrl : public LLUICtrl +{ +public: + LLMultiSliderCtrl(const LLString& name, + const LLRect& rect, + const LLString& label, + const LLFontGL* font, + S32 slider_left, + S32 text_left, + BOOL show_text, + BOOL can_edit_text, + void (*commit_callback)(LLUICtrl*, void*), + void* callback_userdata, + F32 initial_value, F32 min_value, F32 max_value, F32 increment, + S32 max_sliders, BOOL allow_overlap, BOOL draw_track, + BOOL use_triangle, + const LLString& control_which = LLString::null ); + + virtual ~LLMultiSliderCtrl(); + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_MULTI_SLIDER; } + virtual LLString getWidgetTag() const { return LL_MULTI_SLIDER_CTRL_TAG; } + virtual LLXMLNodePtr getXML(bool save_children = true) const; + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + + F32 getSliderValue(const LLString& name) const; + void setSliderValue(const LLString& name, F32 v, BOOL from_event = FALSE); + + virtual void setValue(const LLSD& value ); + virtual LLSD getValue() const { return mMultiSlider->getValue(); } + virtual BOOL setLabelArg( const LLString& key, const LLString& text ); + + const LLString& getCurSlider() const { return mMultiSlider->getCurSlider(); } + F32 getCurSliderValue() const { return mCurValue; } + void setCurSlider(const LLString& name); + void setCurSliderValue(F32 val, BOOL from_event = false) { setSliderValue(mMultiSlider->getCurSlider(), val, from_event); } + + virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); } + virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); } + + BOOL isMouseHeldDown(); + + virtual void setEnabled( BOOL b ); + virtual void clear(); + virtual void setPrecision(S32 precision); + void setMinValue(F32 min_value) {mMultiSlider->setMinValue(min_value);} + void setMaxValue(F32 max_value) {mMultiSlider->setMaxValue(max_value);} + void setIncrement(F32 increment) {mMultiSlider->setIncrement(increment);} + + /// for adding and deleting sliders + const LLString& addSlider(); + const LLString& addSlider(F32 val); + void deleteSlider(const LLString& name); + void deleteCurSlider() { deleteSlider(mMultiSlider->getCurSlider()); } + + F32 getMinValue() { return mMultiSlider->getMinValue(); } + F32 getMaxValue() { return mMultiSlider->getMaxValue(); } + + void setLabel(const LLString& label) { if (mLabelBox) mLabelBox->setText(label); } + void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; } + void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; } + + void setSliderMouseDownCallback( void (*slider_mousedown_callback)(LLUICtrl* caller, void* userdata) ); + void setSliderMouseUpCallback( void (*slider_mouseup_callback)(LLUICtrl* caller, void* userdata) ); + + virtual void onTabInto(); + + virtual void setTentative(BOOL b); // marks value as tentative + virtual void onCommit(); // mark not tentative, then commit + + virtual void setControlName(const LLString& control_name, LLView* context); + virtual LLString getControlName() const; + + static void onSliderCommit(LLUICtrl* caller, void* userdata); + static void onSliderMouseDown(LLUICtrl* caller,void* userdata); + static void onSliderMouseUp(LLUICtrl* caller,void* userdata); + + static void onEditorCommit(LLUICtrl* caller, void* userdata); + static void onEditorGainFocus(LLFocusableElement* caller, void *userdata); + static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata); + +private: + void updateText(); + void reportInvalidData(); + +private: + const LLFontGL* mFont; + BOOL mShowText; + BOOL mCanEditText; + + S32 mPrecision; + LLTextBox* mLabelBox; + S32 mLabelWidth; + + F32 mCurValue; + LLMultiSlider* mMultiSlider; + LLLineEditor* mEditor; + LLTextBox* mTextBox; + + LLColor4 mTextEnabledColor; + LLColor4 mTextDisabledColor; + + void (*mSliderMouseUpCallback)( LLUICtrl* ctrl, void* userdata ); + void (*mSliderMouseDownCallback)( LLUICtrl* ctrl, void* userdata ); +}; + +#endif // LL_MULTI_SLIDERCTRL_H diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp index b72e104..9a3f1a2 100644 --- a/linden/indra/llui/llpanel.cpp +++ b/linden/indra/llui/llpanel.cpp @@ -60,10 +60,10 @@ #include "llresizebar.h" #include "llcriticaldamp.h" -LLPanel::panel_map_t LLPanel::sPanelMap; LLPanel::alert_queue_t LLPanel::sAlertQueue; const S32 RESIZE_BAR_OVERLAP = 1; +const S32 RESIZE_BAR_HEIGHT = 3; void LLPanel::init() { @@ -78,8 +78,7 @@ void LLPanel::init() setIsChrome(FALSE); //is this a decorator to a live window or a form? mLastTabGroup = 0; - // add self to handle->panel map - sPanelMap[mViewHandle] = this; + mPanelHandle.bind(this); setTabStop(FALSE); } @@ -121,31 +120,11 @@ LLPanel::LLPanel(const LLString& name, const LLString& rect_control, BOOL border } } -void LLPanel::addBorder(LLViewBorder::EBevel border_bevel, - LLViewBorder::EStyle border_style, S32 border_thickness) -{ - removeBorder(); - mBorder = new LLViewBorder( "panel border", - LLRect(0, mRect.getHeight(), mRect.getWidth(), 0), - border_bevel, border_style, border_thickness ); - mBorder->setSaveToXML(false); - addChild( mBorder ); -} - -void LLPanel::removeBorder() -{ - delete mBorder; - mBorder = NULL; -} - - LLPanel::~LLPanel() { storeRectControl(); - sPanelMap.erase(mViewHandle); } - // virtual EWidgetType LLPanel::getWidgetType() const { @@ -159,7 +138,7 @@ LLString LLPanel::getWidgetTag() const } // virtual -BOOL LLPanel::isPanel() +BOOL LLPanel::isPanel() const { return TRUE; } @@ -170,6 +149,24 @@ BOOL LLPanel::postBuild() return TRUE; } +void LLPanel::addBorder(LLViewBorder::EBevel border_bevel, + LLViewBorder::EStyle border_style, S32 border_thickness) +{ + removeBorder(); + mBorder = new LLViewBorder( "panel border", + LLRect(0, getRect().getHeight(), getRect().getWidth(), 0), + border_bevel, border_style, border_thickness ); + mBorder->setSaveToXML(false); + addChild( mBorder ); +} + +void LLPanel::removeBorder() +{ + delete mBorder; + mBorder = NULL; +} + + // virtual void LLPanel::clearCtrls() { @@ -200,8 +197,8 @@ void LLPanel::draw() { //RN: I don't see the point of this S32 left = 0;//LLPANEL_BORDER_WIDTH; - S32 top = mRect.getHeight();// - LLPANEL_BORDER_WIDTH; - S32 right = mRect.getWidth();// - LLPANEL_BORDER_WIDTH; + S32 top = getRect().getHeight();// - LLPANEL_BORDER_WIDTH; + S32 right = getRect().getWidth();// - LLPANEL_BORDER_WIDTH; S32 bottom = 0;//LLPANEL_BORDER_WIDTH; if (mBgOpaque ) @@ -281,13 +278,13 @@ BOOL LLPanel::handleKey(KEY key, MASK mask, BOOL called_from_parent) if( (mask == MASK_SHIFT) && (KEY_TAB == key)) { //SHIFT-TAB - LLView* cur_focus = gFocusMgr.getKeyboardFocus(); + LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); if (cur_focus && gFocusMgr.childHasKeyboardFocus(this)) { - LLView* focus_root = cur_focus; - while(cur_focus->getParent()) + LLUICtrl* focus_root = cur_focus; + while(cur_focus->getParentUICtrl()) { - cur_focus = cur_focus->getParent(); + cur_focus = cur_focus->getParentUICtrl(); if (cur_focus->isFocusRoot()) { // this is the root-most focus root found so far @@ -296,7 +293,7 @@ BOOL LLPanel::handleKey(KEY key, MASK mask, BOOL called_from_parent) } handled = focus_root->focusPrevItem(FALSE); } - else if (!cur_focus && mIsFocusRoot) + else if (!cur_focus && isFocusRoot()) { handled = focusLastItem(); if (!handled) @@ -310,13 +307,13 @@ BOOL LLPanel::handleKey(KEY key, MASK mask, BOOL called_from_parent) if( (mask == MASK_NONE ) && (KEY_TAB == key)) { //TAB - LLView* cur_focus = gFocusMgr.getKeyboardFocus(); + LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); if (cur_focus && gFocusMgr.childHasKeyboardFocus(this)) { - LLView* focus_root = cur_focus; - while(cur_focus->getParent()) + LLUICtrl* focus_root = cur_focus; + while(cur_focus->getParentUICtrl()) { - cur_focus = cur_focus->getParent(); + cur_focus = cur_focus->getParentUICtrl(); if (cur_focus->isFocusRoot()) { focus_root = cur_focus; @@ -324,7 +321,7 @@ BOOL LLPanel::handleKey(KEY key, MASK mask, BOOL called_from_parent) } handled = focus_root->focusNextItem(FALSE); } - else if (!cur_focus && mIsFocusRoot) + else if (!cur_focus && isFocusRoot()) { handled = focusFirstItem(); if (!handled) @@ -408,12 +405,12 @@ void LLPanel::requires(LLString name, EWidgetType type) mRequirements[name] = type; } -BOOL LLPanel::checkRequirements() +BOOL LLPanel::checkRequirements() const { BOOL retval = TRUE; LLString message; - for (requirements_map_t::iterator i = mRequirements.begin(); i != mRequirements.end(); ++i) + for (requirements_map_t::const_iterator i = mRequirements.begin(); i != mRequirements.end(); ++i) { if (!this->getCtrlByNameAndType(i->first, i->second)) { @@ -489,21 +486,6 @@ void LLPanel::setFocus(BOOL b) } } -void LLPanel::setBackgroundColor(const LLColor4& color) -{ - mBgColorOpaque = color; -} - -LLColor4 LLPanel::getBackgroundColor() -{ - return mBgColorOpaque; -} - -void LLPanel::setTransparentColor(const LLColor4& color) -{ - mBgColorAlpha = color; -} - void LLPanel::setBorderVisible(BOOL b) { if (mBorder) @@ -512,18 +494,18 @@ void LLPanel::setBorderVisible(BOOL b) } } -LLView* LLPanel::getCtrlByNameAndType(const LLString& name, EWidgetType type) +LLUICtrl* LLPanel::getCtrlByNameAndType(const LLString& name, EWidgetType type) const { LLView* view = getChildByName(name, TRUE); - if (view) + if (view && view->isCtrl()) { if (type == WIDGET_TYPE_DONTCARE || view->getWidgetType() == type) { - return view; + return (LLUICtrl*)view; } else { - llwarns << "Widget " << name << " has improper type in panel " << mName << "\n" + llwarns << "Widget " << name << " has improper type in panel " << getName() << "\n" << "Is: \t\t" << view->getWidgetType() << "\n" << "Should be: \t" << type << llendl; @@ -536,17 +518,6 @@ LLView* LLPanel::getCtrlByNameAndType(const LLString& name, EWidgetType type) return NULL; } -// static -LLPanel* LLPanel::getPanelByHandle(LLViewHandle handle) -{ - if (!sPanelMap.count(handle)) - { - return NULL; - } - - return sPanelMap[handle]; -} - // virtual LLXMLNodePtr LLPanel::getXML(bool save_children) const { @@ -734,7 +705,7 @@ void LLPanel::setPanelParameters(LLXMLNodePtr node, LLView* parent) setLabel(label); } -LLString LLPanel::getFormattedUIString(const LLString& name, const LLString::format_map_t& args) const +LLString LLPanel::getString(const LLString& name, const LLString::format_map_t& args) const { ui_string_map_t::const_iterator found_it = mUIStrings.find(name); if (found_it != mUIStrings.end()) @@ -744,6 +715,7 @@ LLString LLPanel::getFormattedUIString(const LLString& name, const LLString::for formatted_string.setArgList(args); return formatted_string.getString(); } + llerrs << "Failed to find string " << name << " in panel " << getName() << llendl; return LLString::null; } @@ -754,13 +726,14 @@ LLUIString LLPanel::getUIString(const LLString& name) const { return found_it->second; } + llerrs << "Failed to find string " << name << " in panel " << getName() << llendl; return LLUIString(LLString::null); } void LLPanel::childSetVisible(const LLString& id, bool visible) { - LLView* child = getChildByName(id, true); + LLView* child = getChild(id); if (child) { child->setVisible(visible); @@ -769,7 +742,7 @@ void LLPanel::childSetVisible(const LLString& id, bool visible) bool LLPanel::childIsVisible(const LLString& id) const { - LLView* child = getChildByName(id, true); + LLView* child = getChild(id); if (child) { return (bool)child->getVisible(); @@ -779,7 +752,7 @@ bool LLPanel::childIsVisible(const LLString& id) const void LLPanel::childSetEnabled(const LLString& id, bool enabled) { - LLView* child = getChildByName(id, true); + LLView* child = getChild(id); if (child) { child->setEnabled(enabled); @@ -788,7 +761,7 @@ void LLPanel::childSetEnabled(const LLString& id, bool enabled) void LLPanel::childSetTentative(const LLString& id, bool tentative) { - LLView* child = getChildByName(id, true); + LLView* child = getChild(id); if (child) { child->setTentative(tentative); @@ -797,7 +770,7 @@ void LLPanel::childSetTentative(const LLString& id, bool tentative) bool LLPanel::childIsEnabled(const LLString& id) const { - LLView* child = getChildByName(id, true); + LLView* child = getChild(id); if (child) { return (bool)child->getEnabled(); @@ -808,7 +781,7 @@ bool LLPanel::childIsEnabled(const LLString& id) const void LLPanel::childSetToolTip(const LLString& id, const LLString& msg) { - LLView* child = getChildByName(id, true); + LLView* child = getChild(id); if (child) { child->setToolTip(msg); @@ -817,7 +790,7 @@ void LLPanel::childSetToolTip(const LLString& id, const LLString& msg) void LLPanel::childSetRect(const LLString& id, const LLRect& rect) { - LLView* child = getChildByName(id, true); + LLView* child = getChild(id); if (child) { child->setRect(rect); @@ -826,7 +799,7 @@ void LLPanel::childSetRect(const LLString& id, const LLRect& rect) bool LLPanel::childGetRect(const LLString& id, LLRect& rect) const { - LLView* child = getChildByName(id, true); + LLView* child = getChild(id); if (child) { rect = child->getRect(); @@ -837,7 +810,7 @@ bool LLPanel::childGetRect(const LLString& id, LLRect& rect) const void LLPanel::childSetFocus(const LLString& id, BOOL focus) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { child->setFocus(focus); @@ -846,7 +819,7 @@ void LLPanel::childSetFocus(const LLString& id, BOOL focus) BOOL LLPanel::childHasFocus(const LLString& id) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { return child->hasFocus(); @@ -861,7 +834,7 @@ BOOL LLPanel::childHasFocus(const LLString& id) void LLPanel::childSetFocusChangedCallback(const LLString& id, void (*cb)(LLFocusableElement*, void*), void* user_data) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { child->setFocusChangedCallback(cb, user_data); @@ -870,7 +843,7 @@ void LLPanel::childSetFocusChangedCallback(const LLString& id, void (*cb)(LLFocu void LLPanel::childSetCommitCallback(const LLString& id, void (*cb)(LLUICtrl*, void*), void *userdata ) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { child->setCommitCallback(cb); @@ -880,7 +853,7 @@ void LLPanel::childSetCommitCallback(const LLString& id, void (*cb)(LLUICtrl*, v void LLPanel::childSetDoubleClickCallback(const LLString& id, void (*cb)(void*), void *userdata ) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { child->setDoubleClickCallback(cb); @@ -893,7 +866,7 @@ void LLPanel::childSetDoubleClickCallback(const LLString& id, void (*cb)(void*), void LLPanel::childSetValidate(const LLString& id, BOOL (*cb)(LLUICtrl*, void*)) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { child->setValidateBeforeCommit(cb); @@ -902,7 +875,7 @@ void LLPanel::childSetValidate(const LLString& id, BOOL (*cb)(LLUICtrl*, void*)) void LLPanel::childSetUserData(const LLString& id, void* userdata) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { child->setCallbackUserData(userdata); @@ -911,16 +884,16 @@ void LLPanel::childSetUserData(const LLString& id, void* userdata) void LLPanel::childSetColor(const LLString& id, const LLColor4& color) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { child->setColor(color); } } -LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const LLString& id) +LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const LLString& id) const { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { return child->getSelectionInterface(); @@ -928,9 +901,9 @@ LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const LLString& id return NULL; } -LLCtrlListInterface* LLPanel::childGetListInterface(const LLString& id) +LLCtrlListInterface* LLPanel::childGetListInterface(const LLString& id) const { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { return child->getListInterface(); @@ -938,9 +911,9 @@ LLCtrlListInterface* LLPanel::childGetListInterface(const LLString& id) return NULL; } -LLCtrlScrollInterface* LLPanel::childGetScrollInterface(const LLString& id) +LLCtrlScrollInterface* LLPanel::childGetScrollInterface(const LLString& id) const { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { return child->getScrollInterface(); @@ -950,7 +923,7 @@ LLCtrlScrollInterface* LLPanel::childGetScrollInterface(const LLString& id) void LLPanel::childSetValue(const LLString& id, LLSD value) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLView* child = getChild(id, true); if (child) { child->setValue(value); @@ -959,7 +932,7 @@ void LLPanel::childSetValue(const LLString& id, LLSD value) LLSD LLPanel::childGetValue(const LLString& id) const { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLView* child = getChild(id, true); if (child) { return child->getValue(); @@ -970,7 +943,7 @@ LLSD LLPanel::childGetValue(const LLString& id) const BOOL LLPanel::childSetTextArg(const LLString& id, const LLString& key, const LLStringExplicit& text) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { return child->setTextArg(key, text); @@ -980,7 +953,7 @@ BOOL LLPanel::childSetTextArg(const LLString& id, const LLString& key, const LLS BOOL LLPanel::childSetLabelArg(const LLString& id, const LLString& key, const LLStringExplicit& text) { - LLView* child = getChildByName(id, true); + LLView* child = getChild(id); if (child) { return child->setLabelArg(key, text); @@ -1000,7 +973,7 @@ BOOL LLPanel::childSetToolTipArg(const LLString& id, const LLString& key, const void LLPanel::childSetMinValue(const LLString& id, LLSD min_value) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { child->setMinValue(min_value); @@ -1009,7 +982,7 @@ void LLPanel::childSetMinValue(const LLString& id, LLSD min_value) void LLPanel::childSetMaxValue(const LLString& id, LLSD max_value) { - LLUICtrl* child = (LLUICtrl*)getChildByName(id, true); + LLUICtrl* child = getChild(id, true); if (child) { child->setMaxValue(max_value); @@ -1018,16 +991,16 @@ void LLPanel::childSetMaxValue(const LLString& id, LLSD max_value) void LLPanel::childShowTab(const LLString& id, const LLString& tabname, bool visible) { - LLTabContainerCommon* child = LLUICtrlFactory::getTabContainerByName(this, id); + LLTabContainer* child = LLUICtrlFactory::getTabContainerByName(this, id); if (child) { child->selectTabByName(tabname); } } -LLPanel *LLPanel::childGetVisibleTab(const LLString& id) +LLPanel *LLPanel::childGetVisibleTab(const LLString& id) const { - LLTabContainerCommon* child = LLUICtrlFactory::getTabContainerByName(this, id); + LLTabContainer* child = LLUICtrlFactory::getTabContainerByName(this, id); if (child) { return child->getCurrentPanel(); @@ -1037,7 +1010,7 @@ LLPanel *LLPanel::childGetVisibleTab(const LLString& id) void LLPanel::childSetTabChangeCallback(const LLString& id, const LLString& tabname, void (*on_tab_clicked)(void*, bool), void *userdata) { - LLTabContainerCommon* child = LLUICtrlFactory::getTabContainerByName(this, id); + LLTabContainer* child = LLUICtrlFactory::getTabContainerByName(this, id); if (child) { LLPanel *panel = child->getPanelByName(tabname); @@ -1049,11 +1022,6 @@ void LLPanel::childSetTabChangeCallback(const LLString& id, const LLString& tabn } } -void LLPanel::childSetText(const LLString& id, const LLStringExplicit& text) -{ - childSetValue(id, LLSD(text)); -} - void LLPanel::childSetKeystrokeCallback(const LLString& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data) { LLLineEditor* child = LLUICtrlFactory::getLineEditorByName(this, id); @@ -1076,11 +1044,6 @@ void LLPanel::childSetPrevalidate(const LLString& id, BOOL (*func)(const LLWStri } } -LLString LLPanel::childGetText(const LLString& id) -{ - return childGetValue(id).asString(); -} - void LLPanel::childSetWrappedText(const LLString& id, const LLString& text, bool visible) { LLTextBox* child = (LLTextBox*)getCtrlByNameAndType(id, WIDGET_TYPE_TEXT_BOX); @@ -1111,7 +1074,7 @@ void LLPanel::childSetActionTextbox(const LLString& id, void(*function)(void*)) void LLPanel::childSetControlName(const LLString& id, const LLString& control_name) { - LLView* view = getChildByName(id, TRUE); + LLView* view = getChild(id); if (view) { view->setControlName(control_name, NULL); @@ -1161,7 +1124,7 @@ void LLPanel::storeRectControl() { if( !mRectControl.empty() ) { - LLUI::sConfigGroup->setRect( mRectControl, mRect ); + LLUI::sConfigGroup->setRect( mRectControl, getRect() ); } } @@ -1231,6 +1194,19 @@ LLLayoutStack::~LLLayoutStack() std::for_each(mPanels.begin(), mPanels.end(), DeletePointer()); } +// virtual +EWidgetType LLLayoutStack::getWidgetType() const +{ + return WIDGET_TYPE_LAYOUT_STACK; +} + +// virtual +LLString LLLayoutStack::getWidgetTag() const +{ + return LL_LAYOUT_STACK_TAG; +} + + void LLLayoutStack::draw() { updateLayout(); @@ -1343,23 +1319,13 @@ LLView* LLLayoutStack::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactor return layout_stackp; } -S32 LLLayoutStack::getMinWidth() -{ - return mMinWidth; -} - -S32 LLLayoutStack::getMinHeight() -{ - return mMinHeight; -} - S32 LLLayoutStack::getDefaultHeight(S32 cur_height) { // if we are spanning our children (crude upward propagation of size) // then don't enforce our size on our children if (mOrientation == HORIZONTAL) { - cur_height = llmax(mMinHeight, mRect.getHeight()); + cur_height = llmax(mMinHeight, getRect().getHeight()); } return cur_height; @@ -1371,7 +1337,7 @@ S32 LLLayoutStack::getDefaultWidth(S32 cur_width) // then don't enforce our size on our children if (mOrientation == VERTICAL) { - cur_width = llmax(mMinWidth, mRect.getWidth()); + cur_width = llmax(mMinWidth, getRect().getWidth()); } return cur_width; @@ -1497,15 +1463,15 @@ void LLLayoutStack::updateLayout(BOOL force_resize) S32 pixels_to_distribute; if (mOrientation == HORIZONTAL) { - pixels_to_distribute = mRect.getWidth() - total_width; + pixels_to_distribute = getRect().getWidth() - total_width; } else //VERTICAL { - pixels_to_distribute = mRect.getHeight() - total_height; + pixels_to_distribute = getRect().getHeight() - total_height; } S32 cur_x = 0; - S32 cur_y = mRect.getHeight(); + S32 cur_y = getRect().getHeight(); for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { @@ -1643,18 +1609,19 @@ void LLLayoutStack::updateLayout(BOOL force_resize) if (force_resize == FALSE // layout did not complete by reaching target position && ((mOrientation == VERTICAL && cur_y != -mPanelSpacing) - || (mOrientation == HORIZONTAL && cur_x != mRect.getWidth() + mPanelSpacing))) + || (mOrientation == HORIZONTAL && cur_x != getRect().getWidth() + mPanelSpacing))) { // do another layout pass with all stacked elements contributing // even those that don't usually resize llassert_always(force_resize == FALSE); updateLayout(TRUE); } -} +} // end LLLayoutStack::updateLayout -LLLayoutStack::LLEmbeddedPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) + +LLLayoutStack::LLEmbeddedPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const { - e_panel_list_t::iterator panel_it; + e_panel_list_t::const_iterator panel_it; for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { if ((*panel_it)->mPanel == panelp) diff --git a/linden/indra/llui/llpanel.h b/linden/indra/llui/llpanel.h index aeba6d9..e0f48ca 100644 --- a/linden/indra/llui/llpanel.h +++ b/linden/indra/llui/llpanel.h @@ -33,10 +33,11 @@ #ifndef LL_LLPANEL_H #define LL_LLPANEL_H -// Opaque view with a background and a border. Can contain LLUICtrls. #include "llcallbackmap.h" #include "lluictrl.h" +#include "llbutton.h" +#include "lllineeditor.h" #include "llviewborder.h" #include "lluistring.h" #include "v4color.h" @@ -47,39 +48,26 @@ const S32 LLPANEL_BORDER_WIDTH = 1; const BOOL BORDER_YES = TRUE; const BOOL BORDER_NO = FALSE; -class LLViewerImage; -class LLUUID; -class LLCheckBoxCtrl; -class LLComboBox; -class LLIconCtrl; -class LLLineEditor; -class LLRadioGroup; -class LLScrollListCtrl; -class LLSliderCtrl; -class LLSpinCtrl; -class LLTextBox; -class LLTextEditor; - -class LLAlertInfo + +struct LLAlertInfo { -public: LLString mLabel; LLString::format_map_t mArgs; - LLAlertInfo(LLString label, LLString::format_map_t args) - : mLabel(label), mArgs(args) { } - - LLAlertInfo() { } + LLAlertInfo(LLString label, LLString::format_map_t args) : mLabel(label), mArgs(args) { } + LLAlertInfo(){} }; -class LLPanel : public LLUICtrl + +/* + * General purpose concrete view base class. + * Transparent or opaque, + * With or without border, + * Can contain LLUICtrls. + */ +class LLPanel : public LLUICtrl { public: - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; - - // defaults to TRUE - virtual BOOL isPanel(); // minimal constructor for data-driven initialization LLPanel(); @@ -89,34 +77,46 @@ public: LLPanel(const LLString& name, const LLRect& rect, BOOL bordered = TRUE); // Position and size are saved to rect_control - LLPanel(const LLString& name, const LLString& rect_control, BOOL bordered = TRUE); + LLPanel(const LLString& name, const LLString& rect_control, BOOL bordered = TRUE); + + /*virtual*/ ~LLPanel(); + + // LLView interface + /*virtual*/ EWidgetType getWidgetType() const; + /*virtual*/ LLString getWidgetTag() const; + /*virtual*/ BOOL isPanel() const; + /*virtual*/ void draw(); + /*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent ); + /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ); + /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; + // From LLFocusableElement + /*virtual*/ void setFocus( BOOL b ); + + // New virtuals + virtual void refresh(); // called in setFocus() + virtual BOOL postBuild(); + virtual void clearCtrls(); // overridden in LLPanelObject and LLPanelVolume + + // Border controls void addBorder( LLViewBorder::EBevel border_bevel = LLViewBorder::BEVEL_OUT, LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE, S32 border_thickness = LLPANEL_BORDER_WIDTH ); - - void removeBorder(); - - virtual ~LLPanel(); - virtual void draw(); - virtual void refresh(); // called in setFocus() - virtual void setFocus( BOOL b ); - void setFocusRoot(BOOL b) { mIsFocusRoot = b; } - virtual BOOL handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ); - virtual BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent ); - virtual BOOL postBuild(); + void removeBorder(); + BOOL hasBorder() const { return mBorder != NULL; } + void setBorderVisible( BOOL b ); void requires(LLString name, EWidgetType type = WIDGET_TYPE_DONTCARE); - BOOL checkRequirements(); - - static void alertXml(LLString label, LLString::format_map_t args = LLString::format_map_t()); - static BOOL nextAlert(LLAlertInfo &alert); + BOOL checkRequirements() const; - void setBackgroundColor( const LLColor4& color ); - LLColor4 getBackgroundColor(); - void setTransparentColor(const LLColor4& color); + void setBackgroundColor( const LLColor4& color ) { mBgColorOpaque = color; } + const LLColor4& getBackgroundColor() const { return mBgColorOpaque; } + void setTransparentColor(const LLColor4& color) { mBgColorAlpha = color; } + const LLColor4& getTransparentColor() const { return mBgColorAlpha; } void setBackgroundVisible( BOOL b ) { mBgVisible = b; } + BOOL isBackgroundVisible() const { return mBgVisible; } void setBackgroundOpaque(BOOL b) { mBgOpaque = b; } + BOOL isBackgroundOpaque() const { return mBgOpaque; } void setDefaultBtn(LLButton* btn = NULL); void setDefaultBtn(const LLString& id); void updateDefaultBtn(); @@ -124,37 +124,28 @@ public: LLString getLabel() const { return mLabel; } void setRectControl(const LLString& rect_control) { mRectControl.assign(rect_control); } + const LLString& getRectControl() const { return mRectControl; } void storeRectControl(); - - void setBorderVisible( BOOL b ); void setCtrlsEnabled(BOOL b); - virtual void clearCtrls(); - - LLViewHandle getHandle() { return mViewHandle; } - S32 getLastTabGroup() { return mLastTabGroup; } + LLHandle getHandle() const { return mPanelHandle; } - LLView* getCtrlByNameAndType(const LLString& name, EWidgetType type); + S32 getLastTabGroup() const { return mLastTabGroup; } - static LLPanel* getPanelByHandle(LLViewHandle handle); + LLUICtrl* getCtrlByNameAndType(const LLString& name, EWidgetType type) const; - virtual const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; } + const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; } - virtual LLXMLNodePtr getXML(bool save_children = true) const; - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); void initChildrenXML(LLXMLNodePtr node, LLUICtrlFactory* factory); void setPanelParameters(LLXMLNodePtr node, LLView *parentp); - LLString getFormattedUIString(const LLString& name, const LLString::format_map_t& args = LLUIString::sNullArgs) const; + LLString getString(const LLString& name, const LLString::format_map_t& args = LLUIString::sNullArgs) const; LLUIString getUIString(const LLString& name) const; // ** Wrappers for setting child properties by name ** -TomY - // Override to set not found list - virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; - // LLView void childSetVisible(const LLString& name, bool visible); void childShow(const LLString& name) { childSetVisible(name, true); } @@ -183,9 +174,9 @@ public: void childSetColor(const LLString& id, const LLColor4& color); - LLCtrlSelectionInterface* childGetSelectionInterface(const LLString& id); - LLCtrlListInterface* childGetListInterface(const LLString& id); - LLCtrlScrollInterface* childGetScrollInterface(const LLString& id); + LLCtrlSelectionInterface* childGetSelectionInterface(const LLString& id) const; + LLCtrlListInterface* childGetListInterface(const LLString& id) const; + LLCtrlScrollInterface* childGetScrollInterface(const LLString& id) const; // This is the magic bullet for data-driven UI void childSetValue(const LLString& id, LLSD value); @@ -197,21 +188,21 @@ public: BOOL childSetLabelArg(const LLString& id, const LLString& key, const LLStringExplicit& text); BOOL childSetToolTipArg(const LLString& id, const LLString& key, const LLStringExplicit& text); - // LLSlider / LLSpinCtrl + // LLSlider / LLMultiSlider / LLSpinCtrl void childSetMinValue(const LLString& id, LLSD min_value); void childSetMaxValue(const LLString& id, LLSD max_value); // LLTabContainer void childShowTab(const LLString& id, const LLString& tabname, bool visible = true); - LLPanel *childGetVisibleTab(const LLString& id); + LLPanel *childGetVisibleTab(const LLString& id) const; void childSetTabChangeCallback(const LLString& id, const LLString& tabname, void (*on_tab_clicked)(void*, bool), void *userdata); // LLTextBox void childSetWrappedText(const LLString& id, const LLString& text, bool visible = true); // LLTextBox/LLTextEditor/LLLineEditor - void childSetText(const LLString& id, const LLStringExplicit& text); - LLString childGetText(const LLString& id); + void childSetText(const LLString& id, const LLStringExplicit& text) { childSetValue(id, LLSD(text)); } + LLString childGetText(const LLString& id) const { return childGetValue(id).asString(); } // LLLineEditor void childSetKeystrokeCallback(const LLString& id, void (*keystroke_callback)(LLLineEditor* caller, void* user_data), void *user_data); @@ -226,16 +217,23 @@ public: void childNotFound(const LLString& id) const; void childDisplayNotFound(); - typedef std::queue alert_queue_t; - static alert_queue_t sAlertQueue; + static void alertXml(LLString label, LLString::format_map_t args = LLString::format_map_t()); + static BOOL nextAlert(LLAlertInfo &alert); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + +protected: + // Override to set not found list + LLButton* getDefaultButton() { return mDefaultBtn; } + LLCallbackMap::map_t mFactoryMap; - typedef std::map ui_string_map_t; + // Override to set not found list: + virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; private: - // common constructor + // common construction logic void init(); - -protected: + + // From LLView virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group ); virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group); @@ -252,18 +250,20 @@ protected: BOOL mBgOpaque; LLViewBorder* mBorder; LLButton* mDefaultBtn; - LLCallbackMap::map_t mFactoryMap; LLString mLabel; S32 mLastTabGroup; + LLRootHandle mPanelHandle; + typedef std::map ui_string_map_t; ui_string_map_t mUIStrings; typedef std::map requirements_map_t; requirements_map_t mRequirements; - typedef std::map panel_map_t; - static panel_map_t sPanelMap; -}; + typedef std::queue alert_queue_t; + static alert_queue_t sAlertQueue; +}; // end class LLPanel + class LLLayoutStack : public LLView { @@ -281,37 +281,33 @@ public: /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; /*virtual*/ void removeCtrl(LLUICtrl* ctrl); - virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_LAYOUT_STACK; } - virtual LLString getWidgetTag() const { return LL_LAYOUT_STACK_TAG; } + virtual EWidgetType getWidgetType() const; + virtual LLString getWidgetTag() const; static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - S32 getMinWidth(); - S32 getMinHeight(); + S32 getMinWidth() const { return mMinWidth; } + S32 getMinHeight() const { return mMinHeight; } void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, S32 index = S32_MAX); void removePanel(LLPanel* panel); void updateLayout(BOOL force_resize = FALSE); -protected: - struct LLEmbeddedPanel; - - LLEmbeddedPanel* findEmbeddedPanel(LLPanel* panelp); +private: void calcMinExtents(); - S32 getMinStackSize(); - S32 getCurStackSize(); S32 getDefaultHeight(S32 cur_height); S32 getDefaultWidth(S32 cur_width); -protected: - eLayoutOrientation mOrientation; + const eLayoutOrientation mOrientation; + struct LLEmbeddedPanel; typedef std::vector e_panel_list_t; e_panel_list_t mPanels; + LLEmbeddedPanel* findEmbeddedPanel(LLPanel* panelp) const; S32 mMinWidth; S32 mMinHeight; S32 mPanelSpacing; -}; +}; // end class LLLayoutStack #endif diff --git a/linden/indra/llui/llradiogroup.cpp b/linden/indra/llui/llradiogroup.cpp index dad1941..039fe81 100644 --- a/linden/indra/llui/llradiogroup.cpp +++ b/linden/indra/llui/llradiogroup.cpp @@ -29,9 +29,6 @@ * $/LicenseInfo$ */ -// An invisible view containing multiple mutually exclusive toggling -// buttons (usually radio buttons). Automatically handles the mutex -// condition by highlighting only one button at a time. #include "linden_common.h" @@ -45,6 +42,7 @@ #include "llui.h" #include "llfocusmgr.h" + LLRadioGroup::LLRadioGroup(const LLString& name, const LLRect& rect, const LLString& control_name, LLUICtrlCallback callback, @@ -73,7 +71,7 @@ void LLRadioGroup::init(BOOL border) if (border) { addChild( new LLViewBorder( "radio group border", - LLRect(0, mRect.getHeight(), mRect.getWidth(), 0), + LLRect(0, getRect().getHeight(), getRect().getWidth(), 0), LLViewBorder::BEVEL_NONE, LLViewBorder::STYLE_LINE, 1 ) ); @@ -146,11 +144,6 @@ void LLRadioGroup::setIndexEnabled(S32 index, BOOL enabled) } } -S32 LLRadioGroup::getSelectedIndex() const -{ - return mSelectedIndex; -} - BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event) { if (index < 0 || index >= (S32)mRadioButtons.size()) @@ -245,7 +238,9 @@ void LLRadioGroup::draw() radio->setValue( selected ); if (take_focus && selected && !gFocusMgr.childHasKeyboardFocus(radio)) { - radio->focusFirstItem(); + // don't flash keyboard focus when navigating via keyboard + BOOL DONT_FLASH = FALSE; + radio->focusFirstItem(FALSE, DONT_FLASH); } current_button++; } @@ -450,12 +445,12 @@ BOOL LLRadioGroup::setCurrentByID( const LLUUID& id ) return FALSE; } -LLUUID LLRadioGroup::getCurrentID() +LLUUID LLRadioGroup::getCurrentID() const { return LLUUID::null; } -BOOL LLRadioGroup::setSelectedByValue(LLSD value, BOOL selected) +BOOL LLRadioGroup::setSelectedByValue(const LLSD& value, BOOL selected) { S32 idx = 0; std::string value_string = value.asString(); @@ -478,7 +473,7 @@ LLSD LLRadioGroup::getSelectedValue() return getValue(); } -BOOL LLRadioGroup::isSelected(LLSD value) +BOOL LLRadioGroup::isSelected(const LLSD& value) const { S32 idx = 0; std::string value_string = value.asString(); @@ -508,13 +503,6 @@ BOOL LLRadioGroup::operateOnAll(EOperation op) } -LLRadioCtrl::LLRadioCtrl(const LLString& name, const LLRect& rect, const LLString& label, - const LLFontGL* font, void (*commit_callback)(LLUICtrl*, void*), void* callback_userdata) : - LLCheckBoxCtrl(name, rect, label, font, commit_callback, callback_userdata, FALSE, RADIO_STYLE) -{ - setTabStop(FALSE); -} - LLRadioCtrl::~LLRadioCtrl() { } diff --git a/linden/indra/llui/llradiogroup.h b/linden/indra/llui/llradiogroup.h index aed8de2..87591a4 100644 --- a/linden/indra/llui/llradiogroup.h +++ b/linden/indra/llui/llradiogroup.h @@ -29,10 +29,6 @@ * $/LicenseInfo$ */ -// An invisible view containing multiple mutually exclusive toggling -// buttons (usually radio buttons). Automatically handles the mutex -// condition by highlighting only one button at a time. - #ifndef LL_LLRADIOGROUP_H #define LL_LLRADIOGROUP_H @@ -40,21 +36,30 @@ #include "llcheckboxctrl.h" #include "llctrlselectioninterface.h" -class LLFontGL; -// Radio controls are checkbox controls with use_radio_style true +/* + * A checkbox control with use_radio_style == true. + */ class LLRadioCtrl : public LLCheckBoxCtrl { public: - LLRadioCtrl(const LLString& name, const LLRect& rect, const LLString& label, - const LLFontGL* font = NULL, - void (*commit_callback)(LLUICtrl*, void*) = NULL, - void* callback_userdata = NULL); + LLRadioCtrl(const LLString& name, const LLRect& rect, const LLString& label, const LLFontGL* font = NULL, + void (*commit_callback)(LLUICtrl*, void*) = NULL, void* callback_userdata = NULL) : + LLCheckBoxCtrl(name, rect, label, font, commit_callback, callback_userdata, FALSE, RADIO_STYLE) + { + setTabStop(FALSE); + } /*virtual*/ ~LLRadioCtrl(); /*virtual*/ void setValue(const LLSD& value); }; + +/* + * An invisible view containing multiple mutually exclusive toggling + * buttons (usually radio buttons). Automatically handles the mutex + * condition by highlighting only one button at a time. + */ class LLRadioGroup : public LLUICtrl, public LLCtrlSelectionInterface { @@ -88,7 +93,7 @@ public: void setIndexEnabled(S32 index, BOOL enabled); // return the index value of the selected item - S32 getSelectedIndex() const; + S32 getSelectedIndex() const { return mSelectedIndex; } // set the index value programatically BOOL setSelectedIndex(S32 index, BOOL from_event = FALSE); @@ -97,8 +102,7 @@ public: virtual void setValue(const LLSD& value ); virtual LLSD getValue() const; - // Draw the group, but also fix the highlighting based on the - // control. + // Draw the group, but also fix the highlighting based on the control. void draw(); // You must use this method to add buttons to a radio group. @@ -106,8 +110,7 @@ public: // correctly. LLRadioCtrl* addRadioButton(const LLString& name, const LLString& label, const LLRect& rect, const LLFontGL* font); LLRadioCtrl* getRadioButton(const S32& index) { return mRadioButtons[index]; } - // Update the control as needed. Userdata must be a pointer to the - // button. + // Update the control as needed. Userdata must be a pointer to the button. static void onClickButton(LLUICtrl* radio, void* userdata); //======================================================================== @@ -121,14 +124,14 @@ public: /*virtual*/ BOOL selectItemRange( S32 first, S32 last ) { return setSelectedIndex(first); } /*virtual*/ S32 getFirstSelectedIndex() const { return getSelectedIndex(); } /*virtual*/ BOOL setCurrentByID( const LLUUID& id ); - /*virtual*/ LLUUID getCurrentID(); // LLUUID::null if no items in menu - /*virtual*/ BOOL setSelectedByValue(LLSD value, BOOL selected); + /*virtual*/ LLUUID getCurrentID() const; // LLUUID::null if no items in menu + /*virtual*/ BOOL setSelectedByValue(const LLSD& value, BOOL selected); /*virtual*/ LLSD getSelectedValue(); - /*virtual*/ BOOL isSelected(LLSD value); + /*virtual*/ BOOL isSelected(const LLSD& value) const; /*virtual*/ BOOL operateOnSelection(EOperation op); /*virtual*/ BOOL operateOnAll(EOperation op); -protected: +private: // protected function shared by the two constructors. void init(BOOL border); diff --git a/linden/indra/llui/llresizebar.cpp b/linden/indra/llui/llresizebar.cpp index e6ce03b..b4933bd 100644 --- a/linden/indra/llui/llresizebar.cpp +++ b/linden/indra/llui/llresizebar.cpp @@ -33,8 +33,6 @@ #include "llresizebar.h" -//#include "llviewermenu.h" -//#include "llviewerimagelist.h" #include "llmath.h" #include "llui.h" #include "llmenugl.h" @@ -87,7 +85,7 @@ LLResizeBar::LLResizeBar( const LLString& name, LLView* resizing_view, const LLR BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask) { - if( mEnabled ) + if( getEnabled() ) { // Route future Mouse messages here preemptively. (Release on mouse up.) // No handler needed for focus lost since this clas has no state that depends on it. @@ -119,15 +117,6 @@ BOOL LLResizeBar::handleMouseUp(S32 x, S32 y, MASK mask) return handled; } -EWidgetType LLResizeBar::getWidgetType() const -{ - return WIDGET_TYPE_RESIZE_BAR; -} - -LLString LLResizeBar::getWidgetTag() const -{ - return LL_RESIZE_BAR_TAG; -} BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask) { @@ -267,5 +256,34 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask) } return handled; +} // end LLResizeBar::handleHover + +BOOL LLResizeBar::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + LLRect orig_rect = mResizingView->getRect(); + LLRect scaled_rect = orig_rect; + + if (mSnappingEnabled) + { + switch( mSide ) + { + case LEFT: + mResizingView->findSnapEdge(scaled_rect.mLeft, LLCoordGL(0, 0), SNAP_LEFT, SNAP_PARENT_AND_SIBLINGS, S32_MAX); + break; + case TOP: + mResizingView->findSnapEdge(scaled_rect.mTop, LLCoordGL(0, 0), SNAP_TOP, SNAP_PARENT_AND_SIBLINGS, S32_MAX); + break; + case RIGHT: + mResizingView->findSnapEdge(scaled_rect.mRight, LLCoordGL(0, 0), SNAP_RIGHT, SNAP_PARENT_AND_SIBLINGS, S32_MAX); + break; + case BOTTOM: + mResizingView->findSnapEdge(scaled_rect.mBottom, LLCoordGL(0, 0), SNAP_BOTTOM, SNAP_PARENT_AND_SIBLINGS, S32_MAX); + break; + } + } + + mResizingView->reshape(scaled_rect.getWidth(), scaled_rect.getHeight()); + mResizingView->setOrigin(scaled_rect.mLeft, scaled_rect.mBottom); + return TRUE; } diff --git a/linden/indra/llui/llresizebar.h b/linden/indra/llui/llresizebar.h index 11fca9d..5446811 100644 --- a/linden/indra/llui/llresizebar.h +++ b/linden/indra/llui/llresizebar.h @@ -42,18 +42,19 @@ public: LLResizeBar(const LLString& name, LLView* resizing_view, const LLRect& rect, S32 min_size, S32 max_size, Side side ); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_RESIZE_BAR; } + virtual LLString getWidgetTag() const { return LL_RESIZE_BAR_TAG; } // virtual void draw(); No appearance virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); void setResizeLimits( S32 min_size, S32 max_size ) { mMinSize = min_size; mMaxSize = max_size; } void setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; } -protected: +private: S32 mDragLastScreenX; S32 mDragLastScreenY; S32 mLastMouseScreenX; @@ -61,13 +62,11 @@ protected: LLCoordGL mLastMouseDir; S32 mMinSize; S32 mMaxSize; - Side mSide; + const Side mSide; BOOL mSnappingEnabled; LLView* mResizingView; }; -const S32 RESIZE_BAR_HEIGHT = 3; - #endif // LL_RESIZEBAR_H diff --git a/linden/indra/llui/llresizehandle.cpp b/linden/indra/llui/llresizehandle.cpp index 739d583..d3e066b 100644 --- a/linden/indra/llui/llresizehandle.cpp +++ b/linden/indra/llui/llresizehandle.cpp @@ -75,23 +75,13 @@ LLResizeHandle::LLResizeHandle( const LLString& name, const LLRect& rect, S32 mi setSaveToXML(FALSE); } -EWidgetType LLResizeHandle::getWidgetType() const -{ - return WIDGET_TYPE_RESIZE_HANDLE; -} - -LLString LLResizeHandle::getWidgetTag() const -{ - return LL_RESIZE_HANDLE_TAG; -} - BOOL LLResizeHandle::handleMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; if( getVisible() && pointInHandle(x, y) ) { handled = TRUE; - if( mEnabled ) + if( getEnabled() ) { // Route future Mouse messages here preemptively. (Release on mouse up.) // No handler needed for focus lost since this clas has no state that depends on it. @@ -292,10 +282,12 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask) handled = TRUE; } - else - if( getVisible() && pointInHandle( x, y ) ) + else // don't have mouse capture { - handled = TRUE; + if( getVisible() && pointInHandle( x, y ) ) + { + handled = TRUE; + } } if( handled ) @@ -314,7 +306,8 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask) } return handled; -} +} // end handleHover + // assumes GL state is set for 2D void LLResizeHandle::draw() @@ -330,8 +323,8 @@ BOOL LLResizeHandle::pointInHandle( S32 x, S32 y ) { if( pointInView(x, y) ) { - const S32 TOP_BORDER = (mRect.getHeight() - RESIZE_BORDER_WIDTH); - const S32 RIGHT_BORDER = (mRect.getWidth() - RESIZE_BORDER_WIDTH); + const S32 TOP_BORDER = (getRect().getHeight() - RESIZE_BORDER_WIDTH); + const S32 RIGHT_BORDER = (getRect().getWidth() - RESIZE_BORDER_WIDTH); switch( mCorner ) { diff --git a/linden/indra/llui/llresizehandle.h b/linden/indra/llui/llresizehandle.h index 863ce70..77ebcb9 100644 --- a/linden/indra/llui/llresizehandle.h +++ b/linden/indra/llui/llresizehandle.h @@ -46,8 +46,8 @@ public: LLResizeHandle(const LLString& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner = RIGHT_BOTTOM ); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_RESIZE_HANDLE; } + virtual LLString getWidgetTag() const { return LL_RESIZE_HANDLE_TAG; } virtual void draw(); virtual BOOL handleHover(S32 x, S32 y, MASK mask); @@ -56,10 +56,9 @@ public: void setResizeLimits( S32 min_width, S32 min_height ) { mMinWidth = min_width; mMinHeight = min_height; } -protected: +private: BOOL pointInHandle( S32 x, S32 y ); -protected: S32 mDragLastScreenX; S32 mDragLastScreenY; S32 mLastMouseScreenX; @@ -68,7 +67,7 @@ protected: LLPointer mImage; S32 mMinWidth; S32 mMinHeight; - ECorner mCorner; + const ECorner mCorner; }; const S32 RESIZE_HANDLE_HEIGHT = 16; diff --git a/linden/indra/llui/llresmgr.h b/linden/indra/llui/llresmgr.h index b851795..810d386 100644 --- a/linden/indra/llui/llresmgr.h +++ b/linden/indra/llui/llresmgr.h @@ -29,8 +29,6 @@ * $/LicenseInfo$ */ -// NOTE: this is a MINIMAL implementation. The interface will remain, but the implementation will -// (when the time is right) become dynamic and probably use external files. #ifndef LL_LLRESMGR_H #define LL_LLRESMGR_H @@ -157,11 +155,10 @@ public: LLLocale(const LLString& locale_string); virtual ~LLLocale(); -public: static const LLString USER_LOCALE; static const LLString SYSTEM_LOCALE; -protected: +private: LLString mPrevLocaleString; }; diff --git a/linden/indra/llui/llrootview.cpp b/linden/indra/llui/llrootview.cpp index 1580f99..cea9ded 100644 --- a/linden/indra/llui/llrootview.cpp +++ b/linden/indra/llui/llrootview.cpp @@ -36,14 +36,4 @@ LLRootView::LLRootView(const LLString& name, const LLRect& rect, BOOL mouse_opaq : LLView(name,rect,mouse_opaque,follows) { } -// virtual -EWidgetType LLRootView::getWidgetType() const -{ - return WIDGET_TYPE_ROOT_VIEW; -} - -// virtual -LLString LLRootView::getWidgetTag() const -{ - return LL_ROOT_VIEW_TAG; -} +// pretty exciting file, eh? diff --git a/linden/indra/llui/llrootview.h b/linden/indra/llui/llrootview.h index 13037f0..5f130b9 100644 --- a/linden/indra/llui/llrootview.h +++ b/linden/indra/llui/llrootview.h @@ -39,8 +39,8 @@ class LLRootView : public LLView public: LLRootView(const LLString& name, const LLRect& rect, BOOL mouse_opaque, U32 follows=FOLLOWS_NONE); - /*virtual*/ EWidgetType getWidgetType() const; - /*virtual*/ LLString getWidgetTag() const; + /*virtual*/ EWidgetType getWidgetType() const { return WIDGET_TYPE_ROOT_VIEW; } + /*virtual*/ LLString getWidgetTag() const { return LL_ROOT_VIEW_TAG; } }; #endif diff --git a/linden/indra/llui/llscrollbar.cpp b/linden/indra/llui/llscrollbar.cpp index ec46551..cf64742 100644 --- a/linden/indra/llui/llscrollbar.cpp +++ b/linden/indra/llui/llscrollbar.cpp @@ -46,6 +46,7 @@ #include "llwindow.h" #include "llglheaders.h" #include "llcontrol.h" +#include "llglimmediate.h" LLScrollbar::LLScrollbar( const LLString& name, LLRect rect, @@ -92,7 +93,7 @@ LLScrollbar::LLScrollbar( if( LLScrollbar::VERTICAL == mOrientation ) { - line_up_rect.setLeftTopAndSize( 0, mRect.getHeight(), SCROLLBAR_SIZE, SCROLLBAR_SIZE ); + line_up_rect.setLeftTopAndSize( 0, getRect().getHeight(), SCROLLBAR_SIZE, SCROLLBAR_SIZE ); line_up_img="UIImgBtnScrollUpOutUUID"; line_up_selected_img="UIImgBtnScrollUpInUUID"; @@ -107,7 +108,7 @@ LLScrollbar::LLScrollbar( line_up_img="UIImgBtnScrollLeftOutUUID"; line_up_selected_img="UIImgBtnScrollLeftInUUID"; - line_down_rect.setOriginAndSize( mRect.getWidth() - SCROLLBAR_SIZE, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE ); + line_down_rect.setOriginAndSize( getRect().getWidth() - SCROLLBAR_SIZE, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE ); line_down_img="UIImgBtnScrollRightOutUUID"; line_down_selected_img="UIImgBtnScrollRightInUUID"; } @@ -210,7 +211,7 @@ void LLScrollbar::updateThumbRect() const S32 THUMB_MIN_LENGTH = 16; - S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? mRect.getWidth() : mRect.getHeight(); + S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? getRect().getWidth() : getRect().getHeight(); S32 thumb_bg_length = window_length - 2 * SCROLLBAR_SIZE; S32 visible_lines = llmin( mDocSize, mPageSize ); S32 thumb_length = mDocSize ? llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH ) : thumb_bg_length; @@ -300,8 +301,8 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask) BOOL handled = FALSE; if( hasMouseCapture() ) { - S32 height = mRect.getHeight(); - S32 width = mRect.getWidth(); + S32 height = getRect().getHeight(); + S32 width = getRect().getWidth(); if( VERTICAL == mOrientation ) { @@ -408,13 +409,13 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask) mDocChanged = FALSE; return handled; -} +} // end handleHover BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks) { BOOL handled = FALSE; - if( getVisible() && mRect.localPointInRect( x, y ) ) + if( getVisible() && getRect().localPointInRect( x, y ) ) { if( getEnabled() ) { @@ -427,7 +428,7 @@ BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks) } BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, void *carge_data, EAcceptance *accept, LLString &tooltip_msg) + EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, LLString &tooltip_msg) { // enable this to get drag and drop to control scrollbars //if (!drop) @@ -436,7 +437,7 @@ BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, // S32 variable_lines = getDocPosMax(); // S32 pos = (VERTICAL == mOrientation) ? y : x; // S32 thumb_length = (VERTICAL == mOrientation) ? mThumbRect.getHeight() : mThumbRect.getWidth(); - // S32 thumb_track_length = (VERTICAL == mOrientation) ? (mRect.getHeight() - 2 * SCROLLBAR_SIZE) : (mRect.getWidth() - 2 * SCROLLBAR_SIZE); + // S32 thumb_track_length = (VERTICAL == mOrientation) ? (getRect().getHeight() - 2 * SCROLLBAR_SIZE) : (getRect().getWidth() - 2 * SCROLLBAR_SIZE); // S32 usable_track_length = thumb_track_length - thumb_length; // F32 ratio = (VERTICAL == mOrientation) ? F32(pos - SCROLLBAR_SIZE - thumb_length) / usable_track_length // : F32(pos - SCROLLBAR_SIZE) / usable_track_length; @@ -485,7 +486,7 @@ void LLScrollbar::draw() screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y); BOOL other_captor = gFocusMgr.getMouseCapture() && gFocusMgr.getMouseCapture() != this; - BOOL hovered = mEnabled && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y)); + BOOL hovered = getEnabled() && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y)); if (hovered) { mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f)); @@ -504,8 +505,8 @@ void LLScrollbar::draw() if (!rounded_rect_imagep) { gl_rect_2d(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0, - mOrientation == VERTICAL ? mRect.getHeight() - 2 * SCROLLBAR_SIZE : mRect.getHeight(), - mOrientation == HORIZONTAL ? mRect.getWidth() - 2 * SCROLLBAR_SIZE : mRect.getWidth(), + mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(), + mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(), mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, mTrackColor, TRUE); gl_rect_2d(mThumbRect, mThumbColor, TRUE); @@ -518,8 +519,8 @@ void LLScrollbar::draw() mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, 16, 16, - mOrientation == HORIZONTAL ? mRect.getWidth() - 2 * SCROLLBAR_SIZE : mRect.getWidth(), - mOrientation == VERTICAL ? mRect.getHeight() - 2 * SCROLLBAR_SIZE : mRect.getHeight(), + mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(), + mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(), rounded_rect_imagep, mTrackColor, TRUE); @@ -538,10 +539,10 @@ void LLScrollbar::draw() rounded_rect_imagep, mThumbColor ); if (mCurGlowStrength > 0.01f) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); gl_draw_scaled_image_with_border(mThumbRect.mLeft, mThumbRect.mBottom, 16, 16, mThumbRect.getWidth(), mThumbRect.getHeight(), rounded_rect_imagep, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength), TRUE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } } @@ -553,7 +554,8 @@ void LLScrollbar::draw() // Draw children LLView::draw(); } -} +} // end draw + void LLScrollbar::changeLine( S32 delta, BOOL update_thumb ) { @@ -579,21 +581,12 @@ void LLScrollbar::setValue(const LLSD& value) setDocPos((S32) value.asInteger()); } -EWidgetType LLScrollbar::getWidgetType() const -{ - return WIDGET_TYPE_SCROLLBAR; -} - -LLString LLScrollbar::getWidgetTag() const -{ - return LL_SCROLLBAR_TAG; -} BOOL LLScrollbar::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) { BOOL handled = FALSE; - if( getVisible() && mEnabled && !called_from_parent ) + if( getVisible() && getEnabled() && !called_from_parent ) { switch( key ) { @@ -661,3 +654,4 @@ void LLScrollbar::onLineDownBtnPressed( void* userdata ) self->changeLine( self->mStepSize, TRUE ); } + diff --git a/linden/indra/llui/llscrollbar.h b/linden/indra/llui/llscrollbar.h index 464c9c1..b4586c3 100644 --- a/linden/indra/llui/llscrollbar.h +++ b/linden/indra/llui/llscrollbar.h @@ -61,8 +61,9 @@ public: virtual ~LLScrollbar(); virtual void setValue(const LLSD& value); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SCROLLBAR; } + virtual LLString getWidgetTag() const { return LL_SCROLLBAR_TAG; } // Overrides from LLView virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); @@ -71,32 +72,33 @@ public: virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, void *carge_data, EAcceptance *accept, LLString &tooltip_msg); + EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, LLString &tooltip_msg); virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); virtual void draw(); - void setDocParams( S32 size, S32 pos ); - // How long the "document" is. void setDocSize( S32 size ); - S32 getDocSize() { return mDocSize; } + S32 getDocSize() const { return mDocSize; } // How many "lines" the "document" has scrolled. // 0 <= DocPos <= DocSize - DocVisibile void setDocPos( S32 pos ); - S32 getDocPos() { return mDocPos; } + S32 getDocPos() const { return mDocPos; } BOOL isAtBeginning(); BOOL isAtEnd(); + // Setting both at once. + void setDocParams( S32 size, S32 pos ); + // How many "lines" of the "document" is can appear on a page. void setPageSize( S32 page_size ); - S32 getPageSize() { return mPageSize; } + S32 getPageSize() const { return mPageSize; } // The farthest the document can be scrolled (top of the last page). - S32 getDocPosMax() { return llmax( 0, mDocSize - mPageSize); } + S32 getDocPosMax() const { return llmax( 0, mDocSize - mPageSize); } void pageUp(S32 overlap); void pageDown(S32 overlap); @@ -110,15 +112,15 @@ public: void setShadowColor( const LLColor4& color ) { mShadowColor = color; } void setOnScrollEndCallback(void (*callback)(void*), void* userdata) { mOnScrollEndCallback = callback; mOnScrollEndData = userdata;} -protected: + +private: void updateThumbRect(); void changeLine(S32 delta, BOOL update_thumb ); -protected: void (*mChangeCallback)( S32 new_pos, LLScrollbar* self, void* userdata ); void* mCallbackUserData; - ORIENTATION mOrientation; + const ORIENTATION mOrientation; S32 mDocSize; // Size of the document that the scrollbar is modeling. Units depend on the user. 0 <= mDocSize. S32 mDocPos; // Position within the doc that the scrollbar is modeling, in "lines" (user size) S32 mPageSize; // Maximum number of lines that can be seen at one time. diff --git a/linden/indra/llui/llscrollcontainer.cpp b/linden/indra/llui/llscrollcontainer.cpp index 8c8b40c..15b59d4 100644 --- a/linden/indra/llui/llscrollcontainer.cpp +++ b/linden/indra/llui/llscrollcontainer.cpp @@ -29,18 +29,11 @@ * $/LicenseInfo$ */ -//***************************************************************************** -// -// A view meant to encapsulate a clipped region which is -// scrollable. It automatically takes care of pixel perfect scrolling -// and cliipping, as well as turning the scrollbars on or off based on -// the width and height of the view you're scrolling. -// -//***************************************************************************** #include "linden_common.h" #include "llgl.h" +#include "llglimmediate.h" #include "llscrollcontainer.h" #include "llscrollbar.h" @@ -112,11 +105,11 @@ LLScrollableContainerView::LLScrollableContainerView( const LLString& name, cons void LLScrollableContainerView::init() { - LLRect border_rect( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 ); mBorder = new LLViewBorder( "scroll border", border_rect, LLViewBorder::BEVEL_IN ); addChild( mBorder ); - mInnerRect.set( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 ); mInnerRect.stretch( -mBorder->getBorderWidth() ); LLRect vertical_scroll_rect = mInnerRect; @@ -165,25 +158,6 @@ LLScrollableContainerView::~LLScrollableContainerView( void ) mScrolledView = NULL; } -/* -// scrollbar handlers -void LLScrollableContainerView::horizontalChange( S32 new_pos, - LLScrollbar* sb, - void* user_data ) -{ - LLScrollableContainerView* cont = reinterpret_cast(user_data); -// cont->scrollHorizontal( new_pos ); -} - - -void LLScrollableContainerView::verticalChange( S32 new_pos, LLScrollbar* sb, - void* user_data ) -{ - LLScrollableContainerView* cont = reinterpret_cast(user_data); -// cont->scrollVertical( new_pos ); -} -*/ - // internal scrollbar handlers // virtual void LLScrollableContainerView::scrollHorizontal( S32 new_pos ) @@ -215,7 +189,7 @@ void LLScrollableContainerView::reshape(S32 width, S32 height, { LLUICtrl::reshape( width, height, called_from_parent ); - mInnerRect.set( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 ); mInnerRect.stretch( -mBorder->getBorderWidth() ); if (mScrolledView) @@ -238,7 +212,7 @@ void LLScrollableContainerView::reshape(S32 width, S32 height, BOOL LLScrollableContainerView::handleKey( KEY key, MASK mask, BOOL called_from_parent ) { - if( getVisible() && mEnabled ) + if( getVisible() && getEnabled() ) { if( called_from_parent ) { @@ -278,7 +252,7 @@ BOOL LLScrollableContainerView::handleKey( KEY key, MASK mask, BOOL called_from_ BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks ) { - if( mEnabled ) + if( getEnabled() ) { for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) { @@ -295,7 +269,8 @@ BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks ) // Opaque return TRUE; } -BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) + +BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) const { if(mScrollbar[axis]->getVisible()) { @@ -315,6 +290,7 @@ BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContaine } return FALSE; } + BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, @@ -419,19 +395,19 @@ BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, LLString& msg, LLRec return TRUE; } -void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) +void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { const LLRect& rect = mScrolledView->getRect(); calcVisibleSize(rect, visible_width, visible_height, show_h_scrollbar, show_v_scrollbar); } -void LLScrollableContainerView::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) +void LLScrollableContainerView::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const { S32 doc_width = doc_rect.getWidth(); S32 doc_height = doc_rect.getHeight(); - *visible_width = mRect.getWidth() - 2 * mBorder->getBorderWidth(); - *visible_height = mRect.getHeight() - 2 * mBorder->getBorderWidth(); + *visible_width = getRect().getWidth() - 2 * mBorder->getBorderWidth(); + *visible_height = getRect().getHeight() - 2 * mBorder->getBorderWidth(); *show_v_scrollbar = FALSE; if( *visible_height < doc_height ) @@ -484,7 +460,7 @@ void LLScrollableContainerView::draw() if( mIsOpaque ) { LLGLSNoTexture no_texture; - glColor4fv( mBackgroundColor.mV ); + gGL.color4fv( mBackgroundColor.mV ); gl_rect_2d( mInnerRect ); } @@ -544,7 +520,7 @@ void LLScrollableContainerView::draw() drawDebugRect(); } } -} +} // end draw void LLScrollableContainerView::updateScroll() { @@ -560,9 +536,9 @@ void LLScrollableContainerView::updateScroll() S32 border_width = mBorder->getBorderWidth(); if( show_v_scrollbar ) { - if( doc_rect.mTop < mRect.getHeight() - border_width ) + if( doc_rect.mTop < getRect().getHeight() - border_width ) { - mScrolledView->translate( 0, mRect.getHeight() - border_width - doc_rect.mTop ); + mScrolledView->translate( 0, getRect().getHeight() - border_width - doc_rect.mTop ); } scrollVertical( mScrollbar[VERTICAL]->getDocPos() ); @@ -587,7 +563,7 @@ void LLScrollableContainerView::updateScroll() } else { - mScrolledView->translate( 0, mRect.getHeight() - border_width - doc_rect.mTop ); + mScrolledView->translate( 0, getRect().getHeight() - border_width - doc_rect.mTop ); mScrollbar[VERTICAL]->setVisible( FALSE ); mScrollbar[VERTICAL]->setDocPos( 0 ); @@ -626,7 +602,7 @@ void LLScrollableContainerView::updateScroll() mScrollbar[VERTICAL]->setDocSize( doc_height ); mScrollbar[VERTICAL]->setPageSize( visible_height ); -} +} // end updateScroll void LLScrollableContainerView::setBorderVisible(BOOL b) { @@ -723,7 +699,7 @@ void LLScrollableContainerView::goToBottom() mScrollbar[VERTICAL]->setDocPos(mScrollbar[VERTICAL]->getDocSize()); } -S32 LLScrollableContainerView::getBorderWidth() +S32 LLScrollableContainerView::getBorderWidth() const { if (mBorder) { @@ -803,7 +779,3 @@ LLView* LLScrollableContainerView::fromXML(LLXMLNodePtr node, LLView *parent, LL return ret; } - -///---------------------------------------------------------------------------- -/// Local function definitions -///---------------------------------------------------------------------------- diff --git a/linden/indra/llui/llscrollcontainer.h b/linden/indra/llui/llscrollcontainer.h index fb7198c..d512957 100644 --- a/linden/indra/llui/llscrollcontainer.h +++ b/linden/indra/llui/llscrollcontainer.h @@ -40,21 +40,18 @@ #include "llcoord.h" #include "llscrollbar.h" -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLScrollableContainerView -// -// A view meant to encapsulate a clipped region which is -// scrollable. It automatically takes care of pixel perfect scrolling -// and cliipping, as well as turning the scrollbars on or off based on -// the width and height of the view you're scrolling. -// -// This class is a decorator class. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLViewBorder; class LLUICtrlFactory; - +/***************************************************************************** + * + * A decorator view class meant to encapsulate a clipped region which is + * scrollable. It automatically takes care of pixel perfect scrolling + * and cliipping, as well as turning the scrollbars on or off based on + * the width and height of the view you're scrolling. + * + *****************************************************************************/ class LLScrollableContainerView : public LLUICtrl { public: @@ -70,32 +67,26 @@ public: const LLColor4& bg_color = LLColor4(0,0,0,0) ); virtual ~LLScrollableContainerView( void ); - void init(); - void setScrolledView(LLView* view) { mScrolledView = view; } virtual void setValue(const LLSD& value) { mInnerRect.setValue(value); } virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SCROLL_CONTAINER; } virtual LLString getWidgetTag() const { return LL_SCROLLABLE_CONTAINER_VIEW_TAG; } - // scrollbar handlers - static void horizontalChange( S32 new_pos, LLScrollbar* sb, void* user_data ); - static void verticalChange( S32 new_pos, LLScrollbar* sb, void* user_data ); - - void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ); - void calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ); + void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const; + void calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const; void setBorderVisible( BOOL b ); void scrollToShowRect( const LLRect& rect, const LLCoordGL& desired_offset ); void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; } - const LLRect& getScrolledViewRect() { return mScrolledView->getRect(); } + const LLRect& getScrolledViewRect() const { return mScrolledView->getRect(); } void pageUp(S32 overlap = 0); void pageDown(S32 overlap = 0); void goToTop(); void goToBottom(); - S32 getBorderWidth(); + S32 getBorderWidth() const; - BOOL needsToScroll(S32 x, S32 y, SCROLL_ORIENTATION axis); + BOOL needsToScroll(S32 x, S32 y, SCROLL_ORIENTATION axis) const; // LLView functionality virtual void reshape(S32 width, S32 height, BOOL called_from_parent); @@ -113,7 +104,9 @@ public: virtual LLXMLNodePtr getXML(bool save_children = true) const; static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); -protected: +private: + void init(); + // internal scrollbar handlers virtual void scrollHorizontal( S32 new_pos ); virtual void scrollVertical( S32 new_pos ); diff --git a/linden/indra/llui/llscrollingpanellist.cpp b/linden/indra/llui/llscrollingpanellist.cpp index a9d538e..8f85bc8 100644 --- a/linden/indra/llui/llscrollingpanellist.cpp +++ b/linden/indra/llui/llscrollingpanellist.cpp @@ -126,20 +126,6 @@ void LLScrollingPanelList::updatePanelVisiblilty() } } -void LLScrollingPanelList::setValue(const LLSD& value) -{ - -} - -EWidgetType LLScrollingPanelList::getWidgetType() const -{ - return WIDGET_TYPE_SCROLLING_PANEL_LIST; -} - -LLString LLScrollingPanelList::getWidgetTag() const -{ - return LL_SCROLLING_PANEL_LIST_TAG; -} void LLScrollingPanelList::draw() { @@ -165,9 +151,3 @@ LLView* LLScrollingPanelList::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtr return scrolling_panel_list; } -// virtual -LLXMLNodePtr LLScrollingPanelList::getXML(bool save_children) const -{ - LLXMLNodePtr node = LLUICtrl::getXML(); - return node; -} diff --git a/linden/indra/llui/llscrollingpanellist.h b/linden/indra/llui/llscrollingpanellist.h index 84dc7f9..6fe35cd 100644 --- a/linden/indra/llui/llscrollingpanellist.h +++ b/linden/indra/llui/llscrollingpanellist.h @@ -35,30 +35,31 @@ #include "llview.h" #include "llpanel.h" -// virtual class for scrolling panels +/* + * Pure virtual class represents a scrolling panel. + */ class LLScrollingPanel : public LLPanel { public: - LLScrollingPanel(const LLString& name, const LLRect& rect) - : LLPanel(name, rect) - { - } + LLScrollingPanel(const LLString& name, const LLRect& rect) : LLPanel(name, rect) { } virtual void updatePanel(BOOL allow_modify) = 0; - }; - -// A set of panels that are displayed in a vertical sequence inside a scroll container. + + +/* + * A set of panels that are displayed in a vertical sequence inside a scroll container. + */ class LLScrollingPanelList : public LLUICtrl { public: LLScrollingPanelList(const LLString& name, const LLRect& rect) : LLUICtrl(name, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_BOTTOM ) {} - virtual void setValue(const LLSD& value); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual void setValue(const LLSD& value) {}; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SCROLLING_PANEL_LIST; } + virtual LLString getWidgetTag() const { return LL_SCROLLING_PANEL_LIST_TAG; } - virtual LLXMLNodePtr getXML(bool save_children) const; + virtual LLXMLNodePtr getXML(bool save_children) const { return LLUICtrl::getXML(); } virtual void draw(); @@ -68,9 +69,8 @@ public: static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); -protected: +private: void updatePanelVisiblilty(); -protected: std::deque mPanelList; }; diff --git a/linden/indra/llui/llscrolllistctrl.cpp b/linden/indra/llui/llscrolllistctrl.cpp index 043caa9..eee2bcf 100644 --- a/linden/indra/llui/llscrolllistctrl.cpp +++ b/linden/indra/llui/llscrolllistctrl.cpp @@ -1,4 +1,4 @@ -/** + /** * @file llscrolllistctrl.cpp * @brief LLScrollListCtrl base class * @@ -43,6 +43,7 @@ #include "llclipboard.h" #include "llfocusmgr.h" #include "llgl.h" +#include "llglimmediate.h" #include "llglheaders.h" #include "llresmgr.h" #include "llscrollbar.h" @@ -126,7 +127,7 @@ LLScrollListIcon::~LLScrollListIcon() { } -void LLScrollListIcon::setValue(LLSD value) +void LLScrollListIcon::setValue(const LLSD& value) { mImageUUID = value.asUUID(); // don't use default image specified by LLUUID::null, use no image in that case @@ -142,11 +143,11 @@ void LLScrollListIcon::setColor(const LLColor4& color) S32 LLScrollListIcon::getWidth() const { // if no specified fix width, use width of icon - if (mWidth == 0) + if (LLScrollListCell::getWidth() == 0) { return mIcon->getWidth(); } - return mWidth; + return LLScrollListCell::getWidth(); } @@ -170,11 +171,11 @@ LLScrollListCheck::LLScrollListCheck(LLCheckBoxCtrl* check_box, S32 width) rect.mRight = rect.mLeft + width; mCheckBox->setRect(rect); - mWidth = width; + setWidth(width); } else { - mWidth = rect.getWidth(); //check_box->getWidth(); + setWidth(rect.getWidth()); //check_box->getWidth(); } } @@ -259,6 +260,12 @@ void LLScrollListText::setText(const LLStringExplicit& text) mText = text; } +//virtual +void LLScrollListText::setValue(const LLSD& text) +{ + setText(text.asString()); +} + void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_color) const { LLColor4 display_color; @@ -274,7 +281,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col if (mHighlightCount > 0) { mRoundedRectImage->bind(); - glColor4fv(highlight_color.mV); + gGL.color4fv(highlight_color.mV); S32 left = 0; switch(mFontAlignment) { @@ -361,7 +368,7 @@ void LLScrollListItem::setColumn( S32 column, LLScrollListCell *cell ) } } -LLString LLScrollListItem::getContentsCSV() +LLString LLScrollListItem::getContentsCSV() const { LLString ret; @@ -386,7 +393,7 @@ void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const bg_rect.stretch(LIST_BORDER_PAD, 0); { LLGLSNoTexture no_texture; - glColor4fv(bg_color.mV); + gGL.color4fv(bg_color.mV); gl_rect_2d( bg_rect ); } @@ -536,8 +543,8 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, mItemListRect.setOriginAndSize( mBorderThickness + LIST_BORDER_PAD, mBorderThickness + LIST_BORDER_PAD, - mRect.getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ), - mRect.getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) ); + getRect().getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ), + getRect().getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) ); updateLineHeight(); @@ -546,7 +553,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, // Init the scrollbar LLRect scroll_rect; scroll_rect.setOriginAndSize( - mRect.getWidth() - mBorderThickness - SCROLLBAR_SIZE, + getRect().getWidth() - mBorderThickness - SCROLLBAR_SIZE, mItemListRect.mBottom, SCROLLBAR_SIZE, mItemListRect.getHeight()); @@ -567,7 +574,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect, // Border if (show_border) { - LLRect border_rect( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 ); mBorder = new LLViewBorder( "dlg border", border_rect, LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, 1 ); addChild(mBorder); } @@ -733,8 +740,8 @@ void LLScrollListCtrl::updateLayout() mItemListRect.setOriginAndSize( mBorderThickness + LIST_BORDER_PAD, mBorderThickness + LIST_BORDER_PAD, - mRect.getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ), - mRect.getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) - heading_size ); + getRect().getWidth() - 2*( mBorderThickness + LIST_BORDER_PAD ), + getRect().getHeight() - 2*( mBorderThickness + LIST_BORDER_PAD ) - heading_size ); // how many lines of content in a single "page" mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0; @@ -742,7 +749,7 @@ void LLScrollListCtrl::updateLayout() if (scrollbar_visible) { // provide space on the right for scrollbar - mItemListRect.mRight = mRect.getWidth() - ( mBorderThickness + LIST_BORDER_PAD ) - SCROLLBAR_SIZE; + mItemListRect.mRight = getRect().getWidth() - ( mBorderThickness + LIST_BORDER_PAD ) - SCROLLBAR_SIZE; } mScrollbar->reshape(SCROLLBAR_SIZE, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0)); @@ -758,7 +765,7 @@ void LLScrollListCtrl::updateLayout() void LLScrollListCtrl::fitContents(S32 max_width, S32 max_height) { S32 height = llmin( getRequiredRect().getHeight(), max_height ); - S32 width = mRect.getWidth(); + S32 width = getRect().getWidth(); reshape( width, height ); } @@ -770,7 +777,7 @@ LLRect LLScrollListCtrl::getRequiredRect() S32 height = (mLineHeight * getItemCount()) + (2 * ( mBorderThickness + LIST_BORDER_PAD )) + heading_size; - S32 width = mRect.getWidth(); + S32 width = getRect().getWidth(); return LLRect(0, height, width, 0); } @@ -1206,10 +1213,10 @@ S32 LLScrollListCtrl::selectMultiple( LLDynamicArray ids ) return count; } -S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) +S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) const { S32 index = 0; - item_list::iterator iter; + item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem *itemp = *iter; @@ -1222,10 +1229,10 @@ S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) return -1; } -S32 LLScrollListCtrl::getItemIndex( const LLUUID& target_id ) +S32 LLScrollListCtrl::getItemIndex( const LLUUID& target_id ) const { S32 index = 0; - item_list::iterator iter; + item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem *itemp = *iter; @@ -1366,6 +1373,8 @@ LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos) // Returns false if item not found. BOOL LLScrollListCtrl::selectItemByLabel(const LLString& label, BOOL case_sensitive) { + // ensure that no stale items are selected, even if we don't find a match + deselectAllItems(TRUE); //RN: assume no empty items if (label.empty()) { @@ -1525,7 +1534,7 @@ BOOL LLScrollListCtrl::selectByID( const LLUUID& id ) return selectByValue( LLSD(id) ); } -BOOL LLScrollListCtrl::setSelectedByValue(LLSD value, BOOL selected) +BOOL LLScrollListCtrl::setSelectedByValue(const LLSD& value, BOOL selected) { BOOL found = FALSE; @@ -1558,9 +1567,9 @@ BOOL LLScrollListCtrl::setSelectedByValue(LLSD value, BOOL selected) return found; } -BOOL LLScrollListCtrl::isSelected(LLSD value) +BOOL LLScrollListCtrl::isSelected(const LLSD& value) const { - item_list::iterator iter; + item_list::const_iterator iter; for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem* item = *iter; @@ -1572,7 +1581,7 @@ BOOL LLScrollListCtrl::isSelected(LLSD value) return FALSE; } -LLUUID LLScrollListCtrl::getStringUUIDSelectedItem() +LLUUID LLScrollListCtrl::getStringUUIDSelectedItem() const { LLScrollListItem* item = getFirstSelected(); @@ -1698,12 +1707,12 @@ void LLScrollListCtrl::draw() scrollToShowSelected(); mNeedsScroll = FALSE; } - LLRect background(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0); // Draw background if (mBackgroundVisible) { LLGLSNoTexture no_texture; - glColor4fv( getEnabled() ? mBgWriteableColor.mV : mBgReadOnlyColor.mV ); + gGL.color4fv( getEnabled() ? mBgWriteableColor.mV : mBgReadOnlyColor.mV ); gl_rect_2d(background); } @@ -1753,10 +1762,9 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky { LLScrollListCell* hit_cell = hit_item->getColumn(column_index); if (!hit_cell) return FALSE; - S32 cell_required_width = hit_cell->getContentWidth(); + //S32 cell_required_width = hit_cell->getContentWidth(); if (hit_cell - && hit_cell->isText() - && cell_required_width > columnp->mWidth) + && hit_cell->isText()) { S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft; @@ -1772,8 +1780,8 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); msg = hit_cell->getValue().asString(); - handled = TRUE; } + handled = TRUE; } // otherwise, look for a tooltip associated with this column @@ -2441,16 +2449,6 @@ void LLScrollListCtrl::commitIfChanged() } } -void LLScrollListCtrl::setSorted(BOOL sorted) -{ - mSorted = sorted; -} - -BOOL LLScrollListCtrl::isSorted() -{ - return mSorted; -} - struct SameSortColumn { SameSortColumn(S32 column) : mColumn(column) {} @@ -2544,7 +2542,7 @@ void LLScrollListCtrl::dirtyColumns() } -S32 LLScrollListCtrl::getScrollPos() +S32 LLScrollListCtrl::getScrollPos() const { return mScrollbar->getDocPos(); } @@ -2901,7 +2899,7 @@ void LLScrollListCtrl::copy() } // virtual -BOOL LLScrollListCtrl::canCopy() +BOOL LLScrollListCtrl::canCopy() const { return (getFirstSelected() != NULL); } @@ -2914,25 +2912,12 @@ void LLScrollListCtrl::cut() } // virtual -BOOL LLScrollListCtrl::canCut() +BOOL LLScrollListCtrl::canCut() const { return canCopy() && canDoDelete(); } // virtual -void LLScrollListCtrl::doDelete() -{ - // Not yet implemented -} - -// virtual -BOOL LLScrollListCtrl::canDoDelete() -{ - // Not yet implemented - return FALSE; -} - -// virtual void LLScrollListCtrl::selectAll() { // Deselects all other items @@ -2953,7 +2938,7 @@ void LLScrollListCtrl::selectAll() } // virtual -BOOL LLScrollListCtrl::canSelectAll() +BOOL LLScrollListCtrl::canSelectAll() const { return getCanSelect() && mAllowMultipleSelection && !(mMaxSelectable > 0 && mItemList.size() > mMaxSelectable); } @@ -2965,7 +2950,7 @@ void LLScrollListCtrl::deselect() } // virtual -BOOL LLScrollListCtrl::canDeselect() +BOOL LLScrollListCtrl::canDeselect() const { return getCanSelect(); } @@ -3056,7 +3041,7 @@ void LLScrollListCtrl::onClickColumn(void *userdata) LLScrollListCtrl *parent = info->mParentCtrl; if (!parent) return; - U32 column_index = info->mIndex; + S32 column_index = info->mIndex; LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex]; bool ascending = column->mSortAscending; @@ -3430,14 +3415,14 @@ LLColumnHeader::LLColumnHeader(const LLString& label, const LLRect &rect, LLScro mAscendingText = "[LOW]...[HIGH](Ascending)"; mDescendingText = "[HIGH]...[LOW](Descending)"; - mList->reshape(llmax(mList->getRect().getWidth(), 110, mRect.getWidth()), mList->getRect().getHeight()); + mList->reshape(llmax(mList->getRect().getWidth(), 110, getRect().getWidth()), mList->getRect().getHeight()); // resize handles on left and right const S32 RESIZE_BAR_THICKNESS = 3; mResizeBar = new LLResizeBar( "resizebar", this, - LLRect( mRect.getWidth() - RESIZE_BAR_THICKNESS, mRect.getHeight(), mRect.getWidth(), 0), + LLRect( getRect().getWidth() - RESIZE_BAR_THICKNESS, getRect().getHeight(), getRect().getWidth(), 0), MIN_COLUMN_WIDTH, S32_MAX, LLResizeBar::RIGHT ); addChild(mResizeBar); @@ -3458,10 +3443,10 @@ void LLColumnHeader::draw() mButton->setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, draw_arrow ? LLColor4::white : LLColor4::transparent); mArrowImage = mButton->getImageOverlay()->getImage(); - //BOOL clip = mRect.mRight > mColumn->mParentCtrl->getItemListRect().getWidth(); + //BOOL clip = getRect().mRight > mColumn->mParentCtrl->getItemListRect().getWidth(); //LLGLEnable scissor_test(clip ? GL_SCISSOR_TEST : GL_FALSE); - //LLRect column_header_local_rect(-mRect.mLeft, mRect.getHeight(), mColumn->mParentCtrl->getItemListRect().getWidth() - mRect.mLeft, 0); + //LLRect column_header_local_rect(-getRect().mLeft, getRect().getHeight(), mColumn->mParentCtrl->getItemListRect().getWidth() - getRect().mLeft, 0); //LLUI::setScissorRegionLocal(column_header_local_rect); // Draw children @@ -3605,13 +3590,13 @@ void LLColumnHeader::showList() S32 text_width = LLFontGL::sSansSerifSmall->getWidth(ascending_string); text_width = llmax(text_width, LLFontGL::sSansSerifSmall->getWidth(descending_string)) + 10; - text_width = llmax(text_width, mRect.getWidth() - 30); + text_width = llmax(text_width, getRect().getWidth() - 30); mList->getColumn(0)->mWidth = text_width; ((LLScrollListText*)mList->getFirstData()->getColumn(0))->setText(ascending_string); ((LLScrollListText*)mList->getLastData()->getColumn(0))->setText(descending_string); - mList->reshape(llmax(text_width + 30, 110, mRect.getWidth()), mList->getRect().getHeight()); + mList->reshape(llmax(text_width + 30, 110, getRect().getWidth()), mList->getRect().getHeight()); LLComboBox::showList(); } @@ -3684,7 +3669,7 @@ LLView* LLColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_d void LLColumnHeader::userSetShape(const LLRect& new_rect) { S32 new_width = new_rect.getWidth(); - S32 delta_width = new_width - (mRect.getWidth() /*+ mColumn->mParentCtrl->getColumnPadding()*/); + S32 delta_width = new_width - (getRect().getWidth() /*+ mColumn->mParentCtrl->getColumnPadding()*/); if (delta_width != 0) { @@ -3744,7 +3729,7 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect) } // propagate constrained delta_width to new width for this column - new_width = mRect.getWidth() + delta_width - mColumn->mParentCtrl->getColumnPadding(); + new_width = getRect().getWidth() + delta_width - mColumn->mParentCtrl->getColumnPadding(); // use requested width mColumn->mWidth = new_width; diff --git a/linden/indra/llui/llscrolllistctrl.h b/linden/indra/llui/llscrolllistctrl.h index e9486cb..716d18a 100644 --- a/linden/indra/llui/llscrolllistctrl.h +++ b/linden/indra/llui/llscrolllistctrl.h @@ -1,6 +1,5 @@ /** * @file llscrolllistctrl.h - * @brief LLScrollListCtrl base class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -43,16 +42,20 @@ #include "llstring.h" #include "llimagegl.h" #include "lleditmenuhandler.h" -#include "llviewborder.h" #include "llframetimer.h" #include "llcheckboxctrl.h" #include "llcombobox.h" +#include "llscrollbar.h" +#include "llresizebar.h" -class LLScrollbar; -class LLScrollListCtrl; -class LLColumnHeader; -class LLResizeBar; - +/* + * Represents a cell in a scrollable table. + * + * Sub-classes must return height and other properties + * though width accessors are implemented by the base class. + * It is therefore important for sub-class constructors to call + * setWidth() with realistic values. + */ class LLScrollListCell { public: @@ -63,21 +66,24 @@ public: virtual S32 getContentWidth() const { return 0; } virtual S32 getHeight() const = 0; virtual const LLSD getValue() const { return LLString::null; } - virtual void setValue(LLSD value) { } + virtual void setValue(const LLSD& value) { } virtual BOOL getVisible() const { return TRUE; } virtual void setWidth(S32 width) { mWidth = width; } virtual void highlightText(S32 offset, S32 num_chars) {} - virtual BOOL isText() = 0; + virtual BOOL isText() const = 0; virtual void setColor(const LLColor4&) {} virtual void onCommit() {}; - virtual BOOL handleClick() { return FALSE; } - virtual void setEnabled(BOOL enable) { } + virtual BOOL handleClick() { return FALSE; } + virtual void setEnabled(BOOL enable) { } -protected: +private: S32 mWidth; }; +/* + * Draws a horizontal line. + */ class LLScrollListSeparator : public LLScrollListCell { public: @@ -85,9 +91,12 @@ public: virtual ~LLScrollListSeparator() {}; virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; // truncate to given width, if possible virtual S32 getHeight() const { return 5; }; - virtual BOOL isText() { return FALSE; } + virtual BOOL isText() const { return FALSE; } }; +/* + * Cell displaying a text label. + */ class LLScrollListText : public LLScrollListCell { public: @@ -97,13 +106,13 @@ public: virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; virtual S32 getContentWidth() const; virtual S32 getHeight() const { return llround(mFont->getLineHeight()); } - virtual void setValue(LLSD value) { setText(value.asString()); } - virtual const LLSD getValue() const { return LLSD(mText.getString()); } + virtual void setValue(const LLSD& value); + virtual const LLSD getValue() const { return LLSD(mText.getString()); } virtual BOOL getVisible() const { return mVisible; } virtual void highlightText(S32 offset, S32 num_chars) {mHighlightOffset = offset; mHighlightCount = num_chars;} virtual void setColor(const LLColor4&); - virtual BOOL isText() { return TRUE; } + virtual BOOL isText() const { return TRUE; } void setText(const LLStringExplicit& text); void setFontStyle(const U8 font_style) { mFontStyle = font_style; } @@ -124,6 +133,9 @@ private: static U32 sCount; }; +/* + * Cell displaying an image. + */ class LLScrollListIcon : public LLScrollListCell { public: @@ -135,8 +147,8 @@ public: // used as sort criterion virtual const LLSD getValue() const { return LLSD(mImageUUID); } virtual void setColor(const LLColor4&); - virtual BOOL isText() { return FALSE; } - virtual void setValue(LLSD value); + virtual BOOL isText()const { return FALSE; } + virtual void setValue(const LLSD& value); private: LLPointer mIcon; @@ -144,6 +156,9 @@ private: LLColor4 mColor; }; +/* + * An interactive cell containing a check box. + */ class LLScrollListCheck : public LLScrollListCell { public: @@ -152,19 +167,22 @@ public: virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; virtual S32 getHeight() const { return 0; } virtual const LLSD getValue() const { return mCheckBox->getValue(); } - virtual void setValue(LLSD value) { mCheckBox->setValue(value); } + virtual void setValue(const LLSD& value) { mCheckBox->setValue(value); } virtual void onCommit() { mCheckBox->onCommit(); } virtual BOOL handleClick(); virtual void setEnabled(BOOL enable) { mCheckBox->setEnabled(enable); } LLCheckBoxCtrl* getCheckBox() { return mCheckBox; } - virtual BOOL isText() { return FALSE; } + virtual BOOL isText() const { return FALSE; } private: LLCheckBoxCtrl* mCheckBox; }; +/* + * A simple data class describing a column within a scroll list. + */ class LLScrollListColumn { public: @@ -245,6 +263,9 @@ public: mHeader = NULL; } + // Public data is fine so long as this remains a simple struct-like data class. + // If it ever gets any smarter than that, these should all become private + // with protected or public accessor methods added as needed. -MG LLString mName; LLString mSortingColumn; BOOL mSortAscending; @@ -255,7 +276,7 @@ public: S32 mMaxContentWidth; S32 mIndex; LLScrollListCtrl* mParentCtrl; - LLColumnHeader* mHeader; + class LLColumnHeader* mHeader; LLFontGL::HAlign mFontAlignment; }; @@ -284,7 +305,7 @@ public: static void onMouseDown(void* user_data); static void onHeldDown(void* user_data); -protected: +private: LLScrollListColumn* mColumn; LLResizeBar* mResizeBar; LLString mOrigLabel; @@ -331,11 +352,11 @@ public: void setColumn( S32 column, LLScrollListCell *cell ); - S32 getNumColumns() const { return mColumns.size(); } + S32 getNumColumns() const { return mColumns.size(); } LLScrollListCell *getColumn(const S32 i) const { if (0 <= i && i < (S32)mColumns.size()) { return mColumns[i]; } return NULL; } - LLString getContentsCSV(); + LLString getContentsCSV() const; virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding); @@ -347,6 +368,11 @@ private: std::vector mColumns; }; +/* + * A graphical control representing a scrollable table. + * Cells in the table can be simple text or more complicated things + * such as icons or even interactive elements like check boxes. + */ class LLScrollListItemComment : public LLScrollListItem { public: @@ -421,7 +447,7 @@ public: // DEPRECATED: Use setSelectedByValue() below. BOOL setCurrentByID( const LLUUID& id ) { return selectByID(id); } - virtual LLUUID getCurrentID() { return getStringUUIDSelectedItem(); } + virtual LLUUID getCurrentID() const { return getStringUUIDSelectedItem(); } BOOL operateOnSelection(EOperation op); BOOL operateOnAll(EOperation op); @@ -433,11 +459,11 @@ public: // Match item by value.asString(), which should work for string, integer, uuid. // Returns FALSE if not found. - BOOL setSelectedByValue(LLSD value, BOOL selected); + BOOL setSelectedByValue(const LLSD& value, BOOL selected); - BOOL isSorted(); + BOOL isSorted() const { return mSorted; } - virtual BOOL isSelected(LLSD value); + virtual BOOL isSelected(const LLSD& value) const; BOOL handleClick(S32 x, S32 y, MASK mask); BOOL selectFirstItem(); @@ -461,8 +487,8 @@ public: void setCanSelect(BOOL can_select) { mCanSelect = can_select; } virtual BOOL getCanSelect() const { return mCanSelect; } - S32 getItemIndex( LLScrollListItem* item ); - S32 getItemIndex( const LLUUID& item_id ); + S32 getItemIndex( LLScrollListItem* item ) const; + S32 getItemIndex( const LLUUID& item_id ) const; LLScrollListItem* addCommentText( const LLString& comment_text, EAddPosition pos = ADD_BOTTOM); LLScrollListItem* addSeparator(EAddPosition pos); @@ -482,12 +508,11 @@ public: // "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which // has an associated, unique UUID, and only one of which can be selected at a time. LLScrollListItem* addStringUUIDItem(const LLString& item_text, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, S32 column_width = 0); - LLUUID getStringUUIDSelectedItem(); + LLUUID getStringUUIDSelectedItem() const; LLScrollListItem* getFirstSelected() const; virtual S32 getFirstSelectedIndex() const; std::vector getAllSelected() const; - LLScrollListItem* getLastSelectedItem() const { return mLastSelected; } // iterate over all items @@ -520,7 +545,7 @@ public: S32 getMaxSelectable() { return mMaxSelectable; } - virtual S32 getScrollPos(); + virtual S32 getScrollPos() const; virtual void setScrollPos( S32 pos ); S32 getSearchColumn() { return mSearchColumn; } @@ -576,19 +601,13 @@ public: // LLEditMenuHandler functions virtual void copy(); - virtual BOOL canCopy(); - + virtual BOOL canCopy() const; virtual void cut(); - virtual BOOL canCut(); - - virtual void doDelete(); - virtual BOOL canDoDelete(); - + virtual BOOL canCut() const; virtual void selectAll(); - virtual BOOL canSelectAll(); - + virtual BOOL canSelectAll() const; virtual void deselect(); - virtual BOOL canDeselect(); + virtual BOOL canDeselect() const; void setNumDynamicColumns(int num) { mNumDynamicWidthColumns = num; } void setTotalStaticColumnWidth(int width) { mTotalStaticColumnWidth = width; } @@ -600,7 +619,7 @@ public: S32 selectMultiple( LLDynamicArray ids ); void sortItems(); // manually call this whenever editing list items in place to flag need for resorting - void setSorted(BOOL sorted); + void setSorted(BOOL sorted) { mSorted = sorted; } void dirtyColumns(); // some operation has potentially affected column layout or ordering protected: @@ -617,9 +636,14 @@ protected: // The LLScrollListCtrl owns its items and is responsible for deleting them // (except in the case that the addItem() call fails, in which case it is up // to the caller to delete the item) - + // // returns FALSE if item faile to be added to list, does NOT delete 'item' BOOL addItem( LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM, BOOL requires_column = TRUE ); + + typedef std::deque item_list; + item_list& getItemList() { return mItemList; } + +private: void selectPrevItem(BOOL extend_selection); void selectNextItem(BOOL extend_selection); void drawItems(); @@ -632,7 +656,7 @@ protected: void commitIfChanged(); BOOL setSort(S32 column, BOOL ascending); -protected: + S32 mCurIndex; // For get[First/Next]Data S32 mCurSelectedIndex; // For get[First/Next]Selected @@ -652,7 +676,6 @@ protected: BOOL mDisplayColumnHeaders; BOOL mColumnsDirty; - typedef std::deque item_list; item_list mItemList; LLScrollListItem *mLastSelected; @@ -681,7 +704,7 @@ protected: void (*mOnSortChangedCallback)(void* userdata); S32 mHighlightedItem; - LLViewBorder* mBorder; + class LLViewBorder* mBorder; LLWString mSearchString; LLFrameTimer mSearchTimer; @@ -704,15 +727,9 @@ protected: typedef std::pair sort_column_t; std::vector mSortColumns; -public: // HACK: Did we draw one selected item this frame? BOOL mDrewSelected; -}; - -const BOOL MULTIPLE_SELECT_YES = TRUE; -const BOOL MULTIPLE_SELECT_NO = FALSE; +}; // end class LLScrollListCtrl -const BOOL SHOW_BORDER_YES = TRUE; -const BOOL SHOW_BORDER_NO = FALSE; #endif // LL_SCROLLLISTCTRL_H diff --git a/linden/indra/llui/llslider.cpp b/linden/indra/llui/llslider.cpp index e03603d..02841ee 100644 --- a/linden/indra/llui/llslider.cpp +++ b/linden/indra/llui/llslider.cpp @@ -82,15 +82,6 @@ LLSlider::LLSlider( mDragStartThumbRect = mThumbRect; } -EWidgetType LLSlider::getWidgetType() const -{ - return WIDGET_TYPE_SLIDER_BAR; -} - -LLString LLSlider::getWidgetTag() const -{ - return LL_SLIDER_TAG; -} void LLSlider::setValue(F32 value, BOOL from_event) { @@ -118,7 +109,7 @@ void LLSlider::updateThumbRect() S32 thumb_width = mThumbImage->getWidth(); S32 thumb_height = mThumbImage->getHeight(); S32 left_edge = (thumb_width / 2); - S32 right_edge = mRect.getWidth() - (thumb_width / 2); + S32 right_edge = getRect().getWidth() - (thumb_width / 2); S32 x = left_edge + S32( t * (right_edge - left_edge) ); mThumbRect.mLeft = x - (thumb_width / 2); @@ -140,18 +131,13 @@ void LLSlider::setValueAndCommit(F32 value) } -F32 LLSlider::getValueF32() const -{ - return mValue; -} - BOOL LLSlider::handleHover(S32 x, S32 y, MASK mask) { if( hasMouseCapture() ) { S32 thumb_half_width = mThumbImage->getWidth()/2; S32 left_edge = thumb_half_width; - S32 right_edge = mRect.getWidth() - (thumb_half_width); + S32 right_edge = getRect().getWidth() - (thumb_half_width); x += mMouseOffset; x = llclamp( x, left_edge, right_edge ); @@ -231,10 +217,10 @@ BOOL LLSlider::handleMouseDown(S32 x, S32 y, MASK mask) return TRUE; } -BOOL LLSlider::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) +BOOL LLSlider::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) { BOOL handled = FALSE; - if( getVisible() && mEnabled && !called_from_parent ) + if( getVisible() && getEnabled() && !called_from_parent ) { switch(key) { @@ -272,14 +258,14 @@ void LLSlider::draw() LLRect rect(mDragStartThumbRect); - F32 opacity = mEnabled ? 1.f : 0.3f; + F32 opacity = getEnabled() ? 1.f : 0.3f; LLColor4 center_color = (mThumbCenterColor % opacity); LLColor4 track_color = (mTrackColor % opacity); // Track LLRect track_rect(mThumbImage->getWidth() / 2, getLocalRect().getCenterY() + (mTrackImage->getHeight() / 2), - mRect.getWidth() - mThumbImage->getWidth() / 2, + getRect().getWidth() - mThumbImage->getWidth() / 2, getLocalRect().getCenterY() - (mTrackImage->getHeight() / 2) ); gl_draw_scaled_image_with_border(track_rect.mLeft, track_rect.mBottom, 3, 3, track_rect.getWidth(), track_rect.getHeight(), @@ -334,14 +320,14 @@ LLXMLNodePtr LLSlider::getXML(bool save_children) const node->createChild("min_val", TRUE)->setFloatValue(getMinValue()); node->createChild("max_val", TRUE)->setFloatValue(getMaxValue()); node->createChild("increment", TRUE)->setFloatValue(getIncrement()); - node->createChild("volume", TRUE)->setBoolValue(getVolumeSlider()); + node->createChild("volume", TRUE)->setBoolValue(mVolumeSlider); return node; } //static -LLView* LLSlider::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) +LLView* LLSlider::fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory) { LLString name("slider_bar"); node->getAttributeString("name", name); diff --git a/linden/indra/llui/llslider.h b/linden/indra/llui/llslider.h index 08ab600..506a6bd 100644 --- a/linden/indra/llui/llslider.h +++ b/linden/indra/llui/llslider.h @@ -35,7 +35,6 @@ #include "lluictrl.h" #include "v4color.h" -class LLUICtrlFactory; class LLImageGL; class LLSlider : public LLUICtrl @@ -50,16 +49,16 @@ public: F32 min_value, F32 max_value, F32 increment, - BOOL volume, + BOOL volume, //TODO: create a "volume" slider sub-class or just use image art, no? -MG const LLString& control_name = LLString::null ); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SLIDER_BAR; } + virtual LLString getWidgetTag() const { return LL_SLIDER_TAG; } virtual LLXMLNodePtr getXML(bool save_children = true) const; - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); void setValue( F32 value, BOOL from_event = FALSE ); - F32 getValueF32() const; + F32 getValueF32() const { return mValue; } virtual void setValue(const LLSD& value ) { setValue((F32)value.asReal(), TRUE); } virtual LLSD getValue() const { return LLSD(getValueF32()); } @@ -71,9 +70,8 @@ public: F32 getMinValue() const { return mMinValue; } F32 getMaxValue() const { return mMaxValue; } F32 getIncrement() const { return mIncrement; } - BOOL getVolumeSlider() const { return mVolumeSlider; } - void setMinValue(F32 min_value) {mMinValue = min_value;} - void setMaxValue(F32 max_value) {mMaxValue = max_value;} + void setMinValue(F32 min_value) {mMinValue = min_value; updateThumbRect(); } + void setMaxValue(F32 max_value) {mMaxValue = max_value; updateThumbRect(); } void setIncrement(F32 increment) {mIncrement = increment;} void setMouseDownCallback( void (*cb)(LLUICtrl* ctrl, void* userdata) ) { mMouseDownCallback = cb; } void setMouseUpCallback( void (*cb)(LLUICtrl* ctrl, void* userdata) ) { mMouseUpCallback = cb; } @@ -84,11 +82,10 @@ public: virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); virtual void draw(); -protected: +private: void setValueAndCommit(F32 value); void updateThumbRect(); -protected: F32 mValue; F32 mInitialValue; F32 mMinValue; diff --git a/linden/indra/llui/llsliderctrl.cpp b/linden/indra/llui/llsliderctrl.cpp index 17854d0..58ab4ae 100644 --- a/linden/indra/llui/llsliderctrl.cpp +++ b/linden/indra/llui/llsliderctrl.cpp @@ -81,7 +81,7 @@ LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect, mSliderMouseUpCallback( NULL ), mSliderMouseDownCallback( NULL ) { - S32 top = mRect.getHeight(); + S32 top = getRect().getHeight(); S32 bottom = 0; S32 left = 0; @@ -97,7 +97,7 @@ LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect, addChild(mLabelBox); } - S32 slider_right = mRect.getWidth(); + S32 slider_right = getRect().getWidth(); if( show_text ) { slider_right = text_left - SLIDERCTRL_SPACING; @@ -115,7 +115,7 @@ LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect, if( show_text ) { - LLRect text_rect( text_left, top, mRect.getWidth(), bottom ); + LLRect text_rect( text_left, top, getRect().getWidth(), bottom ); if( can_edit_text ) { mEditor = new LLLineEditor( "SliderCtrl Editor", text_rect, @@ -144,10 +144,6 @@ LLSliderCtrl::LLSliderCtrl(const LLString& name, const LLRect& rect, updateText(); } -LLSliderCtrl::~LLSliderCtrl() -{ - // Children all cleaned up by default view destructor. -} // static void LLSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata ) @@ -158,10 +154,6 @@ void LLSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata self->onFocusReceived(); } -F32 LLSliderCtrl::getValueF32() const -{ - return mSlider->getValueF32(); -} void LLSliderCtrl::setValue(F32 v, BOOL from_event) { @@ -209,11 +201,6 @@ void LLSliderCtrl::clear() } -BOOL LLSliderCtrl::isMouseHeldDown() -{ - return mSlider->hasMouseCapture(); -} - void LLSliderCtrl::updateText() { if( mEditor || mTextBox ) @@ -427,18 +414,6 @@ void LLSliderCtrl::reportInvalidData() make_ui_sound("UISndBadKeystroke"); } -//virtual -LLString LLSliderCtrl::getControlName() const -{ - return mSlider->getControlName(); -} - -// virtual -void LLSliderCtrl::setControlName(const LLString& control_name, LLView* context) -{ - mSlider->setControlName(control_name, context); -} - // virtual LLXMLNodePtr LLSliderCtrl::getXML(bool save_children) const { diff --git a/linden/indra/llui/llsliderctrl.h b/linden/indra/llui/llsliderctrl.h index 7af0abf..705fa5c 100644 --- a/linden/indra/llui/llsliderctrl.h +++ b/linden/indra/llui/llsliderctrl.h @@ -1,6 +1,6 @@ /** * @file llsliderctrl.h - * @brief LLSliderCtrl base class + * @brief Decorated wrapper for a LLSlider. * * $LicenseInfo:firstyear=2002&license=viewergpl$ * @@ -44,13 +44,6 @@ const S32 SLIDERCTRL_SPACING = 4; // space between label, slider, and text const S32 SLIDERCTRL_HEIGHT = 16; -// -// Classes -// -class LLFontGL; -class LLLineEditor; -class LLSlider; - class LLSliderCtrl : public LLUICtrl { @@ -63,41 +56,41 @@ public: S32 text_left, BOOL show_text, BOOL can_edit_text, - BOOL volume, + BOOL volume, //TODO: create a "volume" slider sub-class or just use image art, no? -MG void (*commit_callback)(LLUICtrl*, void*), void* callback_userdata, F32 initial_value, F32 min_value, F32 max_value, F32 increment, const LLString& control_which = LLString::null ); - virtual ~LLSliderCtrl(); + virtual ~LLSliderCtrl() {} // Children all cleaned up by default view destructor. virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SLIDER; } virtual LLString getWidgetTag() const { return LL_SLIDER_CTRL_TAG; } virtual LLXMLNodePtr getXML(bool save_children = true) const; static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - F32 getValueF32() const; + F32 getValueF32() const { return mSlider->getValueF32(); } void setValue(F32 v, BOOL from_event = FALSE); - virtual void setValue(const LLSD& value ) { setValue((F32)value.asReal(), TRUE); } - virtual LLSD getValue() const { return LLSD(getValueF32()); } + virtual void setValue(const LLSD& value) { setValue((F32)value.asReal(), TRUE); } + virtual LLSD getValue() const { return LLSD(getValueF32()); } virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); } - virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); } + virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); } - BOOL isMouseHeldDown(); + BOOL isMouseHeldDown() const { return mSlider->hasMouseCapture(); } virtual void setEnabled( BOOL b ); virtual void clear(); virtual void setPrecision(S32 precision); - void setMinValue(F32 min_value) {mSlider->setMinValue(min_value);} - void setMaxValue(F32 max_value) {mSlider->setMaxValue(max_value);} - void setIncrement(F32 increment) {mSlider->setIncrement(increment);} + void setMinValue(F32 min_value) { mSlider->setMinValue(min_value); updateText(); } + void setMaxValue(F32 max_value) { mSlider->setMaxValue(max_value); updateText(); } + void setIncrement(F32 increment) { mSlider->setIncrement(increment);} F32 getMinValue() { return mSlider->getMinValue(); } F32 getMaxValue() { return mSlider->getMaxValue(); } - void setLabel(const LLStringExplicit& label) { if (mLabelBox) mLabelBox->setText(label); } + void setLabel(const LLStringExplicit& label) { if (mLabelBox) mLabelBox->setText(label); } void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; } void setDisabledLabelColor(const LLColor4& c) { mTextDisabledColor = c; } @@ -109,8 +102,13 @@ public: virtual void setTentative(BOOL b); // marks value as tentative virtual void onCommit(); // mark not tentative, then commit - virtual void setControlName(const LLString& control_name, LLView* context); - virtual LLString getControlName() const; + virtual void setControlName(const LLString& control_name, LLView* context) + { + LLView::setControlName(control_name, context); + mSlider->setControlName(control_name, context); + } + + virtual LLString getControlName() const { return mSlider->getControlName(); } static void onSliderCommit(LLUICtrl* caller, void* userdata); static void onSliderMouseDown(LLUICtrl* caller,void* userdata); @@ -124,7 +122,6 @@ private: void updateText(); void reportInvalidData(); -private: const LLFontGL* mFont; BOOL mShowText; BOOL mCanEditText; @@ -136,7 +133,7 @@ private: F32 mValue; LLSlider* mSlider; - LLLineEditor* mEditor; + class LLLineEditor* mEditor; LLTextBox* mTextBox; LLColor4 mTextEnabledColor; diff --git a/linden/indra/llui/llspinctrl.cpp b/linden/indra/llui/llspinctrl.cpp index 4bd79e6..98cdae1 100644 --- a/linden/indra/llui/llspinctrl.cpp +++ b/linden/indra/llui/llspinctrl.cpp @@ -72,7 +72,7 @@ LLSpinCtrl::LLSpinCtrl( const LLString& name, const LLRect& rect, const LLString mTextDisabledColor( LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ), mbHasBeenSet( FALSE ) { - S32 top = mRect.getHeight(); + S32 top = getRect().getHeight(); S32 bottom = top - 2 * SPINCTRL_BTN_HEIGHT; S32 centered_top = top; S32 centered_bottom = bottom; @@ -121,7 +121,7 @@ LLSpinCtrl::LLSpinCtrl( const LLString& name, const LLRect& rect, const LLString mDownBtn->setTabStop(FALSE); addChild(mDownBtn); - LLRect editor_rect( btn_right + 1, centered_top, mRect.getWidth(), centered_bottom ); + LLRect editor_rect( btn_right + 1, centered_top, getRect().getWidth(), centered_bottom ); mEditor = new LLLineEditor( "SpinCtrl Editor", editor_rect, "", font, MAX_STRING_LENGTH, &LLSpinCtrl::onEditorCommit, NULL, NULL, this, @@ -140,11 +140,6 @@ LLSpinCtrl::LLSpinCtrl( const LLString& name, const LLRect& rect, const LLString setUseBoundingRect( TRUE ); } -LLSpinCtrl::~LLSpinCtrl() -{ - // Children all cleaned up by default view destructor. -} - F32 clamp_precision(F32 value, S32 decimal_precision) { @@ -253,10 +248,6 @@ void LLSpinCtrl::setValue(const LLSD& value ) } } -LLSD LLSpinCtrl::getValue() const -{ - return mValue; -} void LLSpinCtrl::clear() { @@ -356,7 +347,7 @@ void LLSpinCtrl::setTentative(BOOL b) } -BOOL LLSpinCtrl::isMouseHeldDown() +BOOL LLSpinCtrl::isMouseHeldDown() const { return mDownBtn->hasMouseCapture() @@ -366,9 +357,7 @@ BOOL LLSpinCtrl::isMouseHeldDown() void LLSpinCtrl::onCommit() { setTentative(FALSE); - setControlValue(mValue); - LLUICtrl::onCommit(); } @@ -412,7 +401,7 @@ void LLSpinCtrl::draw() { if( mLabelBox ) { - mLabelBox->setColor( mEnabled ? mTextEnabledColor : mTextDisabledColor ); + mLabelBox->setColor( getEnabled() ? mTextEnabledColor : mTextDisabledColor ); } LLUICtrl::draw(); } @@ -420,7 +409,7 @@ void LLSpinCtrl::draw() BOOL LLSpinCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks) { - if( mEnabled ) + if( getEnabled() ) { if( clicks > 0 ) { @@ -551,7 +540,3 @@ LLView* LLSpinCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory * return spinner; } -BOOL LLSpinCtrl::isDirty() const -{ - return( mValue != mInitialValue ); -} diff --git a/linden/indra/llui/llspinctrl.h b/linden/indra/llui/llspinctrl.h index c5a36f5..f1f971e 100644 --- a/linden/indra/llui/llspinctrl.h +++ b/linden/indra/llui/llspinctrl.h @@ -1,6 +1,6 @@ /** * @file llspinctrl.h - * @brief LLSpinCtrl base class + * @brief Typical spinner with "up" and "down" arrow buttons. * * $LicenseInfo:firstyear=2002&license=viewergpl$ * @@ -47,15 +47,6 @@ const S32 SPINCTRL_SPACING = 2; // space between label right and button const S32 SPINCTRL_HEIGHT = 2 * SPINCTRL_BTN_HEIGHT; const S32 SPINCTRL_DEFAULT_LABEL_WIDTH = 10; -// -// Classes -// -class LLFontGL; -class LLButton; -class LLTextBox; -class LLLineEditor; -class LLUICtrlFactory; - class LLSpinCtrl : public LLUICtrl @@ -70,31 +61,33 @@ public: const LLString& control_name = LLString(), S32 label_width = SPINCTRL_DEFAULT_LABEL_WIDTH ); - virtual ~LLSpinCtrl(); + virtual ~LLSpinCtrl() {} // Children all cleaned up by default view destructor. virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SPINNER; } virtual LLString getWidgetTag() const { return LL_SPIN_CTRL_TAG; } virtual LLXMLNodePtr getXML(bool save_children = true) const; - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); virtual void setValue(const LLSD& value ); - virtual LLSD getValue() const; - F32 get() { return (F32)getValue().asReal(); } + virtual LLSD getValue() const { return mValue; } + F32 get() const { return (F32)getValue().asReal(); } void set(F32 value) { setValue(value); mInitialValue = value; } virtual void setMinValue(LLSD min_value) { setMinValue((F32)min_value.asReal()); } virtual void setMaxValue(LLSD max_value) { setMaxValue((F32)max_value.asReal()); } - BOOL isMouseHeldDown(); + BOOL isMouseHeldDown() const; virtual void setEnabled( BOOL b ); virtual void setFocus( BOOL b ); virtual void clear(); - virtual BOOL isDirty() const; + virtual BOOL isDirty() const { return( mValue != mInitialValue ); } virtual void setPrecision(S32 precision); virtual void setMinValue(F32 min) { mMinValue = min; } virtual void setMaxValue(F32 max) { mMaxValue = max; } virtual void setIncrement(F32 inc) { mIncrement = inc; } + virtual F32 getMinValue() { return mMinValue ; } + virtual F32 getMaxValue() { return mMaxValue ; } void setLabel(const LLStringExplicit& label); void setLabelColor(const LLColor4& c) { mTextEnabledColor = c; } @@ -119,12 +112,10 @@ public: static void onUpBtn(void *userdata); static void onDownBtn(void *userdata); -protected: +private: void updateEditor(); void reportInvalidData(); -protected: - F32 mValue; F32 mInitialValue; F32 mMaxValue; @@ -132,14 +123,14 @@ protected: F32 mIncrement; S32 mPrecision; - LLTextBox* mLabelBox; + class LLTextBox* mLabelBox; - LLLineEditor* mEditor; + class LLLineEditor* mEditor; LLColor4 mTextEnabledColor; LLColor4 mTextDisabledColor; - LLButton* mUpBtn; - LLButton* mDownBtn; + class LLButton* mUpBtn; + class LLButton* mDownBtn; BOOL mbHasBeenSet; }; diff --git a/linden/indra/llui/llstyle.cpp b/linden/indra/llui/llstyle.cpp index 693e0be..cdf87d3 100644 --- a/linden/indra/llui/llstyle.cpp +++ b/linden/indra/llui/llstyle.cpp @@ -71,11 +71,6 @@ LLStyle::LLStyle(BOOL is_visible, const LLColor4 &color, const LLString& font_na init(is_visible, color, font_name); } -LLStyle::~LLStyle() -{ - free(); -} - void LLStyle::init(BOOL is_visible, const LLColor4 &color, const LLString& font_name) { mVisible = is_visible; @@ -91,14 +86,6 @@ void LLStyle::init(BOOL is_visible, const LLColor4 &color, const LLString& font_ mIsEmbeddedItem = FALSE; } -void LLStyle::free() -{ -} - -LLFONT_ID LLStyle::getFontID() const -{ - return mFontID; -} // Copy assignment LLStyle &LLStyle::operator=(const LLStyle &rhs) @@ -122,48 +109,6 @@ LLStyle &LLStyle::operator=(const LLStyle &rhs) return *this; } -// Compare -bool LLStyle::operator==(const LLStyle &rhs) const -{ - if ((mVisible != rhs.isVisible()) - || (mColor != rhs.getColor()) - || (mFontName != rhs.getFontString()) - || (mLink != rhs.getLinkHREF()) - || (mImagep != rhs.mImagep) - || (mImageHeight != rhs.mImageHeight) - || (mImageWidth != rhs.mImageWidth) - || (mItalic != rhs.mItalic) - || (mBold != rhs.mBold) - || (mUnderline != rhs.mUnderline) - || (mDropShadow != rhs.mDropShadow) - || (mIsEmbeddedItem != rhs.mIsEmbeddedItem) - ) - { - return FALSE; - } - return TRUE; -} - -bool LLStyle::operator!=(const LLStyle& rhs) const -{ - return !(*this == rhs); -} - - -const LLColor4& LLStyle::getColor() const -{ - return(mColor); -} - -void LLStyle::setColor(const LLColor4 &color) -{ - mColor = color; -} - -const LLString& LLStyle::getFontString() const -{ - return mFontName; -} void LLStyle::setFontName(const LLString& fontname) { @@ -192,52 +137,15 @@ void LLStyle::setFontName(const LLString& fontname) } } -const LLString& LLStyle::getLinkHREF() const -{ - return mLink; -} - -void LLStyle::setLinkHREF(const LLString& href) -{ - mLink = href; -} - -BOOL LLStyle::isLink() const -{ - return mLink.size(); -} - -BOOL LLStyle::isVisible() const -{ - return mVisible; -} - -void LLStyle::setVisible(BOOL is_visible) -{ - mVisible = is_visible; -} - -LLImageGL *LLStyle::getImage() const -{ - return mImagep; -} void LLStyle::setImage(const LLString& src) { - if (src.size() < UUID_STR_LENGTH - 1) - { - return; - } - else + if (src.size() >= UUID_STR_LENGTH - 1) { mImagep = LLUI::sImageProvider->getImageByID(LLUUID(src)); } } -BOOL LLStyle::isImage() const -{ - return ((mImageWidth != 0) && (mImageHeight != 0)); -} void LLStyle::setImageSize(S32 width, S32 height) { diff --git a/linden/indra/llui/llstyle.h b/linden/indra/llui/llstyle.h index 1712dc0..d6ae900 100644 --- a/linden/indra/llui/llstyle.h +++ b/linden/indra/llui/llstyle.h @@ -46,36 +46,52 @@ public: LLStyle &operator=(const LLStyle &rhs); - virtual ~LLStyle(); + virtual ~LLStyle() { } virtual void init (BOOL is_visible, const LLColor4 &color, const LLString& font_name); - virtual void free (); - bool operator==(const LLStyle &rhs) const; - bool operator!=(const LLStyle &rhs) const; + virtual const LLColor4& getColor() const { return mColor; } + virtual void setColor(const LLColor4 &color) { mColor = color; } - virtual const LLColor4& getColor() const; - virtual void setColor(const LLColor4 &color); + virtual BOOL isVisible() const { return mVisible; } + virtual void setVisible(BOOL is_visible) { mVisible = is_visible; } - virtual BOOL isVisible() const; - virtual void setVisible(BOOL is_visible); - - virtual const LLString& getFontString() const; + virtual const LLString& getFontString() const { return mFontName; } virtual void setFontName(const LLString& fontname); - virtual LLFONT_ID getFontID() const; + virtual LLFONT_ID getFontID() const { return mFontID; } - virtual const LLString& getLinkHREF() const; - virtual void setLinkHREF(const LLString& fontname); - virtual BOOL isLink() const; + virtual const LLString& getLinkHREF() const { return mLink; } + virtual void setLinkHREF(const LLString& href) { mLink = href; } + virtual BOOL isLink() const { return mLink.size(); } - virtual LLImageGL *getImage() const; + virtual LLImageGL *getImage() const { return mImagep; } virtual void setImage(const LLString& src); - virtual BOOL isImage() const; + virtual BOOL isImage() const { return ((mImageWidth != 0) && (mImageHeight != 0)); } virtual void setImageSize(S32 width, S32 height); BOOL getIsEmbeddedItem() const { return mIsEmbeddedItem; } void setIsEmbeddedItem( BOOL b ) { mIsEmbeddedItem = b; } + // inlined here to make it easier to compare to member data below. -MG + bool operator==(const LLStyle &rhs) const + { + return + mVisible == rhs.isVisible() + && mColor == rhs.getColor() + && mFontName == rhs.getFontString() + && mLink == rhs.getLinkHREF() + && mImagep == rhs.mImagep + && mImageHeight == rhs.mImageHeight + && mImageWidth == rhs.mImageWidth + && mItalic == rhs.mItalic + && mBold == rhs.mBold + && mUnderline == rhs.mUnderline + && mDropShadow == rhs.mDropShadow + && mIsEmbeddedItem == rhs.mIsEmbeddedItem; + } + + bool operator!=(const LLStyle& rhs) const { return !(*this == rhs); } + public: BOOL mItalic; BOOL mBold; @@ -84,14 +100,13 @@ public: S32 mImageWidth; S32 mImageHeight; -protected: +private: BOOL mVisible; LLColor4 mColor; LLString mFontName; LLFONT_ID mFontID; LLString mLink; LLPointer mImagep; - BOOL mIsEmbeddedItem; }; diff --git a/linden/indra/llui/lltabcontainer.cpp b/linden/indra/llui/lltabcontainer.cpp index 0400b50..e632cf1 100644 --- a/linden/indra/llui/lltabcontainer.cpp +++ b/linden/indra/llui/lltabcontainer.cpp @@ -1,6 +1,6 @@ /** * @file lltabcontainer.cpp - * @brief LLTabContainerCommon base class + * @brief LLTabContainer class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -30,33 +30,24 @@ */ #include "linden_common.h" - #include "lltabcontainer.h" - #include "llfocusmgr.h" -#include "llfontgl.h" -#include "llgl.h" - #include "llbutton.h" #include "llrect.h" -#include "llpanel.h" #include "llresmgr.h" -#include "llkeyboard.h" #include "llresizehandle.h" -#include "llui.h" #include "lltextbox.h" -#include "llcontrol.h" #include "llcriticaldamp.h" #include "lluictrlfactory.h" - #include "lltabcontainervertical.h" +#include "llglimmediate.h" -#include "llglheaders.h" const F32 SCROLL_STEP_TIME = 0.4f; const F32 SCROLL_DELAY_TIME = 0.5f; const S32 TAB_PADDING = 15; const S32 TABCNTR_TAB_MIN_WIDTH = 60; +const S32 TABCNTR_VERT_TAB_MIN_WIDTH = 100; const S32 TABCNTR_TAB_MAX_WIDTH = 150; const S32 TABCNTR_TAB_PARTIAL_WIDTH = 12; // When tabs are parially obscured, how much can you still see. const S32 TABCNTR_TAB_HEIGHT = 16; @@ -64,12 +55,19 @@ const S32 TABCNTR_ARROW_BTN_SIZE = 16; const S32 TABCNTR_BUTTON_PANEL_OVERLAP = 1; // how many pixels the tab buttons and tab panels overlap. const S32 TABCNTR_TAB_H_PAD = 4; +const S32 TABCNTR_CLOSE_BTN_SIZE = 16; +const S32 TABCNTR_HEADER_HEIGHT = LLPANEL_BORDER_WIDTH + TABCNTR_CLOSE_BTN_SIZE; -LLTabContainerCommon::LLTabContainerCommon( - const LLString& name, const LLRect& rect, - TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - BOOL bordered ) +const S32 TABCNTRV_CLOSE_BTN_SIZE = 16; +const S32 TABCNTRV_HEADER_HEIGHT = LLPANEL_BORDER_WIDTH + TABCNTRV_CLOSE_BTN_SIZE; +//const S32 TABCNTRV_TAB_WIDTH = 100; +const S32 TABCNTRV_ARROW_BTN_SIZE = 16; +const S32 TABCNTRV_PAD = 0; + + + +LLTabContainer::LLTabContainer(const LLString& name, const LLRect& rect, TabPosition pos, + BOOL bordered, BOOL is_vertical ) : LLPanel(name, rect, bordered), mCurrentTabIdx(-1), @@ -78,50 +76,65 @@ LLTabContainerCommon::LLTabContainerCommon( mScrollPos(0), mScrollPosPixels(0), mMaxScrollPos(0), - mCloseCallback( close_callback ), - mCallbackUserdata( callback_userdata ), + mCloseCallback( NULL ), + mCallbackUserdata( NULL ), mTitleBox(NULL), mTopBorderHeight(LLPANEL_BORDER_WIDTH), mTabPosition(pos), - mLockedTabCount(0) + mLockedTabCount(0), + mMinTabWidth(TABCNTR_TAB_MIN_WIDTH), + mMaxTabWidth(TABCNTR_TAB_MAX_WIDTH), + mPrevArrowBtn(NULL), + mNextArrowBtn(NULL), + mIsVertical(is_vertical), + // Horizontal Specific + mJumpPrevArrowBtn(NULL), + mJumpNextArrowBtn(NULL), + mRightTabBtnOffset(0), + mTotalTabWidth(0) { + //RN: HACK to support default min width for legacy vertical tab containers + if (mIsVertical) + { + mMinTabWidth = TABCNTR_VERT_TAB_MIN_WIDTH; + } setMouseOpaque(FALSE); + initButtons( ); mDragAndDropDelayTimer.stop(); } +LLTabContainer::~LLTabContainer() +{ + std::for_each(mTabList.begin(), mTabList.end(), DeletePointer()); +} -LLTabContainerCommon::LLTabContainerCommon( - const LLString& name, - const LLString& rect_control, - TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - BOOL bordered ) - : - LLPanel(name, rect_control, bordered), - mCurrentTabIdx(-1), - mTabsHidden(FALSE), - mScrolled(FALSE), - mScrollPos(0), - mScrollPosPixels(0), - mMaxScrollPos(0), - mCloseCallback( close_callback ), - mCallbackUserdata( callback_userdata ), - mTitleBox(NULL), - mTopBorderHeight(LLPANEL_BORDER_WIDTH), - mTabPosition(pos), - mLockedTabCount(0) +//virtual +void LLTabContainer::setValue(const LLSD& value) { - setMouseOpaque(FALSE); - mDragAndDropDelayTimer.stop(); + selectTab((S32) value.asInteger()); +} + +//virtual +EWidgetType LLTabContainer::getWidgetType() const +{ + return WIDGET_TYPE_TAB_CONTAINER; } +//virtual +LLString LLTabContainer::getWidgetTag() const +{ + return LL_TAB_CONTAINER_COMMON_TAG; +} -LLTabContainerCommon::~LLTabContainerCommon() +//virtual +void LLTabContainer::reshape(S32 width, S32 height, BOOL called_from_parent) { - std::for_each(mTabList.begin(), mTabList.end(), DeletePointer()); + LLPanel::reshape( width, height, called_from_parent ); + updateMaxScrollPos(); } -LLView* LLTabContainerCommon::getChildByName(const LLString& name, BOOL recurse) const +//virtual +LLView* LLTabContainer::getChildByName(const LLString& name, BOOL recurse) const { tuple_list_t::const_iterator itor; for (itor = mTabList.begin(); itor != mTabList.end(); ++itor) @@ -137,7 +150,7 @@ LLView* LLTabContainerCommon::getChildByName(const LLString& name, BOOL recurse) for (itor = mTabList.begin(); itor != mTabList.end(); ++itor) { LLPanel *panel = (*itor)->mTabPanel; - LLView *child = panel->getChildByName(name, recurse); + LLView *child = panel->getChild(name, recurse); if (child) { return child; @@ -147,754 +160,517 @@ LLView* LLTabContainerCommon::getChildByName(const LLString& name, BOOL recurse) return LLView::getChildByName(name, recurse); } -void LLTabContainerCommon::addPlaceholder(LLPanel* child, const LLString& label) -{ - addTabPanel(child, label, FALSE, NULL, NULL, 0, TRUE); -} - -void LLTabContainerCommon::lockTabs(S32 num_tabs) -{ - // count current tabs or use supplied value and ensure no new tabs get - // inserted between them - mLockedTabCount = num_tabs > 0 ? llmin(getTabCount(), num_tabs) : getTabCount(); -} - -void LLTabContainerCommon::unlockTabs() -{ - mLockedTabCount = 0; -} - -void LLTabContainerCommon::removeTabPanel(LLPanel* child) +// virtual +void LLTabContainer::draw() { - BOOL has_focus = gFocusMgr.childHasKeyboardFocus(this); - - // If the tab being deleted is the selected one, select a different tab. - for(std::vector::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + S32 target_pixel_scroll = 0; + S32 cur_scroll_pos = mIsVertical ? 0 : getScrollPos(); + if (cur_scroll_pos > 0) { - LLTabTuple* tuple = *iter; - if( tuple->mTabPanel == child ) + S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { - removeChild( tuple->mButton ); - delete tuple->mButton; - - removeChild( tuple->mTabPanel ); -// delete tuple->mTabPanel; - - mTabList.erase( iter ); - delete tuple; - - break; + if (cur_scroll_pos == 0) + { + break; + } + target_pixel_scroll += (*iter)->mButton->getRect().getWidth(); + cur_scroll_pos--; } - } - // make sure we don't have more locked tabs than we have tabs - mLockedTabCount = llmin(getTabCount(), mLockedTabCount); - - if (mCurrentTabIdx >= (S32)mTabList.size()) - { - mCurrentTabIdx = mTabList.size()-1; + // Show part of the tab to the left of what is fully visible + target_pixel_scroll -= TABCNTR_TAB_PARTIAL_WIDTH; + // clamp so that rightmost tab never leaves right side of screen + target_pixel_scroll = llmin(mTotalTabWidth - available_width_with_arrows, target_pixel_scroll); } - selectTab(mCurrentTabIdx); - if (has_focus) + + setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f))); + if( getVisible() ) { - LLPanel* panelp = getPanelByIndex(mCurrentTabIdx); - if (panelp) + BOOL has_scroll_arrows = (mMaxScrollPos > 0) || (mScrollPosPixels > 0); + if (!mIsVertical) { - panelp->setFocus(TRUE); + mJumpPrevArrowBtn->setVisible( has_scroll_arrows ); + mJumpNextArrowBtn->setVisible( has_scroll_arrows ); } - } + mPrevArrowBtn->setVisible( has_scroll_arrows ); + mNextArrowBtn->setVisible( has_scroll_arrows ); - updateMaxScrollPos(); -} + S32 left = 0, top = 0; + if (mIsVertical) + { + top = getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1 - (has_scroll_arrows ? TABCNTRV_ARROW_BTN_SIZE : 0); + top += getScrollPosPixels(); + } + else + { + // Set the leftmost position of the tab buttons. + left = LLPANEL_BORDER_WIDTH + (has_scroll_arrows ? (TABCNTR_ARROW_BTN_SIZE * 2) : TABCNTR_TAB_H_PAD); + left -= getScrollPosPixels(); + } + + // Hide all the buttons + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + tuple->mButton->setVisible( FALSE ); + } -void LLTabContainerCommon::deleteAllTabs() -{ - // Remove all the tab buttons and delete them. Also, unlink all the child panels. - for(std::vector::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; + LLPanel::draw(); - removeChild( tuple->mButton ); - delete tuple->mButton; + // if tabs are hidden, don't draw them and leave them in the invisible state + if (!getTabsHidden()) + { + // Show all the buttons + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + tuple->mButton->setVisible( TRUE ); + } - removeChild( tuple->mTabPanel ); -// delete tuple->mTabPanel; - } + // Draw some of the buttons... + LLRect clip_rect = getLocalRect(); + if (has_scroll_arrows) + { + // ...but clip them. + if (mIsVertical) + { + clip_rect.mBottom = mNextArrowBtn->getRect().mTop + 3*TABCNTRV_PAD; + clip_rect.mTop = mPrevArrowBtn->getRect().mBottom - 3*TABCNTRV_PAD; + } + else + { + clip_rect.mLeft = mPrevArrowBtn->getRect().mRight; + clip_rect.mRight = mNextArrowBtn->getRect().mLeft; + } + } + LLLocalClipRect clip(clip_rect); - // Actually delete the tuples themselves - std::for_each(mTabList.begin(), mTabList.end(), DeletePointer()); - mTabList.clear(); - - // And there isn't a current tab any more - mCurrentTabIdx = -1; -} + S32 max_scroll_visible = getTabCount() - getMaxScrollPos() + getScrollPos(); + S32 idx = 0; + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + tuple->mButton->translate( left ? left - tuple->mButton->getRect().mLeft : 0, + top ? top - tuple->mButton->getRect().mTop : 0 ); + if (top) top -= BTN_HEIGHT + TABCNTRV_PAD; + if (left) left += tuple->mButton->getRect().getWidth(); -LLPanel* LLTabContainerCommon::getCurrentPanel() -{ - if (mCurrentTabIdx < 0 || mCurrentTabIdx >= (S32) mTabList.size()) return NULL; - - return mTabList[mCurrentTabIdx]->mTabPanel; -} + if (!mIsVertical) + { + if( idx < getScrollPos() ) + { + if( tuple->mButton->getFlashing() ) + { + mPrevArrowBtn->setFlashing( TRUE ); + } + } + else if( max_scroll_visible < idx ) + { + if( tuple->mButton->getFlashing() ) + { + mNextArrowBtn->setFlashing( TRUE ); + } + } + } + LLUI::pushMatrix(); + { + LLUI::translate((F32)tuple->mButton->getRect().mLeft, (F32)tuple->mButton->getRect().mBottom, 0.f); + tuple->mButton->draw(); + } + LLUI::popMatrix(); -LLTabContainerCommon::LLTabTuple* LLTabContainerCommon::getTabByPanel(LLPanel* child) -{ - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - if( tuple->mTabPanel == child ) - { - return tuple; - } - } - return NULL; -} + idx++; + } -void LLTabContainerCommon::setTabChangeCallback(LLPanel* tab, void (*on_tab_clicked)(void*, bool)) -{ - LLTabTuple* tuplep = getTabByPanel(tab); - if (tuplep) - { - tuplep->mOnChangeCallback = on_tab_clicked; - } -} -void LLTabContainerCommon::setTabUserData(LLPanel* tab, void* userdata) -{ - LLTabTuple* tuplep = getTabByPanel(tab); - if (tuplep) - { - tuplep->mUserData = userdata; - } -} + if( mIsVertical && has_scroll_arrows ) + { + // Redraw the arrows so that they appears on top. + gGL.pushMatrix(); + gGL.translatef((F32)mPrevArrowBtn->getRect().mLeft, (F32)mPrevArrowBtn->getRect().mBottom, 0.f); + mPrevArrowBtn->draw(); + gGL.popMatrix(); + + gGL.pushMatrix(); + gGL.translatef((F32)mNextArrowBtn->getRect().mLeft, (F32)mNextArrowBtn->getRect().mBottom, 0.f); + mNextArrowBtn->draw(); + gGL.popMatrix(); + } + } -S32 LLTabContainerCommon::getCurrentPanelIndex() -{ - return mCurrentTabIdx; + mPrevArrowBtn->setFlashing(FALSE); + mNextArrowBtn->setFlashing(FALSE); + } } -S32 LLTabContainerCommon::getTabCount() -{ - return mTabList.size(); -} -LLPanel* LLTabContainerCommon::getPanelByIndex(S32 index) +// virtual +BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) { - if (index >= 0 && index < (S32)mTabList.size()) - { - return mTabList[index]->mTabPanel; - } - return NULL; -} + BOOL handled = FALSE; + BOOL has_scroll_arrows = (getMaxScrollPos() > 0); -S32 LLTabContainerCommon::getIndexForPanel(LLPanel* panel) -{ - for (S32 index = 0; index < (S32)mTabList.size(); index++) + if (has_scroll_arrows) { - if (mTabList[index]->mTabPanel == panel) + if (mJumpPrevArrowBtn&& mJumpPrevArrowBtn->getRect().pointInRect(x, y)) { - return index; + S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom; + handled = mJumpPrevArrowBtn->handleMouseDown(local_x, local_y, mask); + } + else if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom; + handled = mJumpNextArrowBtn->handleMouseDown(local_x, local_y, mask); + } + else if (mPrevArrowBtn && mPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mPrevArrowBtn->getRect().mBottom; + handled = mPrevArrowBtn->handleMouseDown(local_x, local_y, mask); + } + else if (mNextArrowBtn && mNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mNextArrowBtn->getRect().mLeft; + S32 local_y = y - mNextArrowBtn->getRect().mBottom; + handled = mNextArrowBtn->handleMouseDown(local_x, local_y, mask); } } - return -1; -} + if (!handled) + { + handled = LLPanel::handleMouseDown( x, y, mask ); + } -S32 LLTabContainerCommon::getPanelIndexByTitle(const LLString& title) -{ - for (S32 index = 0 ; index < (S32)mTabList.size(); index++) + S32 tab_count = getTabCount(); + if (tab_count > 0) { - if (title == mTabList[index]->mButton->getLabelSelected()) + LLTabTuple* firsttuple = getTab(0); + LLRect tab_rect; + if (mIsVertical) { - return index; + tab_rect = LLRect(firsttuple->mButton->getRect().mLeft, + has_scroll_arrows ? mPrevArrowBtn->getRect().mBottom - TABCNTRV_PAD : mPrevArrowBtn->getRect().mTop, + firsttuple->mButton->getRect().mRight, + has_scroll_arrows ? mNextArrowBtn->getRect().mTop + TABCNTRV_PAD : mNextArrowBtn->getRect().mBottom ); + } + else + { + tab_rect = LLRect(has_scroll_arrows ? mPrevArrowBtn->getRect().mRight : mJumpPrevArrowBtn->getRect().mLeft, + firsttuple->mButton->getRect().mTop, + has_scroll_arrows ? mNextArrowBtn->getRect().mLeft : mJumpNextArrowBtn->getRect().mRight, + firsttuple->mButton->getRect().mBottom ); + } + if( tab_rect.pointInRect( x, y ) ) + { + S32 index = getCurrentPanelIndex(); + index = llclamp(index, 0, tab_count-1); + LLButton* tab_button = getTab(index)->mButton; + gFocusMgr.setMouseCapture(this); + gFocusMgr.setKeyboardFocus(tab_button); } } - return -1; + return handled; } -LLPanel *LLTabContainerCommon::getPanelByName(const LLString& name) +// virtual +BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask ) { - for (S32 index = 0 ; index < (S32)mTabList.size(); index++) + BOOL handled = FALSE; + BOOL has_scroll_arrows = (getMaxScrollPos() > 0); + + if (has_scroll_arrows) { - LLPanel *panel = mTabList[index]->mTabPanel; - if (name == panel->getName()) + if (mJumpPrevArrowBtn && mJumpPrevArrowBtn->getRect().pointInRect(x, y)) { - return panel; + S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom; + handled = mJumpPrevArrowBtn->handleHover(local_x, local_y, mask); } - } - return NULL; -} - - -void LLTabContainerCommon::scrollNext() -{ - // No wrap - if( mScrollPos < mMaxScrollPos ) - { - mScrollPos++; - } -} - -void LLTabContainerCommon::scrollPrev() -{ - // No wrap - if( mScrollPos > 0 ) - { - mScrollPos--; - } -} - -void LLTabContainerCommon::enableTabButton(S32 which, BOOL enable) -{ - if (which >= 0 && which < (S32)mTabList.size()) - { - mTabList[which]->mButton->setEnabled(enable); - } -} - -BOOL LLTabContainerCommon::selectTabPanel(LLPanel* child) -{ - S32 idx = 0; - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - if( tuple->mTabPanel == child ) + else if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x, y)) { - return selectTab( idx ); + S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom; + handled = mJumpNextArrowBtn->handleHover(local_x, local_y, mask); + } + else if (mPrevArrowBtn && mPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mPrevArrowBtn->getRect().mBottom; + handled = mPrevArrowBtn->handleHover(local_x, local_y, mask); + } + else if (mNextArrowBtn && mNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mNextArrowBtn->getRect().mLeft; + S32 local_y = y - mNextArrowBtn->getRect().mBottom; + handled = mNextArrowBtn->handleHover(local_x, local_y, mask); } - idx++; - } - return FALSE; -} - -BOOL LLTabContainerCommon::selectTabByName(const LLString& name) -{ - LLPanel* panel = getPanelByName(name); - if (!panel) - { - llwarns << "LLTabContainerCommon::selectTabByName(" - << name << ") failed" << llendl; - return FALSE; - } - - BOOL result = selectTabPanel(panel); - return result; -} - - -void LLTabContainerCommon::selectFirstTab() -{ - selectTab( 0 ); -} - - -void LLTabContainerCommon::selectLastTab() -{ - selectTab( mTabList.size()-1 ); -} - - -void LLTabContainerCommon::selectNextTab() -{ - BOOL tab_has_focus = FALSE; - if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus()) - { - tab_has_focus = TRUE; - } - S32 idx = mCurrentTabIdx+1; - if (idx >= (S32)mTabList.size()) - idx = 0; - while (!selectTab(idx) && idx != mCurrentTabIdx) - { - idx = (idx + 1 ) % (S32)mTabList.size(); - } - - if (tab_has_focus) - { - mTabList[idx]->mButton->setFocus(TRUE); - } -} - -void LLTabContainerCommon::selectPrevTab() -{ - BOOL tab_has_focus = FALSE; - if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus()) - { - tab_has_focus = TRUE; - } - S32 idx = mCurrentTabIdx-1; - if (idx < 0) - idx = mTabList.size()-1; - while (!selectTab(idx) && idx != mCurrentTabIdx) - { - idx = idx - 1; - if (idx < 0) - idx = mTabList.size()-1; - } - if (tab_has_focus) - { - mTabList[idx]->mButton->setFocus(TRUE); - } -} - - -void LLTabContainerCommon::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - LLPanel::reshape( width, height, called_from_parent ); - updateMaxScrollPos(); -} - -// static -void LLTabContainerCommon::onTabBtn( void* userdata ) -{ - LLTabTuple* tuple = (LLTabTuple*) userdata; - LLTabContainerCommon* self = tuple->mTabContainer; - self->selectTabPanel( tuple->mTabPanel ); - - if( tuple->mOnChangeCallback ) - { - tuple->mOnChangeCallback( tuple->mUserData, true ); - } - - tuple->mTabPanel->setFocus(TRUE); -} - -// static -void LLTabContainerCommon::onCloseBtn( void* userdata ) -{ - LLTabContainer* self = (LLTabContainer*) userdata; - if( self->mCloseCallback ) - { - self->mCloseCallback( self->mCallbackUserdata ); - } -} - -// static -void LLTabContainerCommon::onNextBtn( void* userdata ) -{ - // Scroll tabs to the left - LLTabContainer* self = (LLTabContainer*) userdata; - if (!self->mScrolled) - { - self->scrollNext(); - } - self->mScrolled = FALSE; -} - -// static -void LLTabContainerCommon::onNextBtnHeld( void* userdata ) -{ - LLTabContainer* self = (LLTabContainer*) userdata; - if (self->mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME) - { - self->mScrollTimer.reset(); - self->scrollNext(); - self->mScrolled = TRUE; - } -} - -// static -void LLTabContainerCommon::onPrevBtn( void* userdata ) -{ - LLTabContainer* self = (LLTabContainer*) userdata; - if (!self->mScrolled) - { - self->scrollPrev(); } - self->mScrolled = FALSE; -} - - -void LLTabContainerCommon::onJumpFirstBtn( void* userdata ) -{ - LLTabContainer* self = (LLTabContainer*) userdata; - - self->mScrollPos = 0; - -} - - -void LLTabContainerCommon::onJumpLastBtn( void* userdata ) -{ - LLTabContainer* self = (LLTabContainer*) userdata; - - self->mScrollPos = self->mMaxScrollPos; -} - - -// static -void LLTabContainerCommon::onPrevBtnHeld( void* userdata ) -{ - LLTabContainer* self = (LLTabContainer*) userdata; - if (self->mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME) + if (!handled) { - self->mScrollTimer.reset(); - self->scrollPrev(); - self->mScrolled = TRUE; + handled = LLPanel::handleHover(x, y, mask); } -} -BOOL LLTabContainerCommon::getTabPanelFlashing(LLPanel *child) -{ - LLTabTuple* tuple = getTabByPanel(child); - if( tuple ) - { - return tuple->mButton->getFlashing(); - } - return FALSE; + commitHoveredButton(x, y); + return handled; } -void LLTabContainerCommon::setTabPanelFlashing(LLPanel* child, BOOL state ) +// virtual +BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask ) { - LLTabTuple* tuple = getTabByPanel(child); - if( tuple ) - { - tuple->mButton->setFlashing( state ); - } -} + BOOL handled = FALSE; + BOOL has_scroll_arrows = (getMaxScrollPos() > 0); -void LLTabContainerCommon::setTabImage(LLPanel* child, std::string img_name, const LLColor4& color) -{ - LLTabTuple* tuple = getTabByPanel(child); - if( tuple ) + if (has_scroll_arrows) { - tuple->mButton->setImageOverlay(img_name, LLFontGL::RIGHT, color); + if (mJumpPrevArrowBtn && mJumpPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom; + handled = mJumpPrevArrowBtn->handleMouseUp(local_x, local_y, mask); + } + else if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom; + handled = mJumpNextArrowBtn->handleMouseUp(local_x, local_y, mask); + } + else if (mPrevArrowBtn && mPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mPrevArrowBtn->getRect().mBottom; + handled = mPrevArrowBtn->handleMouseUp(local_x, local_y, mask); + } + else if (mNextArrowBtn && mNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mNextArrowBtn->getRect().mLeft; + S32 local_y = y - mNextArrowBtn->getRect().mBottom; + handled = mNextArrowBtn->handleMouseUp(local_x, local_y, mask); + } } -} - -void LLTabContainerCommon::setTitle(const LLString& title) -{ - if (mTitleBox) + if (!handled) { - mTitleBox->setText( title ); + handled = LLPanel::handleMouseUp( x, y, mask ); } -} -const LLString LLTabContainerCommon::getPanelTitle(S32 index) -{ - if (index >= 0 && index < (S32)mTabList.size()) + commitHoveredButton(x, y); + LLPanel* cur_panel = getCurrentPanel(); + if (hasMouseCapture()) { - LLButton* tab_button = mTabList[index]->mButton; - return tab_button->getLabelSelected(); + if (cur_panel) + { + if (!cur_panel->focusFirstItem(FALSE)) + { + // if nothing in the panel gets focus, make sure the new tab does + // otherwise the last tab might keep focus + getTab(getCurrentPanelIndex())->mButton->setFocus(TRUE); + } + } + gFocusMgr.setMouseCapture(NULL); } - return LLString::null; -} - -void LLTabContainerCommon::setTopBorderHeight(S32 height) -{ - mTopBorderHeight = height; -} - -// Change the name of the button for the current tab. -void LLTabContainerCommon::setCurrentTabName(const LLString& name) -{ - // Might not have a tab selected - if (mCurrentTabIdx < 0) return; - - mTabList[mCurrentTabIdx]->mButton->setLabelSelected(name); - mTabList[mCurrentTabIdx]->mButton->setLabelUnselected(name); + return handled; } -LLView* LLTabContainerCommon::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) +// virtual +BOOL LLTabContainer::handleToolTip( S32 x, S32 y, LLString& msg, LLRect* sticky_rect ) { - LLString name("tab_container"); - node->getAttributeString("name", name); - - // Figure out if we are creating a vertical or horizontal tab container. - bool is_vertical = false; - LLTabContainer::TabPosition tab_position = LLTabContainer::TOP; - if (node->hasAttribute("tab_position")) + BOOL handled = LLPanel::handleToolTip( x, y, msg, sticky_rect ); + if (!handled && getTabCount() > 0) { - LLString tab_position_string; - node->getAttributeString("tab_position", tab_position_string); - LLString::toLower(tab_position_string); + LLTabTuple* firsttuple = getTab(0); - if ("top" == tab_position_string) - { - tab_position = LLTabContainer::TOP; - is_vertical = false; - } - else if ("bottom" == tab_position_string) + BOOL has_scroll_arrows = (getMaxScrollPos() > 0); + LLRect clip; + if (mIsVertical) { - tab_position = LLTabContainer::BOTTOM; - is_vertical = false; + clip = LLRect(firsttuple->mButton->getRect().mLeft, + has_scroll_arrows ? mPrevArrowBtn->getRect().mBottom - TABCNTRV_PAD : mPrevArrowBtn->getRect().mTop, + firsttuple->mButton->getRect().mRight, + has_scroll_arrows ? mNextArrowBtn->getRect().mTop + TABCNTRV_PAD : mNextArrowBtn->getRect().mBottom ); } - else if ("left" == tab_position_string) - { - is_vertical = true; - } - } - BOOL border = FALSE; - node->getAttributeBOOL("border", border); - - // Create the correct container type. - LLTabContainerCommon* tab_container = NULL; - - if (is_vertical) - { - // Vertical tabs can specify tab width - U32 tab_width = TABCNTRV_TAB_WIDTH; - if (node->hasAttribute("tab_width")) + else { - node->getAttributeU32("tab_width", tab_width); + clip = LLRect(has_scroll_arrows ? mPrevArrowBtn->getRect().mRight : mJumpPrevArrowBtn->getRect().mLeft, + firsttuple->mButton->getRect().mTop, + has_scroll_arrows ? mNextArrowBtn->getRect().mLeft : mJumpNextArrowBtn->getRect().mRight, + firsttuple->mButton->getRect().mBottom ); } - tab_container = new LLTabContainerVertical(name, - LLRect::null, - NULL, - NULL, - tab_width, - border); - - } - else // horizontal tab container - { - // Horizontal tabs can have a title (?) - LLString title(LLString::null); - if (node->hasAttribute("title")) + if( clip.pointInRect( x, y ) ) { - node->getAttributeString("title", title); + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + tuple->mButton->setVisible( TRUE ); + S32 local_x = x - tuple->mButton->getRect().mLeft; + S32 local_y = y - tuple->mButton->getRect().mBottom; + handled = tuple->mButton->handleToolTip( local_x, local_y, msg, sticky_rect ); + if( handled ) + { + break; + } + } } - tab_container = new LLTabContainer(name, - LLRect::null, - tab_position, - NULL, - NULL, - title, - border); - - if(node->hasAttribute("tab_min_width")) - { - S32 minTabWidth=0; - node->getAttributeS32("tab_min_width",minTabWidth); - ((LLTabContainer*)tab_container)->setMinTabWidth(minTabWidth); - } - if(node->hasAttribute("tab_max_width")) + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { - S32 maxTabWidth=0; - node->getAttributeS32("tab_max_width",maxTabWidth); - ((LLTabContainer*)tab_container)->setMaxTabWidth(maxTabWidth); + LLTabTuple* tuple = *iter; + tuple->mButton->setVisible( FALSE ); } } - - node->getAttributeBOOL("hide_tabs", tab_container->mTabsHidden); + return handled; +} - tab_container->setPanelParameters(node, parent); +// virtual +BOOL LLTabContainer::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) +{ + if (!getEnabled()) return FALSE; - if (LLFloater::getFloaterHost()) + if (!gFocusMgr.childHasKeyboardFocus(this)) return FALSE; + + BOOL handled = FALSE; + if (key == KEY_LEFT && mask == MASK_ALT) { - LLFloater::getFloaterHost()->setTabContainer(tab_container); + selectPrevTab(); + handled = TRUE; + } + else if (key == KEY_RIGHT && mask == MASK_ALT) + { + selectNextTab(); + handled = TRUE; } - //parent->addChild(tab_container); - - // Add all tab panels. - LLXMLNodePtr child; - for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) + if (handled) { - LLView *control = factory->createCtrlWidget(tab_container, child); - if (control && control->isPanel()) + if (getCurrentPanel()) { - LLPanel* panelp = (LLPanel*)control; - LLString label; - child->getAttributeString("label", label); - if (label.empty()) - { - label = panelp->getLabel(); - } - BOOL placeholder = FALSE; - child->getAttributeBOOL("placeholder", placeholder); - tab_container->addTabPanel(panelp, label.c_str(), false, - NULL, NULL, 0, placeholder); + getCurrentPanel()->setFocus(TRUE); } } - tab_container->selectFirstTab(); - - tab_container->postBuild(); - - tab_container->initButtons(); // now that we have the correct rect - - return tab_container; -} - -void LLTabContainerCommon::insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_point) -{ - switch(insertion_point) + if (!gFocusMgr.childHasKeyboardFocus(getCurrentPanel())) { - case START: - // insert the new tab in the front of the list - mTabList.insert(mTabList.begin() + mLockedTabCount, tuple); - break; - case LEFT_OF_CURRENT: - // insert the new tab before the current tab (but not before mLockedTabCount) + // if child has focus, but not the current panel, focus is on a button + if (mIsVertical) { - tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx); - mTabList.insert(current_iter, tuple); + switch(key) + { + case KEY_UP: + selectPrevTab(); + handled = TRUE; + break; + case KEY_DOWN: + selectNextTab(); + handled = TRUE; + break; + case KEY_LEFT: + handled = TRUE; + break; + case KEY_RIGHT: + if (getTabPosition() == LEFT && getCurrentPanel()) + { + getCurrentPanel()->setFocus(TRUE); + } + handled = TRUE; + break; + default: + break; + } } - break; - - case RIGHT_OF_CURRENT: - // insert the new tab after the current tab (but not before mLockedTabCount) + else { - tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx + 1); - mTabList.insert(current_iter, tuple); + switch(key) + { + case KEY_UP: + if (getTabPosition() == BOTTOM && getCurrentPanel()) + { + getCurrentPanel()->setFocus(TRUE); + } + handled = TRUE; + break; + case KEY_DOWN: + if (getTabPosition() == TOP && getCurrentPanel()) + { + getCurrentPanel()->setFocus(TRUE); + } + handled = TRUE; + break; + case KEY_LEFT: + selectPrevTab(); + handled = TRUE; + break; + case KEY_RIGHT: + selectNextTab(); + handled = TRUE; + break; + default: + break; + } } - break; - case END: - default: - mTabList.push_back( tuple ); } + return handled; } - -LLTabContainer::LLTabContainer( - const LLString& name, const LLRect& rect, TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - const LLString& title, BOOL bordered ) - : - LLTabContainerCommon(name, rect, pos, close_callback, callback_userdata, bordered), - mLeftArrowBtn(NULL), - mJumpLeftArrowBtn(NULL), - mRightArrowBtn(NULL), - mJumpRightArrowBtn(NULL), - mRightTabBtnOffset(0), - mMinTabWidth(TABCNTR_TAB_MIN_WIDTH), - mMaxTabWidth(TABCNTR_TAB_MAX_WIDTH), - mTotalTabWidth(0) -{ - initButtons( ); -} - -LLTabContainer::LLTabContainer( - const LLString& name, const LLString& rect_control, TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - const LLString& title, BOOL bordered ) - : - LLTabContainerCommon(name, rect_control, pos, close_callback, callback_userdata, bordered), - mLeftArrowBtn(NULL), - mJumpLeftArrowBtn(NULL), - mRightArrowBtn(NULL), - mJumpRightArrowBtn(NULL), - mRightTabBtnOffset(0), - mMinTabWidth(TABCNTR_TAB_MIN_WIDTH), - mMaxTabWidth(TABCNTR_TAB_MAX_WIDTH), - mTotalTabWidth(0) +// virtual +LLXMLNodePtr LLTabContainer::getXML(bool save_children) const { - initButtons( ); + LLXMLNodePtr node = LLPanel::getXML(); + node->createChild("tab_position", TRUE)->setStringValue((getTabPosition() == TOP ? "top" : "bottom")); + return node; } -void LLTabContainer::initButtons() +// virtual +BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType type, void* cargo_data, EAcceptance *accept, LLString &tooltip) { - // Hack: - if (mRect.getHeight() == 0 || mLeftArrowBtn) - { - return; // Don't have a rect yet or already got called - } - - LLString out_id; - LLString in_id; - - S32 arrow_fudge = 1; // match new art better + BOOL has_scroll_arrows = (getMaxScrollPos() > 0); - // tabs on bottom reserve room for resize handle (just in case) - if (mTabPosition == BOTTOM) + if( mDragAndDropDelayTimer.getElapsedTimeF32() > SCROLL_DELAY_TIME ) { - mRightTabBtnOffset = RESIZE_HANDLE_WIDTH; - } - - // Left and right scroll arrows (for when there are too many tabs to show all at once). - S32 btn_top = (mTabPosition == TOP ) ? mRect.getHeight() - mTopBorderHeight : TABCNTR_ARROW_BTN_SIZE + 1; - - LLRect left_arrow_btn_rect; - left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1+TABCNTR_ARROW_BTN_SIZE, btn_top + arrow_fudge, TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); - - LLRect jump_left_arrow_btn_rect; - jump_left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1, btn_top + arrow_fudge, TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); - - S32 right_pad = TABCNTR_ARROW_BTN_SIZE + LLPANEL_BORDER_WIDTH + 1; - - LLRect right_arrow_btn_rect; - right_arrow_btn_rect.setLeftTopAndSize( mRect.getWidth() - mRightTabBtnOffset - right_pad - TABCNTR_ARROW_BTN_SIZE, - btn_top + arrow_fudge, - TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); - - - LLRect jump_right_arrow_btn_rect; - jump_right_arrow_btn_rect.setLeftTopAndSize( mRect.getWidth() - mRightTabBtnOffset - right_pad, - btn_top + arrow_fudge, - TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); - - out_id = "UIImgBtnJumpLeftOutUUID"; - in_id = "UIImgBtnJumpLeftInUUID"; - mJumpLeftArrowBtn = new LLButton( - "Jump Left Arrow", jump_left_arrow_btn_rect, - out_id, in_id, "", - &LLTabContainer::onJumpFirstBtn, this, LLFontGL::sSansSerif ); - mJumpLeftArrowBtn->setFollowsLeft(); - mJumpLeftArrowBtn->setSaveToXML(false); - mJumpLeftArrowBtn->setTabStop(FALSE); - addChild(mJumpLeftArrowBtn); + if (has_scroll_arrows) + { + if (mJumpPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom; + mJumpPrevArrowBtn->handleHover(local_x, local_y, mask); + } + if (mJumpNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft; + S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom; + mJumpNextArrowBtn->handleHover(local_x, local_y, mask); + } + if (mPrevArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mPrevArrowBtn->getRect().mLeft; + S32 local_y = y - mPrevArrowBtn->getRect().mBottom; + mPrevArrowBtn->handleHover(local_x, local_y, mask); + } + else if (mNextArrowBtn->getRect().pointInRect(x, y)) + { + S32 local_x = x - mNextArrowBtn->getRect().mLeft; + S32 local_y = y - mNextArrowBtn->getRect().mBottom; + mNextArrowBtn->handleHover(local_x, local_y, mask); + } + } - out_id = "UIImgBtnScrollLeftOutUUID"; - in_id = "UIImgBtnScrollLeftInUUID"; - mLeftArrowBtn = new LLButton( - "Left Arrow", left_arrow_btn_rect, - out_id, in_id, "", - &LLTabContainer::onPrevBtn, this, LLFontGL::sSansSerif ); - mLeftArrowBtn->setHeldDownCallback(onPrevBtnHeld); - mLeftArrowBtn->setFollowsLeft(); - mLeftArrowBtn->setSaveToXML(false); - mLeftArrowBtn->setTabStop(FALSE); - addChild(mLeftArrowBtn); - - out_id = "UIImgBtnJumpRightOutUUID"; - in_id = "UIImgBtnJumpRightInUUID"; - mJumpRightArrowBtn = new LLButton( - "Jump Right Arrow", jump_right_arrow_btn_rect, - out_id, in_id, "", - &LLTabContainer::onJumpLastBtn, this, - LLFontGL::sSansSerif); - mJumpRightArrowBtn->setFollowsRight(); - mJumpRightArrowBtn->setSaveToXML(false); - mJumpRightArrowBtn->setTabStop(FALSE); - addChild(mJumpRightArrowBtn); - - out_id = "UIImgBtnScrollRightOutUUID"; - in_id = "UIImgBtnScrollRightInUUID"; - mRightArrowBtn = new LLButton( - "Right Arrow", right_arrow_btn_rect, - out_id, in_id, "", - &LLTabContainer::onNextBtn, this, - LLFontGL::sSansSerif); - mRightArrowBtn->setFollowsRight(); - mRightArrowBtn->setHeldDownCallback(onNextBtnHeld); - mRightArrowBtn->setSaveToXML(false); - mRightArrowBtn->setTabStop(FALSE); - addChild(mRightArrowBtn); - - - if( mTabPosition == TOP ) - { - mRightArrowBtn->setFollowsTop(); - mLeftArrowBtn->setFollowsTop(); - mJumpLeftArrowBtn->setFollowsTop(); - mJumpRightArrowBtn->setFollowsTop(); - } - else - { - mRightArrowBtn->setFollowsBottom(); - mLeftArrowBtn->setFollowsBottom(); - mJumpLeftArrowBtn->setFollowsBottom(); - mJumpRightArrowBtn->setFollowsBottom(); + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + tuple->mButton->setVisible( TRUE ); + S32 local_x = x - tuple->mButton->getRect().mLeft; + S32 local_y = y - tuple->mButton->getRect().mBottom; + if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible()) + { + tuple->mButton->onCommit(); + mDragAndDropDelayTimer.stop(); + } + } } - // set default tab group to be panel contents - mDefaultTabGroup = 1; -} - -LLTabContainer::~LLTabContainer() -{ + return LLView::handleDragAndDrop(x, y, mask, drop, type, cargo_data, accept, tooltip); } void LLTabContainer::addTabPanel(LLPanel* child, @@ -911,35 +687,49 @@ void LLTabContainer::addTabPanel(LLPanel* child, // already a child of mine return; } - const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); + const LLFontGL* font = gResMgr->getRes( mIsVertical ? LLFONT_SANSSERIF : LLFONT_SANSSERIF_SMALL ); // Store the original label for possible xml export. child->setLabel(label); LLString trimmed_label = label; LLString::trim(trimmed_label); - S32 button_width = llclamp(font->getWidth(trimmed_label) + TAB_PADDING, mMinTabWidth, mMaxTabWidth); - + S32 button_width = mMinTabWidth; + if (!mIsVertical) + { + button_width = llclamp(font->getWidth(trimmed_label) + TAB_PADDING, mMinTabWidth, mMaxTabWidth); + } + // Tab panel S32 tab_panel_top; S32 tab_panel_bottom; - if( LLTabContainer::TOP == mTabPosition ) + if( getTabPosition() == LLTabContainer::TOP ) { - tab_panel_top = mRect.getHeight() - mTopBorderHeight - (TABCNTR_TAB_HEIGHT - TABCNTR_BUTTON_PANEL_OVERLAP); + S32 tab_height = mIsVertical ? BTN_HEIGHT : TABCNTR_TAB_HEIGHT; + tab_panel_top = getRect().getHeight() - getTopBorderHeight() - (tab_height - TABCNTR_BUTTON_PANEL_OVERLAP); tab_panel_bottom = LLPANEL_BORDER_WIDTH; } else { - tab_panel_top = mRect.getHeight() - mTopBorderHeight; + tab_panel_top = getRect().getHeight() - getTopBorderHeight(); tab_panel_bottom = (TABCNTR_TAB_HEIGHT - TABCNTR_BUTTON_PANEL_OVERLAP); // Run to the edge, covering up the border } - LLRect tab_panel_rect( - LLPANEL_BORDER_WIDTH, - tab_panel_top, - mRect.getWidth()-LLPANEL_BORDER_WIDTH, - tab_panel_bottom ); - + LLRect tab_panel_rect; + if (mIsVertical) + { + tab_panel_rect = LLRect(mMinTabWidth + (LLPANEL_BORDER_WIDTH * 2) + TABCNTRV_PAD, + getRect().getHeight() - LLPANEL_BORDER_WIDTH, + getRect().getWidth() - LLPANEL_BORDER_WIDTH, + LLPANEL_BORDER_WIDTH); + } + else + { + tab_panel_rect = LLRect(LLPANEL_BORDER_WIDTH, + tab_panel_top, + getRect().getWidth()-LLPANEL_BORDER_WIDTH, + tab_panel_bottom ); + } child->setFollowsAll(); child->translate( tab_panel_rect.mLeft - child->getRect().mLeft, tab_panel_rect.mBottom - child->getRect().mBottom); child->reshape( tab_panel_rect.getWidth(), tab_panel_rect.getHeight(), TRUE ); @@ -956,9 +746,16 @@ void LLTabContainer::addTabPanel(LLPanel* child, LLString tab_selected_img; S32 tab_fudge = 1; // To make new tab art look better, nudge buttons up 1 pel - if( LLTabContainer::TOP == mTabPosition ) + if (mIsVertical) { - btn_rect.setLeftTopAndSize( 0, mRect.getHeight() - mTopBorderHeight + tab_fudge, button_width, TABCNTR_TAB_HEIGHT ); + btn_rect.setLeftTopAndSize(TABCNTRV_PAD + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor + (getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + TABCNTRV_PAD) * getTabCount()), + mMinTabWidth, + BTN_HEIGHT); + } + else if( getTabPosition() == LLTabContainer::TOP ) + { + btn_rect.setLeftTopAndSize( 0, getRect().getHeight() - getTopBorderHeight() + tab_fudge, button_width, TABCNTR_TAB_HEIGHT ); tab_img = "tab_top_blue.tga"; tab_selected_img = "tab_top_selected_blue.tga"; } @@ -969,185 +766,377 @@ void LLTabContainer::addTabPanel(LLPanel* child, tab_selected_img = "tab_bottom_selected_blue.tga"; } + LLTextBox* textbox = NULL; + LLButton* btn = NULL; + if (placeholder) { - // *FIX: wont work for horizontal tabs btn_rect.translate(0, -LLBUTTON_V_PAD-2); - LLString box_label = trimmed_label; - LLTextBox* text = new LLTextBox(box_label, btn_rect, box_label, font); - addChild( text, 0 ); - - LLButton* btn = new LLButton("", LLRect(0,0,0,0)); - LLTabTuple* tuple = new LLTabTuple( this, child, btn, on_tab_clicked, userdata, text ); - addChild( btn, 0 ); - addChild( child, 1 ); - insertTuple(tuple, insertion_point); + textbox = new LLTextBox(trimmed_label, btn_rect, trimmed_label, font); + + btn = new LLButton("", LLRect(0,0,0,0)); } else { - LLString tooltip = trimmed_label; - tooltip += "\nAlt-Left arrow for previous tab"; - tooltip += "\nAlt-Right arrow for next tab"; - - LLButton* btn = new LLButton( - LLString(child->getName()) + " tab", - btn_rect, - "", "", "", - &LLTabContainer::onTabBtn, NULL, // set userdata below - font, - trimmed_label, trimmed_label ); - btn->setSaveToXML(false); - btn->setVisible( FALSE ); - btn->setToolTip( tooltip ); - btn->setScaleImage(TRUE); - btn->setImages(tab_img, tab_selected_img); - - // Try to squeeze in a bit more text - btn->setLeftHPad( 4 ); - btn->setRightHPad( 2 ); - btn->setHAlign(LLFontGL::LEFT); - btn->setTabStop(FALSE); - if (indent) - { - btn->setLeftHPad(indent); - } - - if( mTabPosition == TOP ) + if (mIsVertical) { - btn->setFollowsTop(); + btn = new LLButton("vert tab button", + btn_rect, + "", + "", + "", + &LLTabContainer::onTabBtn, NULL, + font, + trimmed_label, trimmed_label); + btn->setImages("tab_left.tga", "tab_left_selected.tga"); + btn->setScaleImage(TRUE); + btn->setHAlign(LLFontGL::LEFT); + btn->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); + btn->setTabStop(FALSE); + if (indent) + { + btn->setLeftHPad(indent); + } } else { - btn->setFollowsBottom(); + LLString tooltip = trimmed_label; + tooltip += "\nAlt-Left arrow for previous tab"; + tooltip += "\nAlt-Right arrow for next tab"; + + btn = new LLButton(LLString(child->getName()) + " tab", + btn_rect, + "", "", "", + &LLTabContainer::onTabBtn, NULL, // set userdata below + font, + trimmed_label, trimmed_label ); + btn->setVisible( FALSE ); + btn->setToolTip( tooltip ); + btn->setScaleImage(TRUE); + btn->setImages(tab_img, tab_selected_img); + + // Try to squeeze in a bit more text + btn->setLeftHPad( 4 ); + btn->setRightHPad( 2 ); + btn->setHAlign(LLFontGL::LEFT); + btn->setTabStop(FALSE); + if (indent) + { + btn->setLeftHPad(indent); + } + + if( getTabPosition() == TOP ) + { + btn->setFollowsTop(); + } + else + { + btn->setFollowsBottom(); + } } + } + + LLTabTuple* tuple = new LLTabTuple( this, child, btn, on_tab_clicked, userdata, textbox ); + insertTuple( tuple, insertion_point ); - LLTabTuple* tuple = new LLTabTuple( this, child, btn, on_tab_clicked, userdata ); + if (textbox) + { + textbox->setSaveToXML(false); + addChild( textbox, 0 ); + } + if (btn) + { + btn->setSaveToXML(false); btn->setCallbackUserData( tuple ); addChild( btn, 0 ); - addChild( child, 1 ); - insertTuple(tuple, insertion_point); } - - updateMaxScrollPos(); - + if (child) + { + addChild(child, 1); + } + if( select ) { selectLastTab(); } + + updateMaxScrollPos(); +} + +void LLTabContainer::addPlaceholder(LLPanel* child, const LLString& label) +{ + addTabPanel(child, label, FALSE, NULL, NULL, 0, TRUE); } void LLTabContainer::removeTabPanel(LLPanel* child) { - // Adjust the total tab width. - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + if (mIsVertical) + { + // Fix-up button sizes + S32 tab_count = 0; + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + LLRect rect; + rect.setLeftTopAndSize(TABCNTRV_PAD + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor + (getRect().getHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + TABCNTRV_PAD) * (tab_count)), + mMinTabWidth, + BTN_HEIGHT); + if (tuple->mPlaceholderText) + { + tuple->mPlaceholderText->setRect(rect); + } + else + { + tuple->mButton->setRect(rect); + } + tab_count++; + } + } + else + { + // Adjust the total tab width. + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + if( tuple->mTabPanel == child ) + { + mTotalTabWidth -= tuple->mButton->getRect().getWidth(); + break; + } + } + } + + BOOL has_focus = gFocusMgr.childHasKeyboardFocus(this); + + // If the tab being deleted is the selected one, select a different tab. + for(std::vector::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { LLTabTuple* tuple = *iter; if( tuple->mTabPanel == child ) { - mTotalTabWidth -= tuple->mButton->getRect().getWidth(); + removeChild( tuple->mButton ); + delete tuple->mButton; + + removeChild( tuple->mTabPanel ); +// delete tuple->mTabPanel; + + mTabList.erase( iter ); + delete tuple; + break; } } - LLTabContainerCommon::removeTabPanel(child); + // make sure we don't have more locked tabs than we have tabs + mLockedTabCount = llmin(getTabCount(), mLockedTabCount); + + if (mCurrentTabIdx >= (S32)mTabList.size()) + { + mCurrentTabIdx = mTabList.size()-1; + } + selectTab(mCurrentTabIdx); + if (has_focus) + { + LLPanel* panelp = getPanelByIndex(mCurrentTabIdx); + if (panelp) + { + panelp->setFocus(TRUE); + } + } + + updateMaxScrollPos(); } -void LLTabContainer::setPanelTitle(S32 index, const LLString& title) +void LLTabContainer::lockTabs(S32 num_tabs) { - if (index >= 0 && index < (S32)mTabList.size()) + // count current tabs or use supplied value and ensure no new tabs get + // inserted between them + mLockedTabCount = num_tabs > 0 ? llmin(getTabCount(), num_tabs) : getTabCount(); +} + +void LLTabContainer::unlockTabs() +{ + mLockedTabCount = 0; +} + +void LLTabContainer::enableTabButton(S32 which, BOOL enable) +{ + if (which >= 0 && which < (S32)mTabList.size()) { - LLTabTuple* tuple = mTabList[index]; - LLButton* tab_button = tuple->mButton; - const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); - mTotalTabWidth -= tab_button->getRect().getWidth(); - tab_button->reshape(llclamp(fontp->getWidth(title) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight()); - mTotalTabWidth += tab_button->getRect().getWidth(); - tab_button->setLabelSelected(title); - tab_button->setLabelUnselected(title); + mTabList[which]->mButton->setEnabled(enable); } - updateMaxScrollPos(); } +void LLTabContainer::deleteAllTabs() +{ + // Remove all the tab buttons and delete them. Also, unlink all the child panels. + for(std::vector::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; -void LLTabContainer::updateMaxScrollPos() + removeChild( tuple->mButton ); + delete tuple->mButton; + + removeChild( tuple->mTabPanel ); +// delete tuple->mTabPanel; + } + + // Actually delete the tuples themselves + std::for_each(mTabList.begin(), mTabList.end(), DeletePointer()); + mTabList.clear(); + + // And there isn't a current tab any more + mCurrentTabIdx = -1; +} + +LLPanel* LLTabContainer::getCurrentPanel() +{ + if (mCurrentTabIdx >= 0 && mCurrentTabIdx < (S32) mTabList.size()) + { + return mTabList[mCurrentTabIdx]->mTabPanel; + } + return NULL; +} + +S32 LLTabContainer::getCurrentPanelIndex() +{ + return mCurrentTabIdx; +} + +S32 LLTabContainer::getTabCount() { - S32 tab_space = 0; - S32 available_space = 0; - tab_space = mTotalTabWidth; - available_space = mRect.getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_TAB_H_PAD); + return mTabList.size(); +} - if( tab_space > available_space ) +LLPanel* LLTabContainer::getPanelByIndex(S32 index) +{ + if (index >= 0 && index < (S32)mTabList.size()) { - S32 available_width_with_arrows = mRect.getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); - // subtract off reserved portion on left - available_width_with_arrows -= TABCNTR_TAB_PARTIAL_WIDTH; + return mTabList[index]->mTabPanel; + } + return NULL; +} - S32 running_tab_width = 0; - mMaxScrollPos = mTabList.size(); - for(tuple_list_t::reverse_iterator tab_it = mTabList.rbegin(); tab_it != mTabList.rend(); ++tab_it) +S32 LLTabContainer::getIndexForPanel(LLPanel* panel) +{ + for (S32 index = 0; index < (S32)mTabList.size(); index++) + { + if (mTabList[index]->mTabPanel == panel) { - running_tab_width += (*tab_it)->mButton->getRect().getWidth(); - if (running_tab_width > available_width_with_arrows) - { - break; - } - mMaxScrollPos--; + return index; } - // in case last tab doesn't actually fit on screen, make it the last scrolling position - mMaxScrollPos = llmin(mMaxScrollPos, (S32)mTabList.size() - 1); } - else - { - mMaxScrollPos = 0; - mScrollPos = 0; - } - if (mScrollPos > mMaxScrollPos) + return -1; +} + +S32 LLTabContainer::getPanelIndexByTitle(const LLString& title) +{ + for (S32 index = 0 ; index < (S32)mTabList.size(); index++) { - mScrollPos = mMaxScrollPos; + if (title == mTabList[index]->mButton->getLabelSelected()) + { + return index; + } } + return -1; } -void LLTabContainer::commitHoveredButton(S32 x, S32 y) +LLPanel *LLTabContainer::getPanelByName(const LLString& name) { - if (hasMouseCapture()) + for (S32 index = 0 ; index < (S32)mTabList.size(); index++) { - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + LLPanel *panel = mTabList[index]->mTabPanel; + if (name == panel->getName()) { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( TRUE ); - S32 local_x = x - tuple->mButton->getRect().mLeft; - S32 local_y = y - tuple->mButton->getRect().mBottom; - if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible()) - { - tuple->mButton->onCommit(); - } + return panel; } } -} - -void LLTabContainer::setMinTabWidth(S32 width) -{ - mMinTabWidth = width; -} - -void LLTabContainer::setMaxTabWidth(S32 width) -{ - mMaxTabWidth = width; -} - -S32 LLTabContainer::getMinTabWidth() const -{ - return mMinTabWidth; -} + return NULL; +} + +// Change the name of the button for the current tab. +void LLTabContainer::setCurrentTabName(const LLString& name) +{ + // Might not have a tab selected + if (mCurrentTabIdx < 0) return; + + mTabList[mCurrentTabIdx]->mButton->setLabelSelected(name); + mTabList[mCurrentTabIdx]->mButton->setLabelUnselected(name); +} + +void LLTabContainer::selectFirstTab() +{ + selectTab( 0 ); +} + + +void LLTabContainer::selectLastTab() +{ + selectTab( mTabList.size()-1 ); +} + +void LLTabContainer::selectNextTab() +{ + BOOL tab_has_focus = FALSE; + if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus()) + { + tab_has_focus = TRUE; + } + S32 idx = mCurrentTabIdx+1; + if (idx >= (S32)mTabList.size()) + idx = 0; + while (!selectTab(idx) && idx != mCurrentTabIdx) + { + idx = (idx + 1 ) % (S32)mTabList.size(); + } + + if (tab_has_focus) + { + mTabList[idx]->mButton->setFocus(TRUE); + } +} + +void LLTabContainer::selectPrevTab() +{ + BOOL tab_has_focus = FALSE; + if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus()) + { + tab_has_focus = TRUE; + } + S32 idx = mCurrentTabIdx-1; + if (idx < 0) + idx = mTabList.size()-1; + while (!selectTab(idx) && idx != mCurrentTabIdx) + { + idx = idx - 1; + if (idx < 0) + idx = mTabList.size()-1; + } + if (tab_has_focus) + { + mTabList[idx]->mButton->setFocus(TRUE); + } +} -S32 LLTabContainer::getMaxTabWidth() const +BOOL LLTabContainer::selectTabPanel(LLPanel* child) { - return mMaxTabWidth; + S32 idx = 0; + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + if( tuple->mTabPanel == child ) + { + return selectTab( idx ); + } + idx++; + } + return FALSE; } BOOL LLTabContainer::selectTab(S32 which) { - if (which >= (S32)mTabList.size()) return FALSE; + if (which >= getTabCount()) return FALSE; if (which < 0) return FALSE; //if( gFocusMgr.childHasKeyboardFocus( this ) ) @@ -1155,15 +1144,16 @@ BOOL LLTabContainer::selectTab(S32 which) // gFocusMgr.setKeyboardFocus( NULL ); //} - LLTabTuple* selected_tuple = mTabList[which]; + LLTabTuple* selected_tuple = getTab(which); if (!selected_tuple) { return FALSE; } - if (mTabList[which]->mButton->getEnabled()) + BOOL is_visible = FALSE; + if (getTab(which)->mButton->getEnabled()) { - mCurrentTabIdx = which; + setCurrentPanelIndex(which); S32 i = 0; for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) @@ -1176,35 +1166,52 @@ BOOL LLTabContainer::selectTab(S32 which) // RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs tuple->mButton->setTabStop( is_selected ); - if( is_selected && mMaxScrollPos > 0) + if( is_selected && (mIsVertical || (getMaxScrollPos() > 0))) { // Make sure selected tab is within scroll region - if( i < mScrollPos ) + if (mIsVertical) { - mScrollPos = i; + S32 num_visible = getTabCount() - getMaxScrollPos(); + if( i >= getScrollPos() && i <= getScrollPos() + num_visible) + { + setCurrentPanelIndex(which); + is_visible = TRUE; + } + else + { + is_visible = FALSE; + } } else { - S32 available_width_with_arrows = mRect.getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); - S32 running_tab_width = tuple->mButton->getRect().getWidth(); - S32 j = i - 1; - S32 min_scroll_pos = i; - if (running_tab_width < available_width_with_arrows) + if( i < getScrollPos() ) + { + setScrollPos(i); + } + else { - while (j >= 0) + S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); + S32 running_tab_width = tuple->mButton->getRect().getWidth(); + S32 j = i - 1; + S32 min_scroll_pos = i; + if (running_tab_width < available_width_with_arrows) { - LLTabTuple* other_tuple = mTabList[j]; - running_tab_width += other_tuple->mButton->getRect().getWidth(); - if (running_tab_width > available_width_with_arrows) + while (j >= 0) { - break; + LLTabTuple* other_tuple = getTab(j); + running_tab_width += other_tuple->mButton->getRect().getWidth(); + if (running_tab_width > available_width_with_arrows) + { + break; + } + j--; } - j--; + min_scroll_pos = j + 1; } - min_scroll_pos = j + 1; + setScrollPos(llclamp(getScrollPos(), min_scroll_pos, i)); + setScrollPos(llmin(getScrollPos(), getMaxScrollPos())); } - mScrollPos = llclamp(mScrollPos, min_scroll_pos, i); - mScrollPos = llmin(mScrollPos, mMaxScrollPos); + is_visible = TRUE; } } i++; @@ -1213,463 +1220,595 @@ BOOL LLTabContainer::selectTab(S32 which) { selected_tuple->mOnChangeCallback( selected_tuple->mUserData, false ); } - return TRUE; } - else + if (mIsVertical && getCurrentPanelIndex() >= 0) { - return FALSE; + LLTabTuple* tuple = getTab(getCurrentPanelIndex()); + tuple->mTabPanel->setVisible( TRUE ); + tuple->mButton->setToggleState( TRUE ); } + return is_visible; } -void LLTabContainer::draw() +BOOL LLTabContainer::selectTabByName(const LLString& name) { - S32 target_pixel_scroll = 0; - S32 cur_scroll_pos = mScrollPos; - if (cur_scroll_pos > 0) + LLPanel* panel = getPanelByName(name); + if (!panel) { - S32 available_width_with_arrows = mRect.getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - if (cur_scroll_pos == 0) - { - break; - } - target_pixel_scroll += (*iter)->mButton->getRect().getWidth(); - cur_scroll_pos--; - } + llwarns << "LLTabContainer::selectTabByName(" + << name << ") failed" << llendl; + return FALSE; + } - // Show part of the tab to the left of what is fully visible - target_pixel_scroll -= TABCNTR_TAB_PARTIAL_WIDTH; - // clamp so that rightmost tab never leaves right side of screen - target_pixel_scroll = llmin(mTotalTabWidth - available_width_with_arrows, target_pixel_scroll); + BOOL result = selectTabPanel(panel); + return result; +} + +BOOL LLTabContainer::getTabPanelFlashing(LLPanel *child) +{ + LLTabTuple* tuple = getTabByPanel(child); + if( tuple ) + { + return tuple->mButton->getFlashing(); } + return FALSE; +} - mScrollPosPixels = (S32)lerp((F32)mScrollPosPixels, (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f)); - if( getVisible() ) +void LLTabContainer::setTabPanelFlashing(LLPanel* child, BOOL state ) +{ + LLTabTuple* tuple = getTabByPanel(child); + if( tuple ) { - BOOL has_scroll_arrows = (mMaxScrollPos > 0) || (mScrollPosPixels > 0); - mJumpLeftArrowBtn->setVisible( has_scroll_arrows ); - mJumpRightArrowBtn->setVisible( has_scroll_arrows ); - mLeftArrowBtn->setVisible( has_scroll_arrows ); - mRightArrowBtn->setVisible( has_scroll_arrows ); + tuple->mButton->setFlashing( state ); + } +} - // Set the leftmost position of the tab buttons. - S32 left = LLPANEL_BORDER_WIDTH + (has_scroll_arrows ? (TABCNTR_ARROW_BTN_SIZE * 2) : TABCNTR_TAB_H_PAD); - left -= mScrollPosPixels; +void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const LLColor4& color) +{ + LLTabTuple* tuple = getTabByPanel(child); + if( tuple ) + { + tuple->mButton->setImageOverlay(image_name, LLFontGL::RIGHT, color); - // Hide all the buttons - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + if (!mIsVertical) { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( FALSE ); - } + const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); + // remove current width from total tab strip width + mTotalTabWidth -= tuple->mButton->getRect().getWidth(); - LLPanel::draw(); + S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? + tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : + 0; - // if tabs are hidden, don't draw them and leave them in the invisible state - if (!mTabsHidden) - { - // Show all the buttons - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( TRUE ); - } + tuple->mPadding = image_overlay_width; - // Draw some of the buttons... - LLRect clip_rect = getLocalRect(); - if (has_scroll_arrows) - { - // ...but clip them. - clip_rect.mLeft = mLeftArrowBtn->getRect().mRight; - clip_rect.mRight = mRightArrowBtn->getRect().mLeft; - } - LLLocalClipRect clip(clip_rect); + tuple->mButton->setRightHPad(6); + tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), + tuple->mButton->getRect().getHeight()); + // add back in button width to total tab strip width + mTotalTabWidth += tuple->mButton->getRect().getWidth(); - S32 max_scroll_visible = mTabList.size() - mMaxScrollPos + mScrollPos; - S32 idx = 0; - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; + // tabs have changed size, might need to scroll to see current tab + updateMaxScrollPos(); + } + } +} - tuple->mButton->translate( left - tuple->mButton->getRect().mLeft, 0 ); - left += tuple->mButton->getRect().getWidth(); +void LLTabContainer::setTitle(const LLString& title) +{ + if (mTitleBox) + { + mTitleBox->setText( title ); + } +} - if( idx < mScrollPos ) - { - if( tuple->mButton->getFlashing() ) - { - mLeftArrowBtn->setFlashing( TRUE ); - } - } - else - if( max_scroll_visible < idx ) - { - if( tuple->mButton->getFlashing() ) - { - mRightArrowBtn->setFlashing( TRUE ); - } - } +const LLString LLTabContainer::getPanelTitle(S32 index) +{ + if (index >= 0 && index < (S32)mTabList.size()) + { + LLButton* tab_button = mTabList[index]->mButton; + return tab_button->getLabelSelected(); + } + return LLString::null; +} - LLUI::pushMatrix(); - { - LLUI::translate((F32)tuple->mButton->getRect().mLeft, (F32)tuple->mButton->getRect().mBottom, 0.f); - tuple->mButton->draw(); - } - LLUI::popMatrix(); - - idx++; - } - } +void LLTabContainer::setTopBorderHeight(S32 height) +{ + mTopBorderHeight = height; +} + +S32 LLTabContainer::getTopBorderHeight() const +{ + return mTopBorderHeight; +} - mLeftArrowBtn->setFlashing(FALSE); - mRightArrowBtn->setFlashing(FALSE); +void LLTabContainer::setTabChangeCallback(LLPanel* tab, void (*on_tab_clicked)(void*, bool)) +{ + LLTabTuple* tuplep = getTabByPanel(tab); + if (tuplep) + { + tuplep->mOnChangeCallback = on_tab_clicked; } } +void LLTabContainer::setTabUserData(LLPanel* tab, void* userdata) +{ + LLTabTuple* tuplep = getTabByPanel(tab); + if (tuplep) + { + tuplep->mUserData = userdata; + } +} void LLTabContainer::setRightTabBtnOffset(S32 offset) { - mRightArrowBtn->translate( -offset - mRightTabBtnOffset, 0 ); + mNextArrowBtn->translate( -offset - mRightTabBtnOffset, 0 ); mRightTabBtnOffset = offset; updateMaxScrollPos(); } -BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) +void LLTabContainer::setPanelTitle(S32 index, const LLString& title) { - BOOL handled = FALSE; - BOOL has_scroll_arrows = (mMaxScrollPos > 0); + if (index >= 0 && index < getTabCount()) + { + LLTabTuple* tuple = getTab(index); + LLButton* tab_button = tuple->mButton; + const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); + mTotalTabWidth -= tab_button->getRect().getWidth(); + tab_button->reshape(llclamp(fontp->getWidth(title) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight()); + mTotalTabWidth += tab_button->getRect().getWidth(); + tab_button->setLabelSelected(title); + tab_button->setLabelUnselected(title); + } + updateMaxScrollPos(); +} - if (has_scroll_arrows) - { - if (mJumpLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpLeftArrowBtn->getRect().mBottom; - handled = mJumpLeftArrowBtn->handleMouseDown(local_x, local_y, mask); - } - if (mJumpRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpRightArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpRightArrowBtn->getRect().mBottom; - handled = mJumpRightArrowBtn->handleMouseDown(local_x, local_y, mask); - } - if (mLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mLeftArrowBtn->getRect().mBottom; - handled = mLeftArrowBtn->handleMouseDown(local_x, local_y, mask); - } - else if (mRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mRightArrowBtn->getRect().mLeft; - S32 local_y = y - mRightArrowBtn->getRect().mBottom; - handled = mRightArrowBtn->handleMouseDown(local_x, local_y, mask); - } + +// static +void LLTabContainer::onTabBtn( void* userdata ) +{ + LLTabTuple* tuple = (LLTabTuple*) userdata; + LLTabContainer* self = tuple->mTabContainer; + self->selectTabPanel( tuple->mTabPanel ); + + if( tuple->mOnChangeCallback ) + { + tuple->mOnChangeCallback( tuple->mUserData, true ); } - if (!handled) + + tuple->mTabPanel->setFocus(TRUE); +} + +// static +void LLTabContainer::onCloseBtn( void* userdata ) +{ + LLTabContainer* self = (LLTabContainer*) userdata; + if( self->mCloseCallback ) { - handled = LLPanel::handleMouseDown( x, y, mask ); + self->mCloseCallback( self->mCallbackUserdata ); } +} - if (mTabList.size() > 0) +// static +void LLTabContainer::onNextBtn( void* userdata ) +{ + // Scroll tabs to the left + LLTabContainer* self = (LLTabContainer*) userdata; + if (!self->mScrolled) { - LLTabTuple* firsttuple = mTabList[0]; - LLRect tab_rect(has_scroll_arrows ? mLeftArrowBtn->getRect().mRight : mJumpLeftArrowBtn->getRect().mLeft, - firsttuple->mButton->getRect().mTop, - has_scroll_arrows ? mRightArrowBtn->getRect().mLeft : mJumpRightArrowBtn->getRect().mRight, - firsttuple->mButton->getRect().mBottom ); - if( tab_rect.pointInRect( x, y ) ) - { - LLButton* tab_button = mTabList[getCurrentPanelIndex()]->mButton; - gFocusMgr.setMouseCapture(this); - gFocusMgr.setKeyboardFocus(tab_button); - } + self->scrollNext(); } - return handled; + self->mScrolled = FALSE; } -BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask ) +// static +void LLTabContainer::onNextBtnHeld( void* userdata ) { - BOOL handled = FALSE; - BOOL has_scroll_arrows = (mMaxScrollPos > 0); + LLTabContainer* self = (LLTabContainer*) userdata; + if (self->mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME) + { + self->mScrollTimer.reset(); + self->scrollNext(); + self->mScrolled = TRUE; + } +} - if (has_scroll_arrows) - { - if (mJumpLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpLeftArrowBtn->getRect().mBottom; - handled = mJumpLeftArrowBtn->handleHover(local_x, local_y, mask); - } - if (mJumpRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpRightArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpRightArrowBtn->getRect().mBottom; - handled = mJumpRightArrowBtn->handleHover(local_x, local_y, mask); - } - if (mLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mLeftArrowBtn->getRect().mBottom; - handled = mLeftArrowBtn->handleHover(local_x, local_y, mask); - } - else if (mRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mRightArrowBtn->getRect().mLeft; - S32 local_y = y - mRightArrowBtn->getRect().mBottom; - handled = mRightArrowBtn->handleHover(local_x, local_y, mask); - } +// static +void LLTabContainer::onPrevBtn( void* userdata ) +{ + LLTabContainer* self = (LLTabContainer*) userdata; + if (!self->mScrolled) + { + self->scrollPrev(); } - if (!handled) + self->mScrolled = FALSE; +} + +// static +void LLTabContainer::onJumpFirstBtn( void* userdata ) +{ + LLTabContainer* self = (LLTabContainer*) userdata; + self->mScrollPos = 0; +} + +// static +void LLTabContainer::onJumpLastBtn( void* userdata ) +{ + LLTabContainer* self = (LLTabContainer*) userdata; + self->mScrollPos = self->mMaxScrollPos; +} + +// static +void LLTabContainer::onPrevBtnHeld( void* userdata ) +{ + LLTabContainer* self = (LLTabContainer*) userdata; + if (self->mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME) { - handled = LLPanel::handleHover(x, y, mask); + self->mScrollTimer.reset(); + self->scrollPrev(); + self->mScrolled = TRUE; } - - commitHoveredButton(x, y); - return handled; } -BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask ) +// static +LLView* LLTabContainer::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) { - BOOL handled = FALSE; - BOOL has_scroll_arrows = (mMaxScrollPos > 0); + LLString name("tab_container"); + node->getAttributeString("name", name); - if (has_scroll_arrows) + // Figure out if we are creating a vertical or horizontal tab container. + bool is_vertical = false; + LLTabContainer::TabPosition tab_position = LLTabContainer::TOP; + if (node->hasAttribute("tab_position")) { - if (mJumpLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpLeftArrowBtn->getRect().mBottom; - handled = mJumpLeftArrowBtn->handleMouseUp(local_x, local_y, mask); - } - if (mJumpRightArrowBtn->getRect().pointInRect(x, y)) + LLString tab_position_string; + node->getAttributeString("tab_position", tab_position_string); + LLString::toLower(tab_position_string); + + if ("top" == tab_position_string) { - S32 local_x = x - mJumpRightArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpRightArrowBtn->getRect().mBottom; - handled = mJumpRightArrowBtn->handleMouseUp(local_x, local_y, mask); + tab_position = LLTabContainer::TOP; + is_vertical = false; } - if (mLeftArrowBtn->getRect().pointInRect(x, y)) + else if ("bottom" == tab_position_string) { - S32 local_x = x - mLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mLeftArrowBtn->getRect().mBottom; - handled = mLeftArrowBtn->handleMouseUp(local_x, local_y, mask); + tab_position = LLTabContainer::BOTTOM; + is_vertical = false; } - else if (mRightArrowBtn->getRect().pointInRect(x, y)) + else if ("left" == tab_position_string) { - S32 local_x = x - mRightArrowBtn->getRect().mLeft; - S32 local_y = y - mRightArrowBtn->getRect().mBottom; - handled = mRightArrowBtn->handleMouseUp(local_x, local_y, mask); + is_vertical = true; } } - if (!handled) + BOOL border = FALSE; + node->getAttributeBOOL("border", border); + + LLTabContainer* tab_container = new LLTabContainer(name, LLRect::null, tab_position, border, is_vertical); + + S32 tab_min_width = tab_container->mMinTabWidth; + if (node->hasAttribute("tab_width")) { - handled = LLPanel::handleMouseUp( x, y, mask ); + node->getAttributeS32("tab_width", tab_min_width); + } + else if( node->hasAttribute("tab_min_width")) + { + node->getAttributeS32("tab_min_width", tab_min_width); } - commitHoveredButton(x, y); - LLPanel* cur_panel = getCurrentPanel(); - if (hasMouseCapture()) + S32 tab_max_width = tab_container->mMaxTabWidth; + if (node->hasAttribute("tab_max_width")) { - if (cur_panel) + node->getAttributeS32("tab_max_width", tab_max_width); + } + + tab_container->setMinTabWidth(tab_min_width); + tab_container->setMaxTabWidth(tab_max_width); + + BOOL hidden(tab_container->getTabsHidden()); + node->getAttributeBOOL("hide_tabs", hidden); + tab_container->setTabsHidden(hidden); + + tab_container->setPanelParameters(node, parent); + + if (LLFloater::getFloaterHost()) + { + LLFloater::getFloaterHost()->setTabContainer(tab_container); + } + + //parent->addChild(tab_container); + + // Add all tab panels. + LLXMLNodePtr child; + for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) + { + LLView *control = factory->createCtrlWidget(tab_container, child); + if (control && control->isPanel()) { - if (!cur_panel->focusFirstItem(FALSE)) + LLPanel* panelp = (LLPanel*)control; + LLString label; + child->getAttributeString("label", label); + if (label.empty()) { - // if nothing in the panel gets focus, make sure the new tab does - // otherwise the last tab might keep focus - mTabList[getCurrentPanelIndex()]->mButton->setFocus(TRUE); + label = panelp->getLabel(); } + BOOL placeholder = FALSE; + child->getAttributeBOOL("placeholder", placeholder); + tab_container->addTabPanel(panelp, label.c_str(), false, + NULL, NULL, 0, placeholder); } - gFocusMgr.setMouseCapture(NULL); } - return handled; + + tab_container->selectFirstTab(); + + tab_container->postBuild(); + + tab_container->initButtons(); // now that we have the correct rect + + return tab_container; } -BOOL LLTabContainer::handleToolTip( S32 x, S32 y, LLString& msg, LLRect* sticky_rect ) +// private + +void LLTabContainer::initButtons() { - BOOL handled = LLPanel::handleToolTip( x, y, msg, sticky_rect ); - if (!handled && mTabList.size() > 0) + // Hack: + if (getRect().getHeight() == 0 || mPrevArrowBtn) { - LLTabTuple* firsttuple = mTabList[0]; + return; // Don't have a rect yet or already got called + } + + LLString out_id; + LLString in_id; - BOOL has_scroll_arrows = (mMaxScrollPos > 0); - LLRect clip( - has_scroll_arrows ? mJumpLeftArrowBtn->getRect().mRight : mJumpLeftArrowBtn->getRect().mLeft, - firsttuple->mButton->getRect().mTop, - has_scroll_arrows ? mRightArrowBtn->getRect().mLeft : mRightArrowBtn->getRect().mRight, - 0 ); - if( clip.pointInRect( x, y ) ) + if (mIsVertical) + { + // Left and right scroll arrows (for when there are too many tabs to show all at once). + S32 btn_top = getRect().getHeight(); + S32 btn_top_lower = getRect().mBottom+TABCNTRV_ARROW_BTN_SIZE; + + LLRect up_arrow_btn_rect; + up_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top, TABCNTRV_ARROW_BTN_SIZE, TABCNTRV_ARROW_BTN_SIZE ); + + LLRect down_arrow_btn_rect; + down_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top_lower, TABCNTRV_ARROW_BTN_SIZE, TABCNTRV_ARROW_BTN_SIZE ); + + out_id = "UIImgBtnScrollUpOutUUID"; + in_id = "UIImgBtnScrollUpInUUID"; + mPrevArrowBtn = new LLButton("Up Arrow", up_arrow_btn_rect, + out_id, in_id, "", + &onPrevBtn, this, NULL ); + mPrevArrowBtn->setFollowsTop(); + mPrevArrowBtn->setFollowsLeft(); + + out_id = "UIImgBtnScrollDownOutUUID"; + in_id = "UIImgBtnScrollDownInUUID"; + mNextArrowBtn = new LLButton("Down Arrow", down_arrow_btn_rect, + out_id, in_id, "", + &onNextBtn, this, NULL ); + mNextArrowBtn->setFollowsBottom(); + mNextArrowBtn->setFollowsLeft(); + } + else // Horizontal + { + S32 arrow_fudge = 1; // match new art better + + // tabs on bottom reserve room for resize handle (just in case) + if (getTabPosition() == BOTTOM) { - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( TRUE ); - S32 local_x = x - tuple->mButton->getRect().mLeft; - S32 local_y = y - tuple->mButton->getRect().mBottom; - handled = tuple->mButton->handleToolTip( local_x, local_y, msg, sticky_rect ); - if( handled ) - { - break; - } - } + mRightTabBtnOffset = RESIZE_HANDLE_WIDTH; } - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + // Left and right scroll arrows (for when there are too many tabs to show all at once). + S32 btn_top = (getTabPosition() == TOP ) ? getRect().getHeight() - getTopBorderHeight() : TABCNTR_ARROW_BTN_SIZE + 1; + + LLRect left_arrow_btn_rect; + left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1+TABCNTR_ARROW_BTN_SIZE, btn_top + arrow_fudge, TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); + + LLRect jump_left_arrow_btn_rect; + jump_left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1, btn_top + arrow_fudge, TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); + + S32 right_pad = TABCNTR_ARROW_BTN_SIZE + LLPANEL_BORDER_WIDTH + 1; + + LLRect right_arrow_btn_rect; + right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad - TABCNTR_ARROW_BTN_SIZE, + btn_top + arrow_fudge, + TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); + + + LLRect jump_right_arrow_btn_rect; + jump_right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad, + btn_top + arrow_fudge, + TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); + + out_id = "UIImgBtnJumpLeftOutUUID"; + in_id = "UIImgBtnJumpLeftInUUID"; + mJumpPrevArrowBtn = new LLButton("Jump Left Arrow", jump_left_arrow_btn_rect, + out_id, in_id, "", + &LLTabContainer::onJumpFirstBtn, this, LLFontGL::sSansSerif ); + mJumpPrevArrowBtn->setFollowsLeft(); + + out_id = "UIImgBtnScrollLeftOutUUID"; + in_id = "UIImgBtnScrollLeftInUUID"; + mPrevArrowBtn = new LLButton("Left Arrow", left_arrow_btn_rect, + out_id, in_id, "", + &LLTabContainer::onPrevBtn, this, LLFontGL::sSansSerif ); + mPrevArrowBtn->setHeldDownCallback(onPrevBtnHeld); + mPrevArrowBtn->setFollowsLeft(); + + out_id = "UIImgBtnJumpRightOutUUID"; + in_id = "UIImgBtnJumpRightInUUID"; + mJumpNextArrowBtn = new LLButton("Jump Right Arrow", jump_right_arrow_btn_rect, + out_id, in_id, "", + &LLTabContainer::onJumpLastBtn, this, + LLFontGL::sSansSerif); + mJumpNextArrowBtn->setFollowsRight(); + + out_id = "UIImgBtnScrollRightOutUUID"; + in_id = "UIImgBtnScrollRightInUUID"; + mNextArrowBtn = new LLButton("Right Arrow", right_arrow_btn_rect, + out_id, in_id, "", + &LLTabContainer::onNextBtn, this, + LLFontGL::sSansSerif); + mNextArrowBtn->setFollowsRight(); + + if( getTabPosition() == TOP ) { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( FALSE ); + mNextArrowBtn->setFollowsTop(); + mPrevArrowBtn->setFollowsTop(); + mJumpPrevArrowBtn->setFollowsTop(); + mJumpNextArrowBtn->setFollowsTop(); + } + else + { + mNextArrowBtn->setFollowsBottom(); + mPrevArrowBtn->setFollowsBottom(); + mJumpPrevArrowBtn->setFollowsBottom(); + mJumpNextArrowBtn->setFollowsBottom(); } } - return handled; -} -BOOL LLTabContainer::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) -{ - if (!getEnabled()) return FALSE; + mPrevArrowBtn->setHeldDownCallback(onPrevBtnHeld); + mPrevArrowBtn->setSaveToXML(false); + mPrevArrowBtn->setTabStop(FALSE); + addChild(mPrevArrowBtn); - if (!gFocusMgr.childHasKeyboardFocus(this)) return FALSE; + mNextArrowBtn->setHeldDownCallback(onNextBtnHeld); + mNextArrowBtn->setSaveToXML(false); + mNextArrowBtn->setTabStop(FALSE); + addChild(mNextArrowBtn); - BOOL handled = FALSE; - if (key == KEY_LEFT && mask == MASK_ALT) + if (mJumpPrevArrowBtn) { - selectPrevTab(); - handled = TRUE; + mJumpPrevArrowBtn->setSaveToXML(false); + mJumpPrevArrowBtn->setTabStop(FALSE); + addChild(mJumpPrevArrowBtn); } - else if (key == KEY_RIGHT && mask == MASK_ALT) + + if (mJumpNextArrowBtn) { - selectNextTab(); - handled = TRUE; + mJumpNextArrowBtn->setSaveToXML(false); + mJumpNextArrowBtn->setTabStop(FALSE); + addChild(mJumpNextArrowBtn); } + + // set default tab group to be panel contents + setDefaultTabGroup(1); +} - if (handled) +LLTabContainer::LLTabTuple* LLTabContainer::getTabByPanel(LLPanel* child) +{ + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { - if (getCurrentPanel()) + LLTabTuple* tuple = *iter; + if( tuple->mTabPanel == child ) { - getCurrentPanel()->setFocus(TRUE); + return tuple; } } + return NULL; +} - if (!gFocusMgr.childHasKeyboardFocus(getCurrentPanel())) +void LLTabContainer::insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_point) +{ + switch(insertion_point) { - // if child has focus, but not the current panel, focus - // is on a button - switch(key) + case START: + // insert the new tab in the front of the list + mTabList.insert(mTabList.begin() + mLockedTabCount, tuple); + break; + case LEFT_OF_CURRENT: + // insert the new tab before the current tab (but not before mLockedTabCount) { - case KEY_UP: - if (getTabPosition() == BOTTOM && getCurrentPanel()) - { - getCurrentPanel()->setFocus(TRUE); - } - handled = TRUE; - break; - case KEY_DOWN: - if (getTabPosition() == TOP && getCurrentPanel()) - { - getCurrentPanel()->setFocus(TRUE); - } - handled = TRUE; - break; - case KEY_LEFT: - selectPrevTab(); - handled = TRUE; - break; - case KEY_RIGHT: - selectNextTab(); - handled = TRUE; - break; - default: - break; + tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx); + mTabList.insert(current_iter, tuple); + } + break; + + case RIGHT_OF_CURRENT: + // insert the new tab after the current tab (but not before mLockedTabCount) + { + tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx + 1); + mTabList.insert(current_iter, tuple); } + break; + case END: + default: + mTabList.push_back( tuple ); } - return handled; } -// virtual -LLXMLNodePtr LLTabContainer::getXML(bool save_children) const -{ - LLXMLNodePtr node = LLTabContainerCommon::getXML(); - - node->createChild("tab_position", TRUE)->setStringValue((mTabPosition == TOP ? "top" : "bottom")); - return node; -} -BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType type, void* cargo_data, EAcceptance *accept, LLString &tooltip) +void LLTabContainer::updateMaxScrollPos() { - BOOL has_scroll_arrows = (mMaxScrollPos > 0); - - if( mDragAndDropDelayTimer.getElapsedTimeF32() > SCROLL_DELAY_TIME ) + BOOL no_scroll = TRUE; + if (mIsVertical) { - - if (has_scroll_arrows) + S32 tab_total_height = (BTN_HEIGHT + TABCNTRV_PAD) * getTabCount(); + S32 available_height = getRect().getHeight() - getTopBorderHeight(); + if( tab_total_height > available_height ) { - if (mJumpLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpLeftArrowBtn->getRect().mBottom; - mJumpLeftArrowBtn->handleHover(local_x, local_y, mask); - } - if (mJumpRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mJumpRightArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpRightArrowBtn->getRect().mBottom; - mJumpRightArrowBtn->handleHover(local_x, local_y, mask); - } - if (mLeftArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mLeftArrowBtn->getRect().mLeft; - S32 local_y = y - mLeftArrowBtn->getRect().mBottom; - mLeftArrowBtn->handleHover(local_x, local_y, mask); - } - else if (mRightArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mRightArrowBtn->getRect().mLeft; - S32 local_y = y - mRightArrowBtn->getRect().mBottom; - mRightArrowBtn->handleHover(local_x, local_y, mask); - } + S32 available_height_with_arrows = getRect().getHeight() - 2*(TABCNTRV_ARROW_BTN_SIZE + 3*TABCNTRV_PAD); + S32 additional_needed = tab_total_height - available_height_with_arrows; + setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) ); + no_scroll = FALSE; } + } + else + { + S32 tab_space = 0; + S32 available_space = 0; + tab_space = mTotalTabWidth; + available_space = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_TAB_H_PAD); - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + if( tab_space > available_space ) { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( TRUE ); - S32 local_x = x - tuple->mButton->getRect().mLeft; - S32 local_y = y - tuple->mButton->getRect().mBottom; - if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible()) + S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); + // subtract off reserved portion on left + available_width_with_arrows -= TABCNTR_TAB_PARTIAL_WIDTH; + + S32 running_tab_width = 0; + setMaxScrollPos(getTabCount()); + for(tuple_list_t::reverse_iterator tab_it = mTabList.rbegin(); tab_it != mTabList.rend(); ++tab_it) { - tuple->mButton->onCommit(); - mDragAndDropDelayTimer.stop(); + running_tab_width += (*tab_it)->mButton->getRect().getWidth(); + if (running_tab_width > available_width_with_arrows) + { + break; + } + setMaxScrollPos(getMaxScrollPos()-1); } + // in case last tab doesn't actually fit on screen, make it the last scrolling position + setMaxScrollPos(llmin(getMaxScrollPos(), getTabCount() - 1)); + no_scroll = FALSE; } } - - return LLView::handleDragAndDrop(x, y, mask, drop, type, cargo_data, accept, tooltip); + if (no_scroll) + { + setMaxScrollPos(0); + setScrollPos(0); + } + if (getScrollPos() > getMaxScrollPos()) + { + setScrollPos(getMaxScrollPos()); // maybe just enforce this via limits in setScrollPos instead? + } } -void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const LLColor4& color) +void LLTabContainer::commitHoveredButton(S32 x, S32 y) { - LLTabTuple* tuple = getTabByPanel(child); - if( tuple ) + if (hasMouseCapture()) { - tuple->mButton->setImageOverlay(image_name, LLFontGL::RIGHT, color); - - const LLFontGL* fontp = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); - // remove current width from total tab strip width - mTotalTabWidth -= tuple->mButton->getRect().getWidth(); - - S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ? - tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : - 0; - - tuple->mPadding = image_overlay_width; - - tuple->mButton->setRightHPad(6); - tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), - tuple->mButton->getRect().getHeight()); - // add back in button width to total tab strip width - mTotalTabWidth += tuple->mButton->getRect().getWidth(); - - // tabs have changed size, might need to scroll to see current tab - updateMaxScrollPos(); + for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) + { + LLTabTuple* tuple = *iter; + tuple->mButton->setVisible( TRUE ); + S32 local_x = x - tuple->mButton->getRect().mLeft; + S32 local_y = y - tuple->mButton->getRect().mBottom; + if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible()) + { + tuple->mButton->onCommit(); + } + } } } + diff --git a/linden/indra/llui/lltabcontainer.h b/linden/indra/llui/lltabcontainer.h index e2770ee..07554b4 100644 --- a/linden/indra/llui/lltabcontainer.h +++ b/linden/indra/llui/lltabcontainer.h @@ -1,6 +1,6 @@ /** * @file lltabcontainer.h - * @brief LLTabContainerCommon base class + * @brief LLTabContainer class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -29,19 +29,16 @@ * $/LicenseInfo$ */ -// Fear my script-fu! - #ifndef LL_TABCONTAINER_H #define LL_TABCONTAINER_H #include "llpanel.h" +#include "lltextbox.h" #include "llframetimer.h" -class LLButton; -class LLTextBox; - +extern const S32 TABCNTR_HEADER_HEIGHT; -class LLTabContainerCommon : public LLPanel +class LLTabContainer : public LLPanel { public: enum TabPosition @@ -58,81 +55,82 @@ public: RIGHT_OF_CURRENT } eInsertionPoint; - LLTabContainerCommon( const LLString& name, - const LLRect& rect, - TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - BOOL bordered = TRUE); - - LLTabContainerCommon( const LLString& name, - const LLString& rect_control, - TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - BOOL bordered = TRUE); + LLTabContainer( const LLString& name, const LLRect& rect, TabPosition pos, + BOOL bordered, BOOL is_vertical); - virtual ~LLTabContainerCommon(); + /*virtual*/ ~LLTabContainer(); - virtual void initButtons() = 0; - - virtual void setValue(const LLSD& value) { selectTab((S32) value.asInteger()); } - virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TAB_CONTAINER; } - virtual LLString getWidgetTag() const { return LL_TAB_CONTAINER_COMMON_TAG; } - - virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; - - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - - virtual void addTabPanel(LLPanel* child, - const LLString& label, - BOOL select = FALSE, - void (*on_tab_clicked)(void*, bool) = NULL, - void* userdata = NULL, - S32 indent = 0, - BOOL placeholder = FALSE, - eInsertionPoint insertion_point = END) = 0; - virtual void addPlaceholder(LLPanel* child, const LLString& label); - virtual void lockTabs(S32 num_tabs = 0); - virtual void unlockTabs(); - S32 getNumLockedTabs() { return mLockedTabCount; } - - virtual void enableTabButton(S32 which, BOOL enable); - - virtual void removeTabPanel( LLPanel* child ); - virtual void deleteAllTabs(); - virtual LLPanel* getCurrentPanel(); - virtual S32 getCurrentPanelIndex(); - virtual S32 getTabCount(); - virtual S32 getPanelIndexByTitle(const LLString& title); - virtual LLPanel* getPanelByIndex(S32 index); - virtual LLPanel* getPanelByName(const LLString& name); - virtual S32 getIndexForPanel(LLPanel* panel); - - virtual void setCurrentTabName(const LLString& name); - - - virtual void selectFirstTab(); - virtual void selectLastTab(); - virtual BOOL selectTabPanel( LLPanel* child ); - virtual BOOL selectTab(S32 which) = 0; - virtual BOOL selectTabByName(const LLString& title); - virtual void selectNextTab(); - virtual void selectPrevTab(); + // from LLView + /*virtual*/ void setValue(const LLSD& value); + /*virtual*/ EWidgetType getWidgetType() const; + /*virtual*/ LLString getWidgetTag() const; + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent); + /*virtual*/ void draw(); + /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask ); + /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect ); + /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); + /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType type, void* cargo_data, + EAcceptance* accept, LLString& tooltip); + /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; + + void addTabPanel(LLPanel* child, + const LLString& label, + BOOL select = FALSE, + void (*on_tab_clicked)(void*, bool) = NULL, + void* userdata = NULL, + S32 indent = 0, + BOOL placeholder = FALSE, + eInsertionPoint insertion_point = END); + void addPlaceholder(LLPanel* child, const LLString& label); + void removeTabPanel( LLPanel* child ); + void lockTabs(S32 num_tabs = 0); + void unlockTabs(); + S32 getNumLockedTabs() { return mLockedTabCount; } + void enableTabButton(S32 which, BOOL enable); + void deleteAllTabs(); + LLPanel* getCurrentPanel(); + S32 getCurrentPanelIndex(); + S32 getTabCount(); + LLPanel* getPanelByIndex(S32 index); + S32 getIndexForPanel(LLPanel* panel); + S32 getPanelIndexByTitle(const LLString& title); + LLPanel* getPanelByName(const LLString& name); + void setCurrentTabName(const LLString& name); + + void selectFirstTab(); + void selectLastTab(); + void selectNextTab(); + void selectPrevTab(); + BOOL selectTabPanel( LLPanel* child ); + BOOL selectTab(S32 which); + BOOL selectTabByName(const LLString& title); BOOL getTabPanelFlashing(LLPanel* child); void setTabPanelFlashing(LLPanel* child, BOOL state); - virtual void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white); + void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white); void setTitle( const LLString& title ); const LLString getPanelTitle(S32 index); - void setDragAndDropDelayTimer() { mDragAndDropDelayTimer.start(); } - - virtual void setTopBorderHeight(S32 height); + void setTopBorderHeight(S32 height); + S32 getTopBorderHeight() const; - virtual void setTabChangeCallback(LLPanel* tab, void (*on_tab_clicked)(void*,bool)); - virtual void setTabUserData(LLPanel* tab, void* userdata); + void setTabChangeCallback(LLPanel* tab, void (*on_tab_clicked)(void*,bool)); + void setTabUserData(LLPanel* tab, void* userdata); - virtual void reshape(S32 width, S32 height, BOOL called_from_parent); + void setRightTabBtnOffset( S32 offset ); + void setPanelTitle(S32 index, const LLString& title); + TabPosition getTabPosition() const { return mTabPosition; } + void setMinTabWidth(S32 width) { mMinTabWidth = width; } + void setMaxTabWidth(S32 width) { mMaxTabWidth = width; } + S32 getMinTabWidth() const { return mMinTabWidth; } + S32 getMaxTabWidth() const { return mMaxTabWidth; } + + void startDragAndDropDelayTimer() { mDragAndDropDelayTimer.start(); } + static void onCloseBtn(void* userdata); static void onTabBtn(void* userdata); static void onNextBtn(void* userdata); @@ -142,17 +140,17 @@ public: static void onJumpFirstBtn( void* userdata ); static void onJumpLastBtn( void* userdata ); - virtual void setRightTabBtnOffset( S32 offset ) { } - virtual void setPanelTitle(S32 index, const LLString& title) { } + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - virtual TabPosition getTabPosition() { return mTabPosition; } +protected: + /*virtual*/ LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; -protected: +private: // Structure used to map tab buttons to and from tab panels struct LLTabTuple { - LLTabTuple( LLTabContainerCommon* c, LLPanel* p, LLButton* b, + LLTabTuple( LLTabContainer* c, LLPanel* p, LLButton* b, void (*cb)(void*,bool), void* userdata, LLTextBox* placeholder = NULL ) : mTabContainer(c), @@ -165,7 +163,7 @@ protected: mPadding(0) {} - LLTabContainerCommon* mTabContainer; + LLTabContainer* mTabContainer; LLPanel* mTabPanel; LLButton* mButton; void (*mOnChangeCallback)(void*, bool); @@ -175,8 +173,35 @@ protected: S32 mPadding; }; + void initButtons(); + + LLTabTuple* getTab(S32 index) { return mTabList[index]; } + LLTabTuple* getTabByPanel(LLPanel* child); + void insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_point); + + S32 getScrollPos() const { return mScrollPos; } + void setScrollPos(S32 pos) { mScrollPos = pos; } + S32 getMaxScrollPos() const { return mMaxScrollPos; } + void setMaxScrollPos(S32 pos) { mMaxScrollPos = pos; } + S32 getScrollPosPixels() const { return mScrollPosPixels; } + void setScrollPosPixels(S32 pixels) { mScrollPosPixels = pixels; } + + void setTabsHidden(BOOL hidden) { mTabsHidden = hidden; } + BOOL getTabsHidden() const { return mTabsHidden; } + + void setCurrentPanelIndex(S32 index) { mCurrentTabIdx = index; } + + void scrollPrev() { mScrollPos = llmax(0, mScrollPos-1); } // No wrap + void scrollNext() { mScrollPos = llmin(mScrollPos+1, mMaxScrollPos); } // No wrap + + void updateMaxScrollPos(); + void commitHoveredButton(S32 x, S32 y); + + // Variables + typedef std::vector tuple_list_t; tuple_list_t mTabList; + S32 mCurrentTabIdx; BOOL mTabsHidden; @@ -186,8 +211,6 @@ protected: S32 mScrollPosPixels; S32 mMaxScrollPos; - LLFrameTimer mDragAndDropDelayTimer; - void (*mCloseCallback)(void*); void* mCallbackUserdata; @@ -196,87 +219,23 @@ protected: S32 mTopBorderHeight; TabPosition mTabPosition; S32 mLockedTabCount; + S32 mMinTabWidth; + LLButton* mPrevArrowBtn; + LLButton* mNextArrowBtn; -protected: - void scrollPrev(); - void scrollNext(); - - virtual void updateMaxScrollPos() = 0; - virtual void commitHoveredButton(S32 x, S32 y) = 0; - LLTabTuple* getTabByPanel(LLPanel* child); - void insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_point); -}; - -class LLTabContainer : public LLTabContainerCommon -{ -public: - LLTabContainer( const LLString& name, const LLRect& rect, TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - const LLString& title=LLString::null, BOOL bordered = TRUE ); - - LLTabContainer( const LLString& name, const LLString& rect_control, TabPosition pos, - void(*close_callback)(void*), void* callback_userdata, - const LLString& title=LLString::null, BOOL bordered = TRUE ); - - ~LLTabContainer(); - - /*virtual*/ void initButtons(); - - /*virtual*/ void draw(); - - /*virtual*/ void addTabPanel(LLPanel* child, - const LLString& label, - BOOL select = FALSE, - void (*on_tab_clicked)(void*, bool) = NULL, - void* userdata = NULL, - S32 indent = 0, - BOOL placeholder = FALSE, - eInsertionPoint insertion_point = END); - - /*virtual*/ BOOL selectTab(S32 which); - /*virtual*/ void removeTabPanel( LLPanel* child ); - - /*virtual*/ void setPanelTitle(S32 index, const LLString& title); - /*virtual*/ void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white); - /*virtual*/ void setRightTabBtnOffset( S32 offset ); - - /*virtual*/ void setMinTabWidth(S32 width); - /*virtual*/ void setMaxTabWidth(S32 width); - - /*virtual*/ S32 getMinTabWidth() const; - /*virtual*/ S32 getMaxTabWidth() const; - - /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect ); - /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); - /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType type, void* cargo_data, - EAcceptance* accept, LLString& tooltip); - - virtual LLXMLNodePtr getXML(bool save_children = true) const; - + BOOL mIsVertical; -protected: - - LLButton* mLeftArrowBtn; - LLButton* mJumpLeftArrowBtn; - LLButton* mRightArrowBtn; - LLButton* mJumpRightArrowBtn; + // Horizontal specific + LLButton* mJumpPrevArrowBtn; + LLButton* mJumpNextArrowBtn; S32 mRightTabBtnOffset; // Extra room to the right of the tab buttons. -protected: - virtual void updateMaxScrollPos(); - virtual void commitHoveredButton(S32 x, S32 y); - - S32 mMinTabWidth; S32 mMaxTabWidth; S32 mTotalTabWidth; + + LLFrameTimer mDragAndDropDelayTimer; }; -const S32 TABCNTR_CLOSE_BTN_SIZE = 16; -const S32 TABCNTR_HEADER_HEIGHT = LLPANEL_BORDER_WIDTH + TABCNTR_CLOSE_BTN_SIZE; #endif // LL_TABCONTAINER_H diff --git a/linden/indra/llui/lltabcontainervertical.cpp b/linden/indra/llui/lltabcontainervertical.cpp index 334cb43..b4b2710 100644 --- a/linden/indra/llui/lltabcontainervertical.cpp +++ b/linden/indra/llui/lltabcontainervertical.cpp @@ -29,584 +29,4 @@ * $/LicenseInfo$ */ -// Fear my script-fu! - -#include "linden_common.h" - -#include "lltabcontainervertical.h" - -#include "llfocusmgr.h" -#include "llfontgl.h" -#include "llgl.h" - -#include "llbutton.h" -#include "llrect.h" -#include "llpanel.h" -#include "llresmgr.h" -#include "llkeyboard.h" -#include "llui.h" -#include "lltextbox.h" -#include "llcontrol.h" -#include "llcriticaldamp.h" - -#include "llglheaders.h" - -LLTabContainerVertical::LLTabContainerVertical( - const LLString& name, const LLRect& rect, - void(*close_callback)(void*), void* callback_userdata, - U32 tab_width, BOOL bordered) - : - LLTabContainerCommon(name, rect, LEFT, close_callback, callback_userdata, bordered), - mTabWidth(tab_width), - mUpArrowBtn(NULL), - mDownArrowBtn(NULL) -{ - initButtons(); -} - -LLTabContainerVertical::LLTabContainerVertical( - const LLString& name, const LLString& rect_control, - void(*close_callback)(void*), void* callback_userdata, - U32 tab_width, BOOL bordered) - : - LLTabContainerCommon(name, rect_control, LEFT, close_callback, callback_userdata, bordered), - mTabWidth(tab_width) -{ - initButtons(); -} - -// Called from all constructors -void LLTabContainerVertical::initButtons() -{ - // Hack: - if (mRect.getHeight() == 0 || mUpArrowBtn) - { - return; // Don't have a rect yet or already got called - } - - LLString out_id; - LLString in_id; - - //S32 arrow_fudge = 1; // match new art better - - // Left and right scroll arrows (for when there are too many tabs to show all at once). - S32 btn_top = mRect.getHeight(); - S32 btn_top_lower = mRect.mBottom+TABCNTRV_ARROW_BTN_SIZE; - - LLRect up_arrow_btn_rect; - up_arrow_btn_rect.setLeftTopAndSize( mTabWidth/2 , btn_top, TABCNTRV_ARROW_BTN_SIZE, TABCNTRV_ARROW_BTN_SIZE ); - - LLRect down_arrow_btn_rect; - down_arrow_btn_rect.setLeftTopAndSize( mTabWidth/2 , btn_top_lower, TABCNTRV_ARROW_BTN_SIZE, TABCNTRV_ARROW_BTN_SIZE ); - - out_id = "UIImgBtnScrollUpOutUUID"; - in_id = "UIImgBtnScrollUpInUUID"; - mUpArrowBtn = new LLButton( - "Up Arrow", up_arrow_btn_rect, - out_id, in_id, "", - &onPrevBtn, this, NULL ); - mUpArrowBtn->setHeldDownCallback(onPrevBtnHeld); - mUpArrowBtn->setSaveToXML(false); - mUpArrowBtn->setFollowsTop(); - mUpArrowBtn->setFollowsLeft(); - mUpArrowBtn->setTabStop(FALSE); - addChild(mUpArrowBtn); - - out_id = "UIImgBtnScrollDownOutUUID"; - in_id = "UIImgBtnScrollDownInUUID"; - mDownArrowBtn = new LLButton( - "Down Arrow", down_arrow_btn_rect, - out_id, in_id, "", - &onNextBtn, this, NULL ); - mDownArrowBtn->setHeldDownCallback(onNextBtnHeld); - mDownArrowBtn->setSaveToXML(false); - mDownArrowBtn->setFollowsBottom(); - mDownArrowBtn->setFollowsLeft(); - mDownArrowBtn->setTabStop(FALSE); - addChild(mDownArrowBtn); - - // set default tab group to be panel contents - mDefaultTabGroup = 1; -} - -LLTabContainerVertical::~LLTabContainerVertical() -{ } - -void LLTabContainerVertical::addTabPanel(LLPanel* child, const LLString& label, - BOOL select, - void (*on_tab_clicked)(void*, bool), void* userdata, - S32 indent, - BOOL placeholder, eInsertionPoint insertion_point) -{ - if (child->getParent() == this) - { - // already a child of mine - return; - } - - const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF ); - - // Store the original label for possible xml export. - child->setLabel(label); - // Replace long label with truncated version (e.g., "FooBa...") - LLString trimmed_label = label; - LLString::trim(trimmed_label); - - // Tab panel - S32 tab_panel_top; - S32 tab_panel_bottom; - tab_panel_top = mRect.getHeight() - - mTopBorderHeight - - (BTN_HEIGHT - TABCNTRV_BUTTON_PANEL_OVERLAP); - tab_panel_bottom = LLPANEL_BORDER_WIDTH; - - LLRect tab_panel_rect( - mTabWidth + (LLPANEL_BORDER_WIDTH * 2) + TABCNTRV_PAD, - mRect.getHeight() - LLPANEL_BORDER_WIDTH, - mRect.getWidth() - LLPANEL_BORDER_WIDTH, - LLPANEL_BORDER_WIDTH); - - child->setFollowsAll(); - child->translate( tab_panel_rect.mLeft - child->getRect().mLeft, tab_panel_rect.mBottom - child->getRect().mBottom); - child->reshape( tab_panel_rect.getWidth(), tab_panel_rect.getHeight(), TRUE ); - child->setBackgroundVisible( FALSE ); // No need to overdraw - - child->setVisible( FALSE ); // Will be made visible when selected - - // Tab button - LLRect btn_rect; - btn_rect.setLeftTopAndSize( - TABCNTRV_PAD + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor - (mRect.getHeight() - mTopBorderHeight - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + TABCNTRV_PAD) * mTabList.size()), - mTabWidth, - BTN_HEIGHT); - - if (!placeholder) - { - LLButton *btn = new LLButton("vert tab button", - btn_rect, - "", - "", - "", - &LLTabContainerVertical::onTabBtn, NULL, - font, - trimmed_label, trimmed_label); - btn->setSaveToXML(false); - btn->setImages("tab_left.tga", "tab_left_selected.tga"); - btn->setScaleImage(TRUE); - btn->setHAlign(LLFontGL::LEFT); - btn->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); - btn->setTabStop(FALSE); - if (indent) - { - btn->setLeftHPad(indent); - } - - LLTabTuple* tuple = new LLTabTuple( this, child, btn, on_tab_clicked, userdata ); - insertTuple( tuple, insertion_point ); - - btn->setCallbackUserData( tuple ); - addChild( btn, 0 ); - addChild(child, 1); - - if( select ) - { - selectTab( mTabList.size()-1 ); - } - } - else - { - btn_rect.translate(0, -LLBUTTON_V_PAD-2); - LLString box_label = trimmed_label; - LLTextBox* text = new LLTextBox(box_label, btn_rect, box_label, font); - text->setSaveToXML(false); - addChild( text, 0 ); - - LLButton* btn = new LLButton("", LLRect(0,0,0,0)); - btn->setSaveToXML(false); - addChild(btn, 0); - addChild(child, 1); - - LLTabTuple* tuple = new LLTabTuple( this, child, btn, on_tab_clicked, userdata, text ); - insertTuple( tuple, insertion_point ); - } - - updateMaxScrollPos(); -} - -void LLTabContainerVertical::removeTabPanel(LLPanel* child) -{ - LLTabContainerCommon::removeTabPanel(child); - - // Fix-up button sizes - S32 tab_count = 0; - for(std::vector::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - LLRect rect; - rect.setLeftTopAndSize(TABCNTRV_PAD + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor - (mRect.getHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + TABCNTRV_PAD) * (tab_count)), - mTabWidth, - BTN_HEIGHT); - if (tuple->mPlaceholderText) - { - tuple->mPlaceholderText->setRect(rect); - } - else - { - tuple->mButton->setRect(rect); - } - tab_count++; - } -} - -void LLTabContainerVertical::updateMaxScrollPos() -{ - S32 tab_total_height = (BTN_HEIGHT + TABCNTRV_PAD) * mTabList.size(); - S32 available_height = mRect.getHeight() - mTopBorderHeight; - if( tab_total_height > available_height ) - { - S32 available_height_with_arrows = mRect.getHeight() - 2*(TABCNTRV_ARROW_BTN_SIZE + 3*TABCNTRV_PAD); - S32 additional_needed = tab_total_height - available_height_with_arrows; - mMaxScrollPos = S32( ceil(additional_needed / float(BTN_HEIGHT) ) ); - } - else - { - mMaxScrollPos = 0; - mScrollPos = 0; - } - if (mScrollPos > mMaxScrollPos) - { - mScrollPos = mMaxScrollPos; - } -} - -void LLTabContainerVertical::commitHoveredButton(S32 x, S32 y) -{ - if (hasMouseCapture()) - { - for(std::vector::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( TRUE ); - S32 local_x = x - tuple->mButton->getRect().mLeft; - S32 local_y = y - tuple->mButton->getRect().mBottom; - if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible()) - { - tuple->mButton->onCommit(); - } - } - } -} - -BOOL LLTabContainerVertical::selectTab(S32 which) -{ - if (which >= (S32)mTabList.size()) return FALSE; - if (which < 0) return FALSE; - - //if( gFocusMgr.childHasKeyboardFocus( this ) ) - //{ - // gFocusMgr.setKeyboardFocus( NULL ); - //} - - LLTabTuple* selected_tuple = mTabList[which]; - if (!selected_tuple) - { - return FALSE; - } - - BOOL is_visible = FALSE; - if (which != mCurrentTabIdx) - { - mCurrentTabIdx = which; - - S32 i = 0; - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - BOOL is_selected = ( tuple == selected_tuple ); - tuple->mTabPanel->setVisible( is_selected ); -// tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here. - tuple->mButton->setToggleState( is_selected ); - // RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs - tuple->mButton->setTabStop( is_selected ); - - if( is_selected ) - { - // Make sure tab is within scroll - S32 num_visible = mTabList.size() - mMaxScrollPos; - if( i >= mScrollPos && i <= mScrollPos + num_visible) - { - mCurrentTabIdx = which; - is_visible = TRUE; - } - else - { - is_visible = FALSE; - } - } - i++; - } - if( selected_tuple->mOnChangeCallback ) - { - selected_tuple->mOnChangeCallback( selected_tuple->mUserData, false ); - } - } - if(mCurrentTabIdx >= 0) - { - LLTabTuple* tuple = mTabList[mCurrentTabIdx]; - tuple->mTabPanel->setVisible( TRUE ); - tuple->mButton->setToggleState( TRUE ); - } - return is_visible; -} - - - -void LLTabContainerVertical::draw() -{ - S32 target_pixel_scroll = mScrollPos * (BTN_HEIGHT + TABCNTRV_PAD); - - mScrollPosPixels = (S32)lerp((F32)mScrollPosPixels, (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f)); - if( getVisible() ) - { - BOOL has_scroll_arrows = (mMaxScrollPos > 0) || (mScrollPosPixels > 0); - mUpArrowBtn->setVisible( has_scroll_arrows ); - mDownArrowBtn->setVisible( has_scroll_arrows ); - - // Set the topmost position of the tab buttons. - S32 top = mRect.getHeight() - mTopBorderHeight - LLPANEL_BORDER_WIDTH - 1 - (has_scroll_arrows ? TABCNTRV_ARROW_BTN_SIZE : 0); - top += mScrollPosPixels; - - // Hide all the buttons - for(std::vector::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( FALSE ); - } - - LLPanel::draw(); - - // Show all the buttons - for(std::vector::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - tuple->mButton->setVisible( TRUE ); - } - - // Draw some of the buttons... - { - LLRect clip_rect = getLocalRect(); - if (has_scroll_arrows) - { - // ...but clip them. - clip_rect.mBottom = mDownArrowBtn->getRect().mTop + 3*TABCNTRV_PAD; - clip_rect.mTop = mUpArrowBtn->getRect().mBottom - 3*TABCNTRV_PAD; - } - LLLocalClipRect clip(clip_rect); - - //S32 max_scroll_visible = mTabList.size() - mMaxScrollPos + mScrollPos; - S32 idx = 0; - for(std::vector::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - LLTabTuple* tuple = *iter; - tuple->mButton->translate( 0 , top - tuple->mButton->getRect().mTop); - top -= BTN_HEIGHT + TABCNTRV_PAD; - - LLUI::pushMatrix(); - { - LLUI::translate((F32)tuple->mButton->getRect().mLeft, (F32)tuple->mButton->getRect().mBottom, 0.f); - tuple->mButton->draw(); - } - LLUI::popMatrix(); - - idx++; - } - - if( has_scroll_arrows ) - { - // Redraw the arrows so that they appears on top. - glPushMatrix(); - glTranslatef((F32)mUpArrowBtn->getRect().mLeft, (F32)mUpArrowBtn->getRect().mBottom, 0.f); - mUpArrowBtn->draw(); - glPopMatrix(); - - glPushMatrix(); - glTranslatef((F32)mDownArrowBtn->getRect().mLeft, (F32)mDownArrowBtn->getRect().mBottom, 0.f); - mDownArrowBtn->draw(); - glPopMatrix(); - } - } - } -} - -BOOL LLTabContainerVertical::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - BOOL has_scroll_arrows = (mMaxScrollPos > 0); - - if (has_scroll_arrows) - { - if (mUpArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mUpArrowBtn->getRect().mLeft; - S32 local_y = y - mUpArrowBtn->getRect().mBottom; - handled = mUpArrowBtn->handleMouseDown(local_x, local_y, mask); - } - else if (mDownArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mDownArrowBtn->getRect().mLeft; - S32 local_y = y - mDownArrowBtn->getRect().mBottom; - handled = mDownArrowBtn->handleMouseDown(local_x, local_y, mask); - } - } - if (!handled) - { - handled = LLPanel::handleMouseDown( x, y, mask ); - } - - if (mTabList.size() > 0) - { - LLTabTuple* firsttuple = mTabList[0]; - LLRect tab_rect(firsttuple->mButton->getRect().mLeft, - has_scroll_arrows ? mUpArrowBtn->getRect().mBottom - TABCNTRV_PAD : mUpArrowBtn->getRect().mTop, - firsttuple->mButton->getRect().mRight, - has_scroll_arrows ? mDownArrowBtn->getRect().mTop + TABCNTRV_PAD : mDownArrowBtn->getRect().mBottom ); - if( tab_rect.pointInRect( x, y ) ) - { - LLButton* tab_button = mTabList[getCurrentPanelIndex()]->mButton; - gFocusMgr.setMouseCapture(this); - gFocusMgr.setKeyboardFocus(tab_button); - } - } - return handled; -} - -BOOL LLTabContainerVertical::handleHover( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - BOOL has_scroll_arrows = (mMaxScrollPos > 0); - - if (has_scroll_arrows) - { - if (mUpArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mUpArrowBtn->getRect().mLeft; - S32 local_y = y - mUpArrowBtn->getRect().mBottom; - handled = mUpArrowBtn->handleHover(local_x, local_y, mask); - } - else if (mDownArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mDownArrowBtn->getRect().mLeft; - S32 local_y = y - mDownArrowBtn->getRect().mBottom; - handled = mDownArrowBtn->handleHover(local_x, local_y, mask); - } - } - if (!handled) - { - handled = LLPanel::handleHover(x, y, mask); - } - - commitHoveredButton(x, y); - return handled; -} - -BOOL LLTabContainerVertical::handleMouseUp( S32 x, S32 y, MASK mask ) -{ - BOOL handled = FALSE; - BOOL has_scroll_arrows = (mMaxScrollPos > 0); - - if (has_scroll_arrows) - { - if (mUpArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mUpArrowBtn->getRect().mLeft; - S32 local_y = y - mUpArrowBtn->getRect().mBottom; - handled = mUpArrowBtn->handleMouseUp(local_x, local_y, mask); - } - else if (mDownArrowBtn->getRect().pointInRect(x, y)) - { - S32 local_x = x - mDownArrowBtn->getRect().mLeft; - S32 local_y = y - mDownArrowBtn->getRect().mBottom; - handled = mDownArrowBtn->handleMouseUp(local_x, local_y, mask); - } - } - if (!handled) - { - handled = LLPanel::handleMouseUp( x, y, mask ); - } - - commitHoveredButton(x, y); - LLPanel* cur_panel = getCurrentPanel(); - if (hasMouseCapture()) - { - if (cur_panel) - { - if (!cur_panel->focusFirstItem(FALSE)) - { - mTabList[getCurrentPanelIndex()]->mButton->setFocus(TRUE); - } - } - gFocusMgr.setMouseCapture(NULL); - } - - return handled; -} - -BOOL LLTabContainerVertical::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) -{ - BOOL handled = FALSE; - if (getEnabled()) - { - if (key == KEY_LEFT && mask == MASK_ALT) - { - selectPrevTab(); - handled = TRUE; - } - else if (key == KEY_RIGHT && mask == MASK_ALT) - { - selectNextTab(); - handled = TRUE; - } - - // focus is on button - if (!handled && !gFocusMgr.childHasKeyboardFocus(getCurrentPanel())) - { - switch(key) - { - case KEY_UP: - selectPrevTab(); - handled = TRUE; - break; - case KEY_DOWN: - selectNextTab(); - handled = TRUE; - break; - case KEY_LEFT: - handled = TRUE; - break; - case KEY_RIGHT: - if (getTabPosition() == LEFT && getCurrentPanel()) - { - getCurrentPanel()->setFocus(TRUE); - } - handled = TRUE; - break; - default: - break; - } - } - } - return handled; -} - -// virtual -LLXMLNodePtr LLTabContainerVertical::getXML(bool save_children) const -{ - LLXMLNodePtr node = LLTabContainerCommon::getXML(); - - // TomY TODO Is this redundant or will it be used later? - node->createChild("tab_position", TRUE)->setStringValue("left"); - - return node; -} +// deprecated: see LLTabContainer diff --git a/linden/indra/llui/lltabcontainervertical.h b/linden/indra/llui/lltabcontainervertical.h index e887e53..ffe65be 100644 --- a/linden/indra/llui/lltabcontainervertical.h +++ b/linden/indra/llui/lltabcontainervertical.h @@ -29,69 +29,4 @@ * $/LicenseInfo$ */ -// Fear my script-fu! - -#ifndef LL_TABCONTAINERVERTICAL_H -#define LL_TABCONTAINERVERTICAL_H - -#include "lltabcontainer.h" - -const S32 TABCNTRV_CLOSE_BTN_SIZE = 16; -const S32 TABCNTRV_HEADER_HEIGHT = LLPANEL_BORDER_WIDTH + TABCNTRV_CLOSE_BTN_SIZE; -const S32 TABCNTRV_TAB_WIDTH = 100; -// const S32 TABCNTRV_TAB_HEIGHT = 16; Use BTN_HEIGHT instead, JC. -const S32 TABCNTRV_ARROW_BTN_SIZE = 16; -const S32 TABCNTRV_BUTTON_PANEL_OVERLAP = 1; // how many pixels the tab buttons and tab panels overlap. -const S32 TABCNTRV_PAD = 0; - -class LLButton; -class LLTextBox; - -class LLTabContainerVertical : public LLTabContainerCommon -{ -public: - LLTabContainerVertical( const LLString& name, const LLRect& rect, - void(*close_callback)(void*), void* callback_userdata, - U32 tab_width = TABCNTRV_TAB_WIDTH, BOOL bordered = TRUE); - - LLTabContainerVertical( const LLString& name, const LLString& rect_control, - void(*close_callback)(void*), void* callback_userdata, - U32 tab_width = TABCNTRV_TAB_WIDTH, BOOL bordered = TRUE); - - /*virtual*/ void initButtons(); - - /*virtual*/ ~LLTabContainerVertical(); - - virtual LLXMLNodePtr getXML(bool save_children = true) const; - /*virtual*/ void draw(); - - /*virtual*/ void addTabPanel(LLPanel* child, - const LLString& label, - BOOL select = FALSE, - void (*on_tab_clicked)(void*, bool) = NULL, - void* userdata = NULL, - S32 indent = 0, - BOOL placeholder = FALSE, - eInsertionPoint insertion_point = END); - - /*virtual*/ BOOL selectTab(S32 which); - /*virtual*/ void removeTabPanel( LLPanel* child ); - - /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask ); - /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); - -protected: - U32 mTabWidth; - - LLButton* mUpArrowBtn; - LLButton* mDownArrowBtn; - -protected: - virtual void updateMaxScrollPos(); - virtual void commitHoveredButton(S32 x, S32 y); -}; - - -#endif +// deprecated: see LLTabContainer diff --git a/linden/indra/llui/lltextbox.cpp b/linden/indra/llui/lltextbox.cpp index 1422e0a..9ad7849 100644 --- a/linden/indra/llui/lltextbox.cpp +++ b/linden/indra/llui/lltextbox.cpp @@ -30,21 +30,14 @@ */ #include "linden_common.h" - #include "lltextbox.h" - -#include "llerror.h" -#include "llgl.h" -#include "llui.h" #include "lluictrlfactory.h" -#include "llcontrol.h" #include "llfocusmgr.h" -#include "llstl.h" -#include LLTextBox::LLTextBox(const LLString& name, const LLRect& rect, const LLString& text, const LLFontGL* font, BOOL mouse_opaque) : LLUICtrl(name, rect, mouse_opaque, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP ), + mFontGL(font ? font : LLFontGL::sSansSerifSmall), mTextColor( LLUI::sColorsGroup->getColor( "LabelTextColor" ) ), mDisabledColor( LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ), mBackgroundColor( LLUI::sColorsGroup->getColor( "DefaultBackgroundColor" ) ), @@ -64,9 +57,7 @@ LLTextBox::LLTextBox(const LLString& name, const LLRect& rect, const LLString& t mClickedCallback(NULL), mCallbackUserData(NULL) { - // TomY TODO Nuke this eventually - setText( !text.empty() ? text : name ); - mFontGL = font ? font : LLFontGL::sSansSerifSmall; + setText( text ); setTabStop(FALSE); } @@ -93,25 +84,54 @@ LLTextBox::LLTextBox(const LLString& name, const LLString& text, F32 max_width, mClickedCallback(NULL), mCallbackUserData(NULL) { - setWrappedText(!text.empty() ? text : name, max_width); + setWrappedText(text, max_width); reshapeToFitText(); setTabStop(FALSE); } -LLTextBox::~LLTextBox() -{ -} - -// virtual -EWidgetType LLTextBox::getWidgetType() const +LLTextBox::LLTextBox(const LLString& name_and_label, const LLRect& rect) : + LLUICtrl(name_and_label, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP), + mFontGL(LLFontGL::sSansSerifSmall), + mTextColor(LLUI::sColorsGroup->getColor("LabelTextColor")), + mDisabledColor(LLUI::sColorsGroup->getColor("LabelDisabledColor")), + mBackgroundColor(LLUI::sColorsGroup->getColor("DefaultBackgroundColor")), + mBorderColor(LLUI::sColorsGroup->getColor("DefaultHighlightLight")), + mBackgroundVisible(FALSE), + mBorderVisible(FALSE), + mFontStyle(LLFontGL::DROP_SHADOW_SOFT), + mBorderDropShadowVisible(FALSE), + mHPad(0), + mVPad(0), + mHAlign(LLFontGL::LEFT), + mVAlign( LLFontGL::TOP ), + mClickedCallback(NULL), + mCallbackUserData(NULL) { - return WIDGET_TYPE_TEXT_BOX; + setText( name_and_label ); + setTabStop(FALSE); } -// virtual -LLString LLTextBox::getWidgetTag() const +LLTextBox::LLTextBox(const LLString& name_and_label) : + LLUICtrl(name_and_label, LLRect(0, 0, 1, 1), TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP), + mFontGL(LLFontGL::sSansSerifSmall), + mTextColor(LLUI::sColorsGroup->getColor("LabelTextColor")), + mDisabledColor(LLUI::sColorsGroup->getColor("LabelDisabledColor")), + mBackgroundColor(LLUI::sColorsGroup->getColor("DefaultBackgroundColor")), + mBorderColor(LLUI::sColorsGroup->getColor("DefaultHighlightLight")), + mBackgroundVisible(FALSE), + mBorderVisible(FALSE), + mFontStyle(LLFontGL::DROP_SHADOW_SOFT), + mBorderDropShadowVisible(FALSE), + mHPad(0), + mVPad(0), + mHAlign(LLFontGL::LEFT), + mVAlign( LLFontGL::TOP ), + mClickedCallback(NULL), + mCallbackUserData(NULL) { - return LL_TEXT_BOX_TAG; + setWrappedText(name_and_label); + reshapeToFitText(); + setTabStop(FALSE); } BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask) @@ -127,7 +147,7 @@ BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask) // Route future Mouse messages here preemptively. (Release on mouse up.) gFocusMgr.setMouseCapture( this ); - if (mSoundFlags & MOUSE_DOWN) + if (getSoundFlags() & MOUSE_DOWN) { make_ui_sound("UISndClick"); } @@ -153,7 +173,7 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask) // Release the mouse gFocusMgr.setMouseCapture( NULL ); - if (mSoundFlags & MOUSE_UP) + if (getSoundFlags() & MOUSE_UP) { make_ui_sound("UISndClickRelease"); } @@ -294,16 +314,6 @@ S32 LLTextBox::getTextPixelHeight() } -void LLTextBox::setValue(const LLSD& value ) -{ - setText(value.asString()); -} - -LLSD LLTextBox::getValue() const -{ - return LLSD(getText()); -} - BOOL LLTextBox::setTextArg( const LLString& key, const LLStringExplicit& text ) { mText.setArg(key, text); @@ -324,13 +334,13 @@ void LLTextBox::draw() { static LLColor4 color_drop_shadow = LLUI::sColorsGroup->getColor("ColorDropShadow"); static S32 drop_shadow_tooltip = LLUI::sConfigGroup->getS32("DropShadowTooltip"); - gl_drop_shadow(0, mRect.getHeight(), mRect.getWidth(), 0, + gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, color_drop_shadow, drop_shadow_tooltip); } if (mBackgroundVisible) { - LLRect r( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 ); gl_rect_2d( r, mBackgroundColor ); } @@ -341,14 +351,14 @@ void LLTextBox::draw() text_x = mHPad; break; case LLFontGL::HCENTER: - text_x = mRect.getWidth() / 2; + text_x = getRect().getWidth() / 2; break; case LLFontGL::RIGHT: - text_x = mRect.getWidth() - mHPad; + text_x = getRect().getWidth() - mHPad; break; } - S32 text_y = mRect.getHeight() - mVPad; + S32 text_y = getRect().getHeight() - mVPad; if ( getEnabled() ) { @@ -360,7 +370,6 @@ void LLTextBox::draw() { drawText( text_x, text_y, mTextColor ); } - } else { @@ -385,7 +394,14 @@ void LLTextBox::reshape(S32 width, S32 height, BOOL called_from_parent) void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) { - if( !mLineLengthList.empty() ) + if( mLineLengthList.empty() ) + { + mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color, + mHAlign, mVAlign, + mFontStyle, + S32_MAX, getRect().getWidth(), NULL, TRUE, mUseEllipses); + } + else { S32 cur_pos = 0; for (std::vector::iterator iter = mLineLengthList.begin(); @@ -395,21 +411,13 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color ) mFontGL->render(mText.getWString(), cur_pos, (F32)x, (F32)y, color, mHAlign, mVAlign, mFontStyle, - line_length, mRect.getWidth(), NULL, TRUE, mUseEllipses ); + line_length, getRect().getWidth(), NULL, TRUE, mUseEllipses ); cur_pos += line_length + 1; y -= llfloor(mFontGL->getLineHeight()); } } - else - { - mFontGL->render(mText.getWString(), 0, (F32)x, (F32)y, color, - mHAlign, mVAlign, - mFontStyle, - S32_MAX, mRect.getWidth(), NULL, TRUE, mUseEllipses); - } } - void LLTextBox::reshapeToFitText() { S32 width = getTextPixelWidth(); @@ -423,28 +431,19 @@ LLXMLNodePtr LLTextBox::getXML(bool save_children) const LLXMLNodePtr node = LLUICtrl::getXML(); // Attributes - node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mFontGL)); - node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(mHAlign)); - addColorXML(node, mTextColor, "text_color", "LabelTextColor"); addColorXML(node, mDisabledColor, "disabled_color", "LabelDisabledColor"); addColorXML(node, mBackgroundColor, "bg_color", "DefaultBackgroundColor"); addColorXML(node, mBorderColor, "border_color", "DefaultHighlightLight"); - node->createChild("bg_visible", TRUE)->setBoolValue(mBackgroundVisible); - node->createChild("border_visible", TRUE)->setBoolValue(mBorderVisible); - node->createChild("border_drop_shadow_visible", TRUE)->setBoolValue(mBorderDropShadowVisible); - node->createChild("h_pad", TRUE)->setIntValue(mHPad); - node->createChild("v_pad", TRUE)->setIntValue(mVPad); // Contents - node->setStringValue(mText); return node; @@ -459,12 +458,6 @@ LLView* LLTextBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f LLString text = node->getTextContents(); - // TomY Yes I know this is a hack, but insert a space to make a blank text field - if (text == "") - { - text = " "; - } - LLTextBox* text_box = new LLTextBox(name, LLRect(), text, @@ -510,6 +503,5 @@ LLView* LLTextBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f text_box->setHoverActive(hover_active); } - return text_box; } diff --git a/linden/indra/llui/lltextbox.h b/linden/indra/llui/lltextbox.h index c8bdfc5..7bea722 100644 --- a/linden/indra/llui/lltextbox.h +++ b/linden/indra/llui/lltextbox.h @@ -35,11 +35,8 @@ #include "lluictrl.h" #include "v4color.h" #include "llstring.h" -#include "llfontgl.h" #include "lluistring.h" -class LLUICtrlFactory; - class LLTextBox : public LLUICtrl @@ -48,18 +45,22 @@ public: // By default, follows top and left and is mouse-opaque. // If no text, text = name. // If no font, uses default system font. - LLTextBox(const LLString& name, const LLRect& rect, const LLString& text = LLString::null, + LLTextBox(const LLString& name, const LLRect& rect, const LLString& text, const LLFontGL* font = NULL, BOOL mouse_opaque = TRUE ); // Construct a textbox which handles word wrapping for us. LLTextBox(const LLString& name, const LLString& text, F32 max_width = 200, const LLFontGL* font = NULL, BOOL mouse_opaque = TRUE ); - virtual ~LLTextBox(); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + // "Simple" constructors for text boxes that have the same name and label *TO BE DEPRECATED* + LLTextBox(const LLString& name_and_label, const LLRect& rect); + LLTextBox(const LLString& name_and_label); + + virtual ~LLTextBox() {} + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TEXT_BOX; } + virtual LLString getWidgetTag() const { return LL_TEXT_BOX_TAG; } virtual LLXMLNodePtr getXML(bool save_children = true) const; - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); virtual void draw(); virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -77,8 +78,7 @@ public: void setHoverActive( BOOL active ) { mHoverActive = active; } void setText( const LLStringExplicit& text ); - void setWrappedText(const LLStringExplicit& text, F32 max_width = -1.0); - // default width means use existing control width + void setWrappedText(const LLStringExplicit& text, F32 max_width = -1.0); // -1 means use existing control width void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; } void setBackgroundVisible(BOOL visible) { mBackgroundVisible = visible; } @@ -90,7 +90,7 @@ public: void setRightAlign() { mHAlign = LLFontGL::RIGHT; } void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } void setClickedCallback( void (*cb)(void *data) ){ mClickedCallback = cb; } // mouse down and up within button - void setCallbackUserData( void* data ) { mCallbackUserData = data; } + void setCallbackUserData( void* data ) { mCallbackUserData = data; } const LLFontGL* getFont() const { return mFontGL; } @@ -100,16 +100,14 @@ public: S32 getTextPixelWidth(); S32 getTextPixelHeight(); - - virtual void setValue(const LLSD& value ); - virtual LLSD getValue() const; + virtual void setValue(const LLSD& value ) { setText(value.asString()); } + virtual LLSD getValue() const { return LLSD(getText()); } virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ); -protected: +private: void setLineLengths(); void drawText(S32 x, S32 y, const LLColor4& color ); -protected: LLUIString mText; const LLFontGL* mFontGL; LLColor4 mTextColor; diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index 9061ca3..545fddb 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp @@ -37,6 +37,7 @@ #include "llfontgl.h" #include "llgl.h" +#include "llglimmediate.h" #include "llui.h" #include "lluictrlfactory.h" #include "llrect.h" @@ -63,15 +64,12 @@ // // Globals // - BOOL gDebugTextEditorTips = FALSE; // // Constants // - const S32 UI_TEXTEDITOR_BUFFER_BLOCK_SIZE = 512; - const S32 UI_TEXTEDITOR_BORDER = 1; const S32 UI_TEXTEDITOR_H_PAD = 4; const S32 UI_TEXTEDITOR_V_PAD_TOP = 4; @@ -93,67 +91,33 @@ void (* LLTextEditor::mURLcallback)(const char*) = NULL; bool (* LLTextEditor::mSecondlifeURLcallback)(const std::string&) = NULL; bool (* LLTextEditor::mSecondlifeURLcallbackRightClick)(const std::string&) = NULL; -/////////////////////////////////////////////////////////////////// -//virtuals -BOOL LLTextCmd::canExtend(S32 pos) -{ - return FALSE; -} - -void LLTextCmd::blockExtensions() -{ -} - -BOOL LLTextCmd::extendAndExecute( LLTextEditor* editor, S32 pos, llwchar c, S32* delta ) -{ - llassert(0); - return 0; -} - -BOOL LLTextCmd::hasExtCharValue( llwchar value ) -{ - return FALSE; -} - -// Utility funcs -S32 LLTextCmd::insert(LLTextEditor* editor, S32 pos, const LLWString &wstr) -{ - return editor->insertStringNoUndo( pos, wstr ); -} -S32 LLTextCmd::remove(LLTextEditor* editor, S32 pos, S32 length) -{ - return editor->removeStringNoUndo( pos, length ); -} -S32 LLTextCmd::overwrite(LLTextEditor* editor, S32 pos, llwchar wc) -{ - return editor->overwriteCharNoUndo(pos, wc); -} /////////////////////////////////////////////////////////////////// -class LLTextCmdInsert : public LLTextCmd +class LLTextEditor::LLTextCmdInsert : public LLTextEditor::LLTextCmd { public: LLTextCmdInsert(S32 pos, BOOL group_with_next, const LLWString &ws) : LLTextCmd(pos, group_with_next), mWString(ws) { } + virtual ~LLTextCmdInsert() {} virtual BOOL execute( LLTextEditor* editor, S32* delta ) { - *delta = insert(editor, mPos, mWString ); + *delta = insert(editor, getPosition(), mWString ); LLWString::truncate(mWString, *delta); //mWString = wstring_truncate(mWString, *delta); return (*delta != 0); } virtual S32 undo( LLTextEditor* editor ) { - remove(editor, mPos, mWString.length() ); - return mPos; + remove(editor, getPosition(), mWString.length() ); + return getPosition(); } virtual S32 redo( LLTextEditor* editor ) { - insert(editor, mPos, mWString ); - return mPos + mWString.length(); + insert(editor, getPosition(), mWString ); + return getPosition() + mWString.length(); } private: @@ -161,8 +125,7 @@ private: }; /////////////////////////////////////////////////////////////////// - -class LLTextCmdAddChar : public LLTextCmd +class LLTextEditor::LLTextCmdAddChar : public LLTextEditor::LLTextCmd { public: LLTextCmdAddChar( S32 pos, BOOL group_with_next, llwchar wc) @@ -173,13 +136,13 @@ public: { mBlockExtensions = TRUE; } - virtual BOOL canExtend(S32 pos) + virtual BOOL canExtend(S32 pos) const { - return !mBlockExtensions && (pos == mPos + (S32)mWString.length()); + return !mBlockExtensions && (pos == getPosition() + (S32)mWString.length()); } virtual BOOL execute( LLTextEditor* editor, S32* delta ) { - *delta = insert(editor, mPos, mWString); + *delta = insert(editor, getPosition(), mWString); LLWString::truncate(mWString, *delta); //mWString = wstring_truncate(mWString, *delta); return (*delta != 0); @@ -198,13 +161,13 @@ public: } virtual S32 undo( LLTextEditor* editor ) { - remove(editor, mPos, mWString.length() ); - return mPos; + remove(editor, getPosition(), mWString.length() ); + return getPosition(); } virtual S32 redo( LLTextEditor* editor ) { - insert(editor, mPos, mWString ); - return mPos + mWString.length(); + insert(editor, getPosition(), mWString ); + return getPosition() + mWString.length(); } private: @@ -215,7 +178,7 @@ private: /////////////////////////////////////////////////////////////////// -class LLTextCmdOverwriteChar : public LLTextCmd +class LLTextEditor::LLTextCmdOverwriteChar : public LLTextEditor::LLTextCmd { public: LLTextCmdOverwriteChar( S32 pos, BOOL group_with_next, llwchar wc) @@ -223,20 +186,20 @@ public: virtual BOOL execute( LLTextEditor* editor, S32* delta ) { - mOldChar = editor->getWChar(mPos); - overwrite(editor, mPos, mChar); + mOldChar = editor->getWChar(getPosition()); + overwrite(editor, getPosition(), mChar); *delta = 0; return TRUE; } virtual S32 undo( LLTextEditor* editor ) { - overwrite(editor, mPos, mOldChar); - return mPos; + overwrite(editor, getPosition(), mOldChar); + return getPosition(); } virtual S32 redo( LLTextEditor* editor ) { - overwrite(editor, mPos, mChar); - return mPos+1; + overwrite(editor, getPosition(), mChar); + return getPosition()+1; } private: @@ -246,7 +209,7 @@ private: /////////////////////////////////////////////////////////////////// -class LLTextCmdRemove : public LLTextCmd +class LLTextEditor::LLTextCmdRemove : public LLTextEditor::LLTextCmd { public: LLTextCmdRemove( S32 pos, BOOL group_with_next, S32 len ) : @@ -255,30 +218,27 @@ public: } virtual BOOL execute( LLTextEditor* editor, S32* delta ) { - mWString = editor->getWSubString(mPos, mLen); - *delta = remove(editor, mPos, mLen ); + mWString = editor->getWSubString(getPosition(), mLen); + *delta = remove(editor, getPosition(), mLen ); return (*delta != 0); } virtual S32 undo( LLTextEditor* editor ) { - insert(editor, mPos, mWString ); - return mPos + mWString.length(); + insert(editor, getPosition(), mWString ); + return getPosition() + mWString.length(); } virtual S32 redo( LLTextEditor* editor ) { - remove(editor, mPos, mLen ); - return mPos; + remove(editor, getPosition(), mLen ); + return getPosition(); } private: LLWString mWString; S32 mLen; }; -/////////////////////////////////////////////////////////////////// -// -// Member functions -// +/////////////////////////////////////////////////////////////////// LLTextEditor::LLTextEditor( const LLString& name, @@ -309,7 +269,7 @@ LLTextEditor::LLTextEditor( mFocusBgColor( LLUI::sColorsGroup->getColor( "TextBgFocusColor" ) ), mReadOnly(FALSE), mWordWrap( FALSE ), - mTabToNextField( TRUE ), + mTabsToNextField( TRUE ), mCommitOnFocusLost( FALSE ), mHideScrollbarForShortDocs( FALSE ), mTakesNonScrollClicks( TRUE ), @@ -344,10 +304,10 @@ LLTextEditor::LLTextEditor( // Init the scrollbar LLRect scroll_rect; scroll_rect.setOriginAndSize( - mRect.getWidth() - UI_TEXTEDITOR_BORDER - SCROLLBAR_SIZE, + getRect().getWidth() - UI_TEXTEDITOR_BORDER - SCROLLBAR_SIZE, UI_TEXTEDITOR_BORDER, SCROLLBAR_SIZE, - mRect.getHeight() - 2 * UI_TEXTEDITOR_BORDER ); + getRect().getHeight() - 2 * UI_TEXTEDITOR_BORDER ); S32 lines_in_doc = getLineCount(); mScrollbar = new LLScrollbar( "Scrollbar", scroll_rect, LLScrollbar::VERTICAL, @@ -363,7 +323,7 @@ LLTextEditor::LLTextEditor( mScrollbar->setOnScrollEndCallback(mOnScrollEndCallback, mOnScrollEndData); addChild(mScrollbar); - mBorder = new LLViewBorder( "text ed border", LLRect(0, mRect.getHeight(), mRect.getWidth(), 0), LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, UI_TEXTEDITOR_BORDER ); + mBorder = new LLViewBorder( "text ed border", LLRect(0, getRect().getHeight(), getRect().getWidth(), 0), LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, UI_TEXTEDITOR_BORDER ); addChild( mBorder ); appendText(default_text, FALSE, FALSE); @@ -392,12 +352,6 @@ LLTextEditor::~LLTextEditor() std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); } -//virtual -LLString LLTextEditor::getWidgetTag() const -{ - return LL_TEXT_EDITOR_TAG; -} - void LLTextEditor::setTrackColor( const LLColor4& color ) { mScrollbar->setTrackColor(color); @@ -422,7 +376,7 @@ void LLTextEditor::updateLineStartList(S32 startpos) { updateSegments(); - bindEmbeddedChars( mGLFont ); + bindEmbeddedChars( const_cast(mGLFont) ); S32 seg_num = mSegments.size(); S32 seg_idx = 0; @@ -471,7 +425,7 @@ void LLTextEditor::updateLineStartList(S32 startpos) else { const llwchar* str = mWText.c_str() + start_idx; - S32 drawn = mGLFont->maxDrawableChars(str, (F32)mTextRect.getWidth() - line_width, + S32 drawn = mGLFont->maxDrawableChars(str, (F32)abs(mTextRect.getWidth()) - line_width, end_idx - start_idx, mWordWrap, mAllowEmbeddedItems ); if( 0 == drawn && line_width == 0) { @@ -499,7 +453,7 @@ void LLTextEditor::updateLineStartList(S32 startpos) } } - unbindEmbeddedChars(mGLFont); + unbindEmbeddedChars(const_cast(mGLFont)); mScrollbar->setDocSize( getLineCount() ); @@ -515,11 +469,6 @@ void LLTextEditor::updateLineStartList(S32 startpos) // LLTextEditor // Public methods -//static -BOOL LLTextEditor::isPartOfWord(llwchar c) { return (c == '_') || isalnum(c); } - - - BOOL LLTextEditor::truncate() { BOOL did_truncate = FALSE; @@ -581,6 +530,7 @@ void LLTextEditor::setWText(const LLWString &wtext) resetDirty(); } +// virtual void LLTextEditor::setValue(const LLSD& value) { setText(value.asString()); @@ -600,6 +550,7 @@ const LLString& LLTextEditor::getText() const return mUTF8Text; } +// virtual LLSD LLTextEditor::getValue() const { return LLSD(getText()); @@ -622,7 +573,10 @@ void LLTextEditor::setBorderVisible(BOOL b) mBorder->setVisible(b); } - +BOOL LLTextEditor::isBorderVisible() const +{ + return mBorder->getVisible(); +} void LLTextEditor::setHideScrollbarForShortDocs(BOOL b) { @@ -734,12 +688,6 @@ void LLTextEditor::replaceTextAll(const LLString& search_text, const LLString& r mScrollbar->setDocPos(cur_pos); } -void LLTextEditor::setTakesNonScrollClicks(BOOL b) -{ - mTakesNonScrollClicks = b; -} - - // Picks a new cursor position based on the screen size of text being drawn. void LLTextEditor::setCursorAtLocalPos( S32 local_x, S32 local_y, BOOL round ) { @@ -774,11 +722,6 @@ S32 LLTextEditor::nextWordPos(S32 cursorPos) const return cursorPos; } -S32 LLTextEditor::getLineCount() const -{ - return mLineStartList.size(); -} - S32 LLTextEditor::getLineStart( S32 line ) const { S32 num_lines = getLineCount(); @@ -796,7 +739,7 @@ S32 LLTextEditor::getLineStart( S32 line ) const } // Given an offset into text (pos), find the corresponding line (from the start of the doc) and an offset into the line. -void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp ) +void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp ) const { if (mLineStartList.empty()) { @@ -809,7 +752,7 @@ void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp ) getSegmentAndOffset( startpos, &seg_idx, &seg_offset ); line_info tline(seg_idx, seg_offset); - line_list_t::iterator iter = std::upper_bound(mLineStartList.begin(), mLineStartList.end(), tline, line_info_compare()); + line_list_t::const_iterator iter = std::upper_bound(mLineStartList.begin(), mLineStartList.end(), tline, line_info_compare()); if (iter != mLineStartList.begin()) --iter; *linep = iter - mLineStartList.begin(); S32 line_start = mSegments[iter->mSegment]->getStart() + iter->mOffset; @@ -817,7 +760,7 @@ void LLTextEditor::getLineAndOffset( S32 startpos, S32* linep, S32* offsetp ) } } -void LLTextEditor::getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) +void LLTextEditor::getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) const { if (mSegments.empty()) { @@ -826,46 +769,21 @@ void LLTextEditor::getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp } LLTextSegment tseg(startpos); - segment_list_t::iterator seg_iter; + segment_list_t::const_iterator seg_iter; seg_iter = std::upper_bound(mSegments.begin(), mSegments.end(), &tseg, LLTextSegment::compare()); if (seg_iter != mSegments.begin()) --seg_iter; *segidxp = seg_iter - mSegments.begin(); *offsetp = startpos - (*seg_iter)->getStart(); } -const LLWString& LLTextEditor::getWText() const -{ - return mWText; -} - -S32 LLTextEditor::getLength() const -{ - return mWText.length(); -} - -llwchar LLTextEditor::getWChar(S32 pos) -{ - return mWText[pos]; -} - -LLWString LLTextEditor::getWSubString(S32 pos, S32 len) -{ - return mWText.substr(pos, len); -} - -LLTextSegment* LLTextEditor::getCurrentSegment() -{ - return getSegmentAtOffset(mCursorPos); -} - -LLTextSegment* LLTextEditor::getPreviousSegment() +const LLTextSegment* LLTextEditor::getPreviousSegment() { // find segment index at character to left of cursor (or rightmost edge of selection) S32 idx = llmax(0, getSegmentIdxAtOffset(mCursorPos) - 1); return idx >= 0 ? mSegments[idx] : NULL; } -void LLTextEditor::getSelectedSegments(std::vector& segments) +void LLTextEditor::getSelectedSegments(std::vector& segments) { S32 left = hasSelection() ? llmin(mSelectionStart, mSelectionEnd) : mCursorPos; S32 right = hasSelection() ? llmax(mSelectionStart, mSelectionEnd) : mCursorPos; @@ -878,7 +796,7 @@ void LLTextEditor::getSelectedSegments(std::vector& segments) } } -S32 LLTextEditor::getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) +S32 LLTextEditor::getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const { // If round is true, if the position is on the right half of a character, the cursor // will be put to its right. If round is false, the cursor will always be put to the @@ -916,13 +834,13 @@ S32 LLTextEditor::getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL rou if (mAllowEmbeddedItems) { // Figure out which character we're nearest to. - bindEmbeddedChars(mGLFont); + bindEmbeddedChars(const_cast(mGLFont)); pos = mGLFont->charFromPixelOffset(mWText.c_str(), line_start, (F32)(local_x - mTextRect.mLeft), (F32)(mTextRect.getWidth()), line_len, round, TRUE); - unbindEmbeddedChars(mGLFont); + unbindEmbeddedChars(const_cast(mGLFont)); } else { @@ -958,8 +876,8 @@ void LLTextEditor::setCursorPos(S32 offset) mDesiredXPixel = -1; } - -BOOL LLTextEditor::canDeselect() +// virtual +BOOL LLTextEditor::canDeselect() const { return hasSelection(); } @@ -1126,12 +1044,13 @@ void LLTextEditor::indentSelectedLines( S32 spaces ) } } - -BOOL LLTextEditor::canSelectAll() +//virtual +BOOL LLTextEditor::canSelectAll() const { return TRUE; } +// virtual void LLTextEditor::selectAll() { mSelectionStart = getLength(); @@ -1143,7 +1062,7 @@ void LLTextEditor::selectAll() BOOL LLTextEditor::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) { for ( child_list_const_iter_t child_it = getChildList()->begin(); - child_it != getChildList()->end(); ++child_it) + child_it != getChildList()->end(); ++child_it) { LLView* viewp = *child_it; S32 local_x = x - viewp->getRect().mLeft; @@ -1159,7 +1078,7 @@ BOOL LLTextEditor::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rec return TRUE; } - LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); + const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); if( cur_segment ) { BOOL has_tool_tip = FALSE; @@ -1267,7 +1186,7 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) } // Delay cursor flashing - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); return handled; } @@ -1320,7 +1239,7 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) if( handled ) { // Delay cursor flashing - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); } // Opaque @@ -1329,7 +1248,7 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) // Check to see if we're over an HTML-style link if( !mSegments.empty() ) { - LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); + const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); if( cur_segment ) { if(cur_segment->getStyle().isLink()) @@ -1353,7 +1272,7 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) if( !handled ) { lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl; - if (!mScrollbar->getVisible() || x < mRect.getWidth() - SCROLLBAR_SIZE) + if (!mScrollbar->getVisible() || x < getRect().getWidth() - SCROLLBAR_SIZE) { getWindow()->setCursor(UI_CURSOR_IBEAM); } @@ -1411,7 +1330,7 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) } // Delay cursor flashing - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); if( hasMouseCapture() ) { @@ -1467,7 +1386,7 @@ BOOL LLTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) mIsSelecting = FALSE; // delay cursor flashing - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); handled = TRUE; } @@ -1548,50 +1467,51 @@ S32 LLTextEditor::overwriteChar(S32 pos, llwchar wc) // a pseudo-tab (up to for spaces in a row) void LLTextEditor::removeCharOrTab() { - if( getEnabled() ) + if( !getEnabled() ) { - if( mCursorPos > 0 ) - { - S32 chars_to_remove = 1; + return; + } + if( mCursorPos > 0 ) + { + S32 chars_to_remove = 1; - const LLWString &text = mWText; - if (text[mCursorPos - 1] == ' ') + const LLWString &text = mWText; + if (text[mCursorPos - 1] == ' ') + { + // Try to remove a "tab" + S32 line, offset; + getLineAndOffset(mCursorPos, &line, &offset); + if (offset > 0) { - // Try to remove a "tab" - S32 line, offset; - getLineAndOffset(mCursorPos, &line, &offset); - if (offset > 0) + chars_to_remove = offset % SPACES_PER_TAB; + if( chars_to_remove == 0 ) { - chars_to_remove = offset % SPACES_PER_TAB; - if( chars_to_remove == 0 ) - { - chars_to_remove = SPACES_PER_TAB; - } + chars_to_remove = SPACES_PER_TAB; + } - for( S32 i = 0; i < chars_to_remove; i++ ) + for( S32 i = 0; i < chars_to_remove; i++ ) + { + if (text[ mCursorPos - i - 1] != ' ') { - if (text[ mCursorPos - i - 1] != ' ') - { - // Fewer than a full tab's worth of spaces, so - // just delete a single character. - chars_to_remove = 1; - break; - } + // Fewer than a full tab's worth of spaces, so + // just delete a single character. + chars_to_remove = 1; + break; } } } - - for (S32 i = 0; i < chars_to_remove; i++) - { - setCursorPos(mCursorPos - 1); - remove( mCursorPos, 1, FALSE ); - } } - else + + for (S32 i = 0; i < chars_to_remove; i++) { - reportBadKeystroke(); + setCursorPos(mCursorPos - 1); + remove( mCursorPos, 1, FALSE ); } } + else + { + reportBadKeystroke(); + } } // Remove a single character from the text @@ -1602,17 +1522,18 @@ S32 LLTextEditor::removeChar(S32 pos) void LLTextEditor::removeChar() { - if (getEnabled()) + if (!getEnabled()) { - if (mCursorPos > 0) - { - setCursorPos(mCursorPos - 1); - removeChar(mCursorPos); - } - else - { - reportBadKeystroke(); - } + return; + } + if (mCursorPos > 0) + { + setCursorPos(mCursorPos - 1); + removeChar(mCursorPos); + } + else + { + reportBadKeystroke(); } } @@ -1639,19 +1560,20 @@ S32 LLTextEditor::addChar(S32 pos, llwchar wc) void LLTextEditor::addChar(llwchar wc) { - if( getEnabled() ) + if( !getEnabled() ) { - if( hasSelection() ) - { - deleteSelection(TRUE); - } - else if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) - { - removeChar(mCursorPos); - } - - setCursorPos(mCursorPos + addChar( mCursorPos, wc )); + return; } + if( hasSelection() ) + { + deleteSelection(TRUE); + } + else if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode()) + { + removeChar(mCursorPos); + } + + setCursorPos(mCursorPos + addChar( mCursorPos, wc )); } @@ -1747,7 +1669,6 @@ BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask) } } - if( !handled && mHandleEditKeysDirectly ) { if( (MASK_CONTROL & mask) && ('A' == key) ) @@ -1900,7 +1821,8 @@ void LLTextEditor::deleteSelection(BOOL group_with_next_op ) } } -BOOL LLTextEditor::canCut() +// virtual +BOOL LLTextEditor::canCut() const { return !mReadOnly && hasSelection(); } @@ -1908,36 +1830,37 @@ BOOL LLTextEditor::canCut() // cut selection to clipboard void LLTextEditor::cut() { - if( canCut() ) + if( !canCut() ) { - S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); - S32 length = abs( mSelectionStart - mSelectionEnd ); - gClipboard.copyFromSubstring( mWText, left_pos, length, mSourceID ); - deleteSelection( FALSE ); - - updateLineStartList(); - updateScrollFromCursor(); + return; } + S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); + S32 length = abs( mSelectionStart - mSelectionEnd ); + gClipboard.copyFromSubstring( mWText, left_pos, length, mSourceID ); + deleteSelection( FALSE ); + + updateLineStartList(); + updateScrollFromCursor(); } -BOOL LLTextEditor::canCopy() +BOOL LLTextEditor::canCopy() const { return hasSelection(); } - // copy selection to clipboard void LLTextEditor::copy() { - if( canCopy() ) + if( !canCopy() ) { - S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); - S32 length = abs( mSelectionStart - mSelectionEnd ); - gClipboard.copyFromSubstring(mWText, left_pos, length, mSourceID); + return; } + S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); + S32 length = abs( mSelectionStart - mSelectionEnd ); + gClipboard.copyFromSubstring(mWText, left_pos, length, mSourceID); } -BOOL LLTextEditor::canPaste() +BOOL LLTextEditor::canPaste() const { return !mReadOnly && gClipboard.canPasteString(); } @@ -1946,47 +1869,49 @@ BOOL LLTextEditor::canPaste() // paste from clipboard void LLTextEditor::paste() { - if (canPaste()) + if (!canPaste()) + { + return; + } + LLUUID source_id; + LLWString paste = gClipboard.getPasteWString(&source_id); + if (paste.empty()) { - LLUUID source_id; - LLWString paste = gClipboard.getPasteWString(&source_id); - if (!paste.empty()) + return; + } + // Delete any selected characters (the paste replaces them) + if( hasSelection() ) + { + deleteSelection(TRUE); + } + + // Clean up string (replace tabs and remove characters that our fonts don't support). + LLWString clean_string(paste); + LLWString::replaceTabsWithSpaces(clean_string, SPACES_PER_TAB); + if( mAllowEmbeddedItems ) + { + const llwchar LF = 10; + S32 len = clean_string.length(); + for( S32 i = 0; i < len; i++ ) { - // Delete any selected characters (the paste replaces them) - if( hasSelection() ) + llwchar wc = clean_string[i]; + if( (wc < LLFont::FIRST_CHAR) && (wc != LF) ) { - deleteSelection(TRUE); + clean_string[i] = LL_UNKNOWN_CHAR; } - - // Clean up string (replace tabs and remove characters that our fonts don't support). - LLWString clean_string(paste); - LLWString::replaceTabsWithSpaces(clean_string, SPACES_PER_TAB); - if( mAllowEmbeddedItems ) + else if (wc >= FIRST_EMBEDDED_CHAR && wc <= LAST_EMBEDDED_CHAR) { - const llwchar LF = 10; - S32 len = clean_string.length(); - for( S32 i = 0; i < len; i++ ) - { - llwchar wc = clean_string[i]; - if( (wc < LLFont::FIRST_CHAR) && (wc != LF) ) - { - clean_string[i] = LL_UNKNOWN_CHAR; - } - else if (wc >= FIRST_EMBEDDED_CHAR && wc <= LAST_EMBEDDED_CHAR) - { - clean_string[i] = pasteEmbeddedItem(wc); - } - } + clean_string[i] = pasteEmbeddedItem(wc); } - - // Insert the new text into the existing text. - setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE)); - deselect(); - - updateLineStartList(); - updateScrollFromCursor(); } } + + // Insert the new text into the existing text. + setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE)); + deselect(); + + updateLineStartList(); + updateScrollFromCursor(); } @@ -2240,7 +2165,7 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) { // Special case for TAB. If want to move to next field, report // not handled and let the parent take care of field movement. - if (KEY_TAB == key && mTabToNextField) + if (KEY_TAB == key && mTabsToNextField) { return FALSE; } @@ -2296,7 +2221,7 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent ) if( handled ) { - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); // Most keystrokes will make the selection box go away, but not all will. if( !selection_modified && @@ -2350,7 +2275,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_pare if( handled ) { - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); // Most keystrokes will make the selection box go away, but not all will. deselect(); @@ -2364,58 +2289,58 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_pare } - -BOOL LLTextEditor::canDoDelete() +// virtual +BOOL LLTextEditor::canDoDelete() const { return !mReadOnly && ( hasSelection() || (mCursorPos < getLength()) ); } void LLTextEditor::doDelete() { - if( canDoDelete() ) + if( !canDoDelete() ) { - if( hasSelection() ) + return; + } + if( hasSelection() ) + { + deleteSelection(FALSE); + } + else + if( mCursorPos < getLength() ) + { + S32 i; + S32 chars_to_remove = 1; + const LLWString &text = mWText; + if( (text[ mCursorPos ] == ' ') && (mCursorPos + SPACES_PER_TAB < getLength()) ) { - deleteSelection(FALSE); - } - else - if( mCursorPos < getLength() ) - { - S32 i; - S32 chars_to_remove = 1; - const LLWString &text = mWText; - if( (text[ mCursorPos ] == ' ') && (mCursorPos + SPACES_PER_TAB < getLength()) ) + // Try to remove a full tab's worth of spaces + S32 line, offset; + getLineAndOffset( mCursorPos, &line, &offset ); + chars_to_remove = SPACES_PER_TAB - (offset % SPACES_PER_TAB); + if( chars_to_remove == 0 ) { - // Try to remove a full tab's worth of spaces - S32 line, offset; - getLineAndOffset( mCursorPos, &line, &offset ); - chars_to_remove = SPACES_PER_TAB - (offset % SPACES_PER_TAB); - if( chars_to_remove == 0 ) - { - chars_to_remove = SPACES_PER_TAB; - } - - for( i = 0; i < chars_to_remove; i++ ) - { - if( text[mCursorPos + i] != ' ' ) - { - chars_to_remove = 1; - break; - } - } + chars_to_remove = SPACES_PER_TAB; } - for( i = 0; i < chars_to_remove; i++ ) { - setCursorPos(mCursorPos + 1); - removeChar(); + if( text[mCursorPos + i] != ' ' ) + { + chars_to_remove = 1; + break; + } } } - updateLineStartList(); - updateScrollFromCursor(); + for( i = 0; i < chars_to_remove; i++ ) + { + setCursorPos(mCursorPos + 1); + removeChar(); + } } + + updateLineStartList(); + updateScrollFromCursor(); } //---------------------------------------------------------------------------- @@ -2429,65 +2354,66 @@ void LLTextEditor::blockUndo() mUndoStack.clear(); } - -BOOL LLTextEditor::canUndo() +// virtual +BOOL LLTextEditor::canUndo() const { return !mReadOnly && mLastCmd != NULL; } void LLTextEditor::undo() { - if( canUndo() ) + if( !canUndo() ) { - deselect(); - - S32 pos = 0; - do - { - pos = mLastCmd->undo(this); - undo_stack_t::iterator iter = std::find(mUndoStack.begin(), mUndoStack.end(), mLastCmd); - if (iter != mUndoStack.end()) - ++iter; - if (iter != mUndoStack.end()) - mLastCmd = *iter; - else - mLastCmd = NULL; + return; + } + deselect(); + S32 pos = 0; + do + { + pos = mLastCmd->undo(this); + undo_stack_t::iterator iter = std::find(mUndoStack.begin(), mUndoStack.end(), mLastCmd); + if (iter != mUndoStack.end()) + ++iter; + if (iter != mUndoStack.end()) + mLastCmd = *iter; + else + mLastCmd = NULL; } while( mLastCmd && mLastCmd->groupWithNext() ); setCursorPos(pos); - updateLineStartList(); - updateScrollFromCursor(); - } + updateLineStartList(); + updateScrollFromCursor(); } -BOOL LLTextEditor::canRedo() +BOOL LLTextEditor::canRedo() const { return !mReadOnly && (mUndoStack.size() > 0) && (mLastCmd != mUndoStack.front()); } void LLTextEditor::redo() { - if( canRedo() ) + if( !canRedo() ) { - deselect(); - - S32 pos = 0; - do + return; + } + deselect(); + S32 pos = 0; + do + { + if( !mLastCmd ) { - if( !mLastCmd ) - { - mLastCmd = mUndoStack.back(); - } + mLastCmd = mUndoStack.back(); + } + else + { + undo_stack_t::iterator iter = std::find(mUndoStack.begin(), mUndoStack.end(), mLastCmd); + if (iter != mUndoStack.begin()) + mLastCmd = *(--iter); else - { - undo_stack_t::iterator iter = std::find(mUndoStack.begin(), mUndoStack.end(), mLastCmd); - if (iter != mUndoStack.begin()) - mLastCmd = *(--iter); - else - mLastCmd = NULL; - } + mLastCmd = NULL; + } if( mLastCmd ) { @@ -2500,9 +2426,8 @@ void LLTextEditor::redo() setCursorPos(pos); - updateLineStartList(); - updateScrollFromCursor(); - } + updateLineStartList(); + updateScrollFromCursor(); } void LLTextEditor::onFocusReceived() @@ -2548,8 +2473,8 @@ void LLTextEditor::setEnabled(BOOL enabled) void LLTextEditor::drawBackground() { S32 left = 0; - S32 top = mRect.getHeight(); - S32 right = mRect.getWidth(); + S32 top = getRect().getHeight(); + S32 right = getRect().getWidth(); S32 bottom = 0; LLColor4 bg_color = mReadOnlyBgColor; @@ -2677,7 +2602,7 @@ void LLTextEditor::drawSelectionBackground() LLGLSNoTexture no_texture; const LLColor4& color = mReadOnly ? mReadOnlyBgColor : mWriteableBgColor; F32 alpha = hasFocus() ? 1.f : 0.5f; - glColor4f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], alpha ); + gGL.color4f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], alpha ); if( selection_left_y == selection_right_y ) { @@ -2805,14 +2730,14 @@ void LLTextEditor::drawCursor() LLGLSNoTexture no_texture; - glColor4fv( mCursorColor.mV ); + gGL.color4fv( mCursorColor.mV ); gl_rect_2d(llfloor(cursor_left), llfloor(cursor_top), llfloor(cursor_right), llfloor(cursor_bottom)); if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection() && text[mCursorPos] != '\n') { - LLTextSegment* segmentp = getSegmentAtOffset(mCursorPos); + const LLTextSegment* segmentp = getSegmentAtOffset(mCursorPos); LLColor4 text_color; if (segmentp) { @@ -2826,7 +2751,6 @@ void LLTextEditor::drawCursor() { text_color = mFgColor; } - LLGLSTexture texture; mGLFont->render(text, mCursorPos, next_char_left, cursor_bottom + line_height, LLColor4(1.f - text_color.mV[VRED], 1.f - text_color.mV[VGREEN], 1.f - text_color.mV[VBLUE], 1.f), LLFontGL::LEFT, LLFontGL::TOP, @@ -2945,122 +2869,118 @@ void LLTextEditor::drawText() { const LLWString &text = mWText; const S32 text_len = getLength(); + if( text_len <= 0 ) + { + return; + } + S32 selection_left = -1; + S32 selection_right = -1; + // Draw selection even if we don't have keyboard focus for search/replace + if( hasSelection()) + { + selection_left = llmin( mSelectionStart, mSelectionEnd ); + selection_right = llmax( mSelectionStart, mSelectionEnd ); + } - if( text_len > 0 ) + LLGLSUIDefault gls_ui; + + S32 cur_line = mScrollbar->getDocPos(); + S32 num_lines = getLineCount(); + if (cur_line >= num_lines) + { + return; + } + + S32 line_start = getLineStart(cur_line); + LLTextSegment t(line_start); + segment_list_t::iterator seg_iter; + seg_iter = std::upper_bound(mSegments.begin(), mSegments.end(), &t, LLTextSegment::compare()); + if (seg_iter == mSegments.end() || (*seg_iter)->getStart() > line_start) --seg_iter; + LLTextSegment* cur_segment = *seg_iter; + + S32 line_height = llround( mGLFont->getLineHeight() ); + F32 text_y = (F32)(mTextRect.mTop - line_height); + while((mTextRect.mBottom <= text_y) && (cur_line < num_lines)) { - S32 selection_left = -1; - S32 selection_right = -1; - // Draw selection even if we don't have keyboard focus for search/replace - if( hasSelection()) + S32 next_start = -1; + S32 line_end = text_len; + + if ((cur_line + 1) < num_lines) { - selection_left = llmin( mSelectionStart, mSelectionEnd ); - selection_right = llmax( mSelectionStart, mSelectionEnd ); + next_start = getLineStart(cur_line + 1); + line_end = next_start; } - - LLGLSUIDefault gls_ui; - - S32 cur_line = mScrollbar->getDocPos(); - S32 num_lines = getLineCount(); - if (cur_line >= num_lines) + if ( text[line_end-1] == '\n' ) { - return; + --line_end; } - S32 line_start = getLineStart(cur_line); - LLTextSegment t(line_start); - segment_list_t::iterator seg_iter; - seg_iter = std::upper_bound(mSegments.begin(), mSegments.end(), &t, LLTextSegment::compare()); - if (seg_iter == mSegments.end() || (*seg_iter)->getStart() > line_start) --seg_iter; - LLTextSegment* cur_segment = *seg_iter; - - S32 line_height = llround( mGLFont->getLineHeight() ); - F32 text_y = (F32)(mTextRect.mTop - line_height); - while((mTextRect.mBottom <= text_y) && (cur_line < num_lines)) - { - S32 next_start = -1; - S32 line_end = text_len; + F32 text_x = (F32)mTextRect.mLeft; - if ((cur_line + 1) < num_lines) - { - next_start = getLineStart(cur_line + 1); - line_end = next_start; - } - if ( text[line_end-1] == '\n' ) + S32 seg_start = line_start; + while( seg_start < line_end ) + { + while( cur_segment->getEnd() <= seg_start ) { - --line_end; + seg_iter++; + if (seg_iter == mSegments.end()) + { + llwarns << "Ran off the segmentation end!" << llendl; + return; + } + cur_segment = *seg_iter; } - F32 text_x = (F32)mTextRect.mLeft; - - S32 seg_start = line_start; - while( seg_start < line_end ) + // Draw a segment within the line + S32 clipped_end = llmin( line_end, cur_segment->getEnd() ); + S32 clipped_len = clipped_end - seg_start; + if( clipped_len > 0 ) { - while( cur_segment->getEnd() <= seg_start ) + LLStyle style = cur_segment->getStyle(); + if ( style.isImage() && (cur_segment->getStart() >= seg_start) && (cur_segment->getStart() <= clipped_end)) { - seg_iter++; - if (seg_iter == mSegments.end()) - { - llwarns << "Ran off the segmentation end!" << llendl; - return; - } - cur_segment = *seg_iter; + LLImageGL *image = style.getImage(); + gl_draw_scaled_image( llround(text_x), llround(text_y)+line_height-style.mImageHeight, style.mImageWidth, style.mImageHeight, image, LLColor4::white ); } - - // Draw a segment within the line - S32 clipped_end = llmin( line_end, cur_segment->getEnd() ); - S32 clipped_len = clipped_end - seg_start; - if( clipped_len > 0 ) - { - LLStyle style = cur_segment->getStyle(); - if ( style.isImage() && (cur_segment->getStart() >= seg_start) && (cur_segment->getStart() <= clipped_end)) - { - LLImageGL *image = style.getImage(); - - gl_draw_scaled_image( llround(text_x), llround(text_y)+line_height-style.mImageHeight, style.mImageWidth, style.mImageHeight, image, LLColor4::white ); - - } - if (cur_segment == mHoverSegment && style.getIsEmbeddedItem()) - { - style.mUnderline = TRUE; - } + if (cur_segment == mHoverSegment && style.getIsEmbeddedItem()) + { + style.mUnderline = TRUE; + } - S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); - - if ( (mParseHTML) && (left_pos > seg_start) && (left_pos < clipped_end) && mIsSelecting && (mSelectionStart == mSelectionEnd) ) - { - mHTML = style.getLinkHREF(); - } + S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); + + if ( (mParseHTML) && (left_pos > seg_start) && (left_pos < clipped_end) && mIsSelecting && (mSelectionStart == mSelectionEnd) ) + { + mHTML = style.getLinkHREF(); + } - drawClippedSegment( text, seg_start, clipped_end, text_x, text_y, selection_left, selection_right, style, &text_x ); + drawClippedSegment( text, seg_start, clipped_end, text_x, text_y, selection_left, selection_right, style, &text_x ); - // Note: text_x is incremented by drawClippedSegment() - seg_start += clipped_len; - } + // Note: text_x is incremented by drawClippedSegment() + seg_start += clipped_len; } + } // move down one line text_y -= (F32)line_height; - line_start = next_start; - cur_line++; - } + line_start = next_start; + cur_line++; } } // Draws a single text segment, reversing the color for selection if needed. void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyle& style, F32* right_x ) { - const LLFontGL* font = mGLFont; - - LLColor4 color; - if (!style.isVisible()) { return; } - color = style.getColor(); + const LLFontGL* font = mGLFont; + + LLColor4 color = style.getColor(); if ( style.getFontString()[0] ) { @@ -3131,12 +3051,14 @@ void LLTextEditor::drawClippedSegment(const LLWString &text, S32 seg_start, S32 void LLTextEditor::draw() { - if( getVisible() ) + if( !getVisible() ) { - { - LLLocalClipRect clip(LLRect(0, mRect.getHeight(), mRect.getWidth() - (mScrollbar->getVisible() ? SCROLLBAR_SIZE : 0), 0)); + return; + } + { + LLLocalClipRect clip(LLRect(0, getRect().getHeight(), getRect().getWidth() - (mScrollbar->getVisible() ? SCROLLBAR_SIZE : 0), 0)); - bindEmbeddedChars( mGLFont ); + bindEmbeddedChars( const_cast(mGLFont) ); drawBackground(); drawSelectionBackground(); @@ -3144,34 +3066,30 @@ void LLTextEditor::draw() drawText(); drawCursor(); - unbindEmbeddedChars( mGLFont ); + unbindEmbeddedChars( const_cast(mGLFont) ); - //RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret - // when in readonly mode - mBorder->setKeyboardFocusHighlight( gFocusMgr.getKeyboardFocus() == this);// && !mReadOnly); - } - LLView::draw(); // Draw children (scrollbar and border) + //RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret + // when in readonly mode + mBorder->setKeyboardFocusHighlight( gFocusMgr.getKeyboardFocus() == this);// && !mReadOnly); } // remember if we are supposed to be at the bottom of the buffer mScrolledToBottom = isScrolledToBottom(); -} -void LLTextEditor::reportBadKeystroke() -{ - make_ui_sound("UISndBadKeystroke"); + LLView::draw(); // Draw children (scrollbar and border) } void LLTextEditor::onTabInto() { // selecting all on tabInto causes users to hit tab twice and replace their text with a tab character - // theoretically, one could selectAll if mTabToNextField is true, but we couldn't think of a use case + // theoretically, one could selectAll if mTabsToNextField is true, but we couldn't think of a use case // where you'd want to select all anyway // preserve insertion point when returning to the editor //selectAll(); } +// virtual void LLTextEditor::clear() { setText(LLString::null); @@ -3200,7 +3118,7 @@ void LLTextEditor::setFocus( BOOL new_state ) gEditMenuHandler = this; // Don't start the cursor flashing right away - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); } else { @@ -3214,6 +3132,7 @@ void LLTextEditor::setFocus( BOOL new_state ) } } +// virtual BOOL LLTextEditor::acceptsTextInput() const { return !mReadOnly; @@ -3268,7 +3187,7 @@ void LLTextEditor::changePage( S32 delta ) void LLTextEditor::changeLine( S32 delta ) { - bindEmbeddedChars( mGLFont ); + bindEmbeddedChars( const_cast(mGLFont) ); S32 line, offset; getLineAndOffset( mCursorPos, &line, &offset ); @@ -3295,7 +3214,7 @@ void LLTextEditor::changeLine( S32 delta ) } else { - unbindEmbeddedChars( mGLFont ); + unbindEmbeddedChars( const_cast(mGLFont) ); return; } @@ -3320,7 +3239,7 @@ void LLTextEditor::changeLine( S32 delta ) // put desired position into remember-buffer after setCursorPos() mDesiredXPixel = desired_x_pixel; - unbindEmbeddedChars( mGLFont ); + unbindEmbeddedChars( const_cast(mGLFont) ); } BOOL LLTextEditor::isScrolledToTop() @@ -3768,20 +3687,14 @@ BOOL LLTextEditor::tryToRevertToPristineState() return isPristine(); // TRUE => success } -// virtual Return TRUE if changes have been made -BOOL LLTextEditor::isDirty() const -{ - return( mLastCmd != NULL || (mPristineCmd && (mPristineCmd != mLastCmd)) ); -} - void LLTextEditor::updateTextRect() { mTextRect.setOriginAndSize( UI_TEXTEDITOR_BORDER + UI_TEXTEDITOR_H_PAD, UI_TEXTEDITOR_BORDER, - mRect.getWidth() - SCROLLBAR_SIZE - 2 * (UI_TEXTEDITOR_BORDER + UI_TEXTEDITOR_H_PAD), - mRect.getHeight() - 2 * UI_TEXTEDITOR_BORDER - UI_TEXTEDITOR_V_PAD_TOP ); + getRect().getWidth() - SCROLLBAR_SIZE - 2 * (UI_TEXTEDITOR_BORDER + UI_TEXTEDITOR_H_PAD), + getRect().getHeight() - 2 * UI_TEXTEDITOR_BORDER - UI_TEXTEDITOR_V_PAD_TOP ); } void LLTextEditor::loadKeywords(const LLString& filename, @@ -3862,8 +3775,7 @@ void LLTextEditor::pruneSegments() } else { - llwarns << "Tried to erase end of empty LLTextEditor" - << llendl; + llwarns << "Tried to erase end of empty LLTextEditor" << llendl; } } @@ -3949,21 +3861,9 @@ BOOL LLTextEditor::handleMouseUpOverSegment(S32 x, S32 y, MASK mask) return FALSE; } -llwchar LLTextEditor::pasteEmbeddedItem(llwchar ext_char) -{ - return ext_char; -} - -void LLTextEditor::bindEmbeddedChars(const LLFontGL* font) -{ -} - -void LLTextEditor::unbindEmbeddedChars(const LLFontGL* font) -{ -} // Finds the text segment (if any) at the give local screen position -LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) +const LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) const { // Find the cursor position at the requested local screen position S32 offset = getCursorPosFromLocalCoord( x, y, FALSE ); @@ -3971,13 +3871,13 @@ LLTextSegment* LLTextEditor::getSegmentAtLocalPos( S32 x, S32 y ) return idx >= 0 ? mSegments[idx] : NULL; } -LLTextSegment* LLTextEditor::getSegmentAtOffset(S32 offset) +const LLTextSegment* LLTextEditor::getSegmentAtOffset(S32 offset) const { S32 idx = getSegmentIdxAtOffset(offset); return idx >= 0 ? mSegments[idx] : NULL; } -S32 LLTextEditor::getSegmentIdxAtOffset(S32 offset) +S32 LLTextEditor::getSegmentIdxAtOffset(S32 offset) const { if (mSegments.empty() || offset < 0 || offset >= getLength()) { @@ -4149,7 +4049,7 @@ LLTextSegment::LLTextSegment( const LLColor3& color, S32 start, S32 end ) : { } -BOOL LLTextSegment::getToolTip(LLString& msg) +BOOL LLTextSegment::getToolTip(LLString& msg) const { if (mToken && !mToken->getToolTip().empty()) { @@ -4162,7 +4062,7 @@ BOOL LLTextSegment::getToolTip(LLString& msg) -void LLTextSegment::dump() +void LLTextSegment::dump() const { llinfos << "Segment [" << // mColor.mV[VX] << ", " << @@ -4182,13 +4082,9 @@ LLXMLNodePtr LLTextEditor::getXML(bool save_children) const // Attributes node->createChild("max_length", TRUE)->setIntValue(getMaxLength()); - node->createChild("embedded_items", TRUE)->setBoolValue(mAllowEmbeddedItems); - node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mGLFont)); - node->createChild("word_wrap", TRUE)->setBoolValue(mWordWrap); - node->createChild("hide_scrollbar", TRUE)->setBoolValue(mHideScrollbarForShortDocs); addColorXML(node, mCursorColor, "cursor_color", "TextCursorColor"); @@ -4274,7 +4170,7 @@ void LLTextEditor::setTextEditorParameters(LLXMLNodePtr node) } /////////////////////////////////////////////////////////////////// -S32 LLTextEditor::findHTMLToken(const LLString &line, S32 pos, BOOL reverse) +S32 LLTextEditor::findHTMLToken(const LLString &line, S32 pos, BOOL reverse) const { LLString openers=" \t('\"[{<>"; LLString closers=" \t)'\"]}><;"; @@ -4311,7 +4207,7 @@ S32 LLTextEditor::findHTMLToken(const LLString &line, S32 pos, BOOL reverse) return retval; } -BOOL LLTextEditor::findHTML(const LLString &line, S32 *begin, S32 *end) +BOOL LLTextEditor::findHTML(const LLString &line, S32 *begin, S32 *end) const { S32 m1,m2,m3; diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h index 4c92297..82d9069 100644 --- a/linden/indra/llui/lltexteditor.h +++ b/linden/indra/llui/lltexteditor.h @@ -52,24 +52,16 @@ class LLKeywordToken; class LLTextCmd; class LLUICtrlFactory; -// -// Constants -// - -const llwchar FIRST_EMBEDDED_CHAR = 0x100000; -const llwchar LAST_EMBEDDED_CHAR = 0x10ffff; -const S32 MAX_EMBEDDED_ITEMS = LAST_EMBEDDED_CHAR - FIRST_EMBEDDED_CHAR + 1; - -// -// Classes -// -class LLTextSegment; -class LLTextCmd; - class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor { - friend class LLTextCmd; public: + // + // Constants + // + static const llwchar FIRST_EMBEDDED_CHAR = 0x100000; + static const llwchar LAST_EMBEDDED_CHAR = 0x10ffff; + static const S32 MAX_EMBEDDED_ITEMS = LAST_EMBEDDED_CHAR - FIRST_EMBEDDED_CHAR + 1; + LLTextEditor(const LLString& name, const LLRect& rect, S32 max_length, @@ -80,10 +72,10 @@ public: virtual ~LLTextEditor(); virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TEXT_EDITOR; } - virtual LLString getWidgetTag() const; + virtual LLString getWidgetTag() const { return LL_TEXT_EDITOR_TAG; } virtual LLXMLNodePtr getXML(bool save_children = true) const; - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); void setTextEditorParameters(LLXMLNodePtr node); void setParseHTML(BOOL parsing) {mParseHTML=parsing;} @@ -102,7 +94,6 @@ public: EAcceptance *accept, LLString& tooltip_msg); virtual void onMouseCaptureLost(); - // view overrides virtual void reshape(S32 width, S32 height, BOOL called_from_parent); virtual void draw(); @@ -115,32 +106,25 @@ public: virtual void clear(); virtual void setFocus( BOOL b ); virtual BOOL acceptsTextInput() const; - virtual BOOL isDirty() const; + virtual BOOL isDirty() const { return( mLastCmd != NULL || (mPristineCmd && (mPristineCmd != mLastCmd)) ); } // LLEditMenuHandler interface virtual void undo(); - virtual BOOL canUndo(); - + virtual BOOL canUndo() const; virtual void redo(); - virtual BOOL canRedo(); - + virtual BOOL canRedo() const; virtual void cut(); - virtual BOOL canCut(); - + virtual BOOL canCut() const; virtual void copy(); - virtual BOOL canCopy(); - + virtual BOOL canCopy() const; virtual void paste(); - virtual BOOL canPaste(); - + virtual BOOL canPaste() const; virtual void doDelete(); - virtual BOOL canDoDelete(); - + virtual BOOL canDoDelete() const; virtual void selectAll(); - virtual BOOL canSelectAll(); - + virtual BOOL canSelectAll() const; virtual void deselect(); - virtual BOOL canDeselect(); + virtual BOOL canDeselect() const; void selectNext(const LLString& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); BOOL replaceText(const LLString& search_text, const LLString& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); @@ -152,6 +136,7 @@ public: // Text editing virtual void makePristine(); BOOL isPristine() const; + BOOL allowsEmbeddedItems() const { return mAllowEmbeddedItems; } // inserts text at cursor void insertText(const LLString &text); @@ -180,18 +165,21 @@ public: void getCurrentLineAndColumn( S32* line, S32* col, BOOL include_wordwrap ); + // Keywords support void loadKeywords(const LLString& filename, const LLDynamicArray& funcs, const LLDynamicArray& tooltips, const LLColor3& func_color); + LLKeywords::keyword_iterator_t keywordsBegin() { return mKeywords.begin(); } + LLKeywords::keyword_iterator_t keywordsEnd() { return mKeywords.end(); } + // Color support void setCursorColor(const LLColor4& c) { mCursorColor = c; } void setFgColor( const LLColor4& c ) { mFgColor = c; } void setTextDefaultColor( const LLColor4& c ) { mDefaultColor = c; } void setReadOnlyFgColor( const LLColor4& c ) { mReadOnlyFgColor = c; } void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; } void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } - void setTrackColor( const LLColor4& color ); void setThumbColor( const LLColor4& color ); void setHighlightColor( const LLColor4& color ); @@ -200,11 +188,13 @@ public: // Hacky methods to make it into a word-wrapping, potentially scrolling, // read-only text box. void setBorderVisible(BOOL b); - void setTakesNonScrollClicks(BOOL b); + BOOL isBorderVisible() const; + void setTakesNonScrollClicks(BOOL b) { mTakesNonScrollClicks = b; } void setHideScrollbarForShortDocs(BOOL b); void setWordWrap( BOOL b ); - void setTabToNextField(BOOL b) { mTabToNextField = b; } + void setTabsToNextField(BOOL b) { mTabsToNextField = b; } + BOOL tabsToNextField() const { return mTabsToNextField; } void setCommitOnFocusLost(BOOL b) { mCommitOnFocusLost = b; } // Hack to handle Notecards @@ -215,7 +205,9 @@ public: void setTakesFocus(BOOL b) { mTakesFocus = b; } void setSourceID(const LLUUID& id) { mSourceID = id; } + const LLUUID& getSourceID() const { return mSourceID; } void setAcceptCallingCardNames(BOOL enable) { mAcceptCallingCardNames = enable; } + BOOL acceptsCallingCardNames() const { return mAcceptCallingCardNames; } void setHandleEditKeysDirectly( BOOL b ) { mHandleEditKeysDirectly = b; } @@ -250,49 +242,46 @@ public: BOOL isScrolledToBottom(); // Getters - const LLWString& getWText() const; - llwchar getWChar(S32 pos); - LLWString getWSubString(S32 pos, S32 len); + const LLWString& getWText() const { return mWText; } + llwchar getWChar(S32 pos) const { return mWText[pos]; } + LLWString getWSubString(S32 pos, S32 len) const { return mWText.substr(pos, len); } - LLTextSegment* getCurrentSegment(); - LLTextSegment* getPreviousSegment(); - void getSelectedSegments(std::vector& segments); + const LLTextSegment* getCurrentSegment() { return getSegmentAtOffset(mCursorPos); } + const LLTextSegment* getPreviousSegment(); + void getSelectedSegments(std::vector& segments); protected: - S32 getLength() const; - void getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ); + // + // Methods + // - void drawBackground(); - void drawSelectionBackground(); - void drawCursor(); - void drawText(); - void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyle& color, F32* right_x); + S32 getLength() const { return mWText.length(); } + void getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) const; void drawPreeditMarker(); void updateLineStartList(S32 startpos = 0); void updateScrollFromCursor(); void updateTextRect(); - void updateSegments(); - void pruneSegments(); + const LLRect& getTextRect() const { return mTextRect; } void assignEmbedded(const LLString &s); BOOL truncate(); // Returns true if truncation occurs - static BOOL isPartOfWord(llwchar c); + static BOOL isPartOfWord(llwchar c) { return (c == '_') || isalnum(c); } void removeCharOrTab(); void setCursorAtLocalPos(S32 x, S32 y, BOOL round); - S32 getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ); + S32 getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const; void indentSelectedLines( S32 spaces ); S32 indentLine( S32 pos, S32 spaces ); void unindentLineBeforeCloseBrace(); - S32 getSegmentIdxAtOffset(S32 offset); - LLTextSegment* getSegmentAtLocalPos(S32 x, S32 y); - LLTextSegment* getSegmentAtOffset(S32 offset); + S32 getSegmentIdxAtOffset(S32 offset) const; + const LLTextSegment* getSegmentAtLocalPos(S32 x, S32 y) const; + const LLTextSegment* getSegmentAtOffset(S32 offset) const; - void reportBadKeystroke(); + void reportBadKeystroke() { make_ui_sound("UISndBadKeystroke"); } BOOL handleNavigationKey(const KEY key, const MASK mask); BOOL handleSpecialKey(const KEY key, const MASK mask, BOOL* return_key_hit); @@ -309,29 +298,58 @@ protected: S32 prevWordPos(S32 cursorPos) const; S32 nextWordPos(S32 cursorPos) const; - S32 getLineCount() const; + S32 getLineCount() const { return mLineStartList.size(); } S32 getLineStart( S32 line ) const; - void getLineAndOffset(S32 pos, S32* linep, S32* offsetp); + void getLineAndOffset(S32 pos, S32* linep, S32* offsetp) const; S32 getPos(S32 line, S32 offset); void changePage(S32 delta); void changeLine(S32 delta); void autoIndent(); - - S32 execute(LLTextCmd* cmd); void findEmbeddedItemSegments(); virtual BOOL handleMouseUpOverSegment(S32 x, S32 y, MASK mask); - virtual llwchar pasteEmbeddedItem(llwchar ext_char); - virtual void bindEmbeddedChars(const LLFontGL* font); - virtual void unbindEmbeddedChars(const LLFontGL* font); + + virtual llwchar pasteEmbeddedItem(llwchar ext_char) { return ext_char; } + virtual void bindEmbeddedChars(LLFontGL* font) const {} + virtual void unbindEmbeddedChars(LLFontGL* font) const {} - S32 findHTMLToken(const LLString &line, S32 pos, BOOL reverse); - BOOL findHTML(const LLString &line, S32 *begin, S32 *end); + S32 findHTMLToken(const LLString &line, S32 pos, BOOL reverse) const; + BOOL findHTML(const LLString &line, S32 *begin, S32 *end) const; + + // Abstract inner base class representing an undoable editor command. + // Concrete sub-classes can be defined for operations such as insert, remove, etc. + // Used as arguments to the execute() method below. + class LLTextCmd + { + public: + LLTextCmd( S32 pos, BOOL group_with_next ) : mPos(pos), mGroupWithNext(group_with_next) {} + virtual ~LLTextCmd() {} + virtual BOOL execute(LLTextEditor* editor, S32* delta) = 0; + virtual S32 undo(LLTextEditor* editor) = 0; + virtual S32 redo(LLTextEditor* editor) = 0; + virtual BOOL canExtend(S32 pos) const { return FALSE; } + virtual void blockExtensions() {} + virtual BOOL extendAndExecute( LLTextEditor* editor, S32 pos, llwchar c, S32* delta ) { llassert(0); return 0; } + virtual BOOL hasExtCharValue( llwchar value ) const { return FALSE; } + + // Defined here so they can access protected LLTextEditor editing methods + S32 insert(LLTextEditor* editor, S32 pos, const LLWString &wstr) { return editor->insertStringNoUndo( pos, wstr ); } + S32 remove(LLTextEditor* editor, S32 pos, S32 length) { return editor->removeStringNoUndo( pos, length ); } + S32 overwrite(LLTextEditor* editor, S32 pos, llwchar wc) { return editor->overwriteCharNoUndo(pos, wc); } + + S32 getPosition() const { return mPos; } + BOOL groupWithNext() const { return mGroupWithNext; } + + private: + const S32 mPos; + BOOL mGroupWithNext; + }; + // Here's the method that takes and applies text commands. + S32 execute(LLTextCmd* cmd); -protected: // Undoable operations void addChar(llwchar c); // at mCursorPos S32 addChar(S32 pos, llwchar wc); @@ -342,12 +360,13 @@ protected: S32 remove(const S32 pos, const S32 length, const BOOL group_with_next_op); S32 append(const LLWString &wstr, const BOOL group_with_next_op); - // direct operations + // Direct operations S32 insertStringNoUndo(S32 pos, const LLWString &wstr); // returns num of chars actually inserted S32 removeStringNoUndo(S32 pos, S32 length); S32 overwriteCharNoUndo(S32 pos, llwchar wc); - -protected: + + void resetKeystrokeTimer() { mKeystrokeTimer.reset(); } + void updateAllowingLanguageInput(); BOOL hasPreeditString() const; @@ -360,14 +379,76 @@ protected: virtual void getSelectionRange(S32 *position, S32 *length) const; virtual BOOL getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const; virtual S32 getPreeditFontSize() const; + // + // Protected data + // + // Probably deserves serious thought to hiding as many of these + // as possible behind protected accessor methods. + // -public: + // I-beam is just after the mCursorPos-th character. + S32 mCursorPos; + + // Use these to determine if a click on an embedded item is a drag or not. + S32 mMouseDownX; + S32 mMouseDownY; + + // Are we in the middle of a drag-select? To figure out if there is a current + // selection, call hasSelection(). + BOOL mIsSelecting; + S32 mSelectionStart; + S32 mSelectionEnd; + S32 mLastSelectionX; + S32 mLastSelectionY; + + BOOL mParseHTML; + LLString mHTML; + + typedef std::vector segment_list_t; + segment_list_t mSegments; + const LLTextSegment* mHoverSegment; + + // Scrollbar data + class LLScrollbar* mScrollbar; + BOOL mHideScrollbarForShortDocs; + BOOL mTakesNonScrollClicks; + void (*mOnScrollEndCallback)(void*); + void *mOnScrollEndData; + + LLWString mPreeditWString; + LLWString mPreeditOverwrittenWString; + std::vector mPreeditPositions; + std::vector mPreeditStandouts; + +private: + + // + // Methods + // + void updateSegments(); + void pruneSegments(); + + void drawBackground(); + void drawSelectionBackground(); + void drawCursor(); + void drawText(); + void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyle& color, F32* right_x); + + // + // Data + // LLKeywords mKeywords; static LLColor4 mLinkColor; static void (*mURLcallback) (const char* url); static bool (*mSecondlifeURLcallback) (const std::string& url); static bool (*mSecondlifeURLcallbackRightClick) (const std::string& url); -protected: + + // Concrete LLTextCmd sub-classes used by the LLTextEditor base class + class LLTextCmdInsert; + class LLTextCmdAddChar; + class LLTextCmdOverwriteChar; + class LLTextCmdRemove; + LLWString mWText; mutable LLString mUTF8Text; mutable BOOL mTextIsUpToDate; @@ -376,8 +457,7 @@ protected: const LLFontGL* mGLFont; - LLScrollbar* mScrollbar; - LLViewBorder* mBorder; + class LLViewBorder* mBorder; BOOL mBaseDocIsPristine; LLTextCmd* mPristineCmd; @@ -387,7 +467,6 @@ protected: typedef std::deque undo_stack_t; undo_stack_t mUndoStack; - S32 mCursorPos; // I-beam is just after the mCursorPos-th character. S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be LLRect mTextRect; // The rect in which text is drawn. Excludes borders. // List of offsets and segment index of the start of each line. Always has at least one node (0). @@ -411,20 +490,7 @@ protected: }; typedef std::vector line_list_t; line_list_t mLineStartList; - - // Are we in the middle of a drag-select? To figure out if there is a current - // selection, call hasSelection(). - BOOL mIsSelecting; - - S32 mSelectionStart; - S32 mSelectionEnd; - - void (*mOnScrollEndCallback)(void*); - void *mOnScrollEndData; - typedef std::vector segment_list_t; - segment_list_t mSegments; - LLTextSegment* mHoverSegment; LLFrameTimer mKeystrokeTimer; LLColor4 mCursorColor; @@ -439,11 +505,9 @@ protected: BOOL mReadOnly; BOOL mWordWrap; - BOOL mTabToNextField; // if true, tab moves focus to next field, else inserts spaces + BOOL mTabsToNextField; // if true, tab moves focus to next field, else inserts spaces BOOL mCommitOnFocusLost; BOOL mTakesFocus; - BOOL mHideScrollbarForShortDocs; - BOOL mTakesNonScrollClicks; BOOL mTrackBottom; // if true, keeps scroll position at bottom during resize BOOL mScrolledToBottom; @@ -453,24 +517,14 @@ protected: LLUUID mSourceID; - BOOL mHandleEditKeysDirectly; // If true, the standard edit keys (Ctrl-X, Delete, etc,) are handled here instead of routed by the menu system + // If true, the standard edit keys (Ctrl-X, Delete, etc,) are handled here + //instead of routed by the menu system + BOOL mHandleEditKeysDirectly; - // Use these to determine if a click on an embedded item is a drag - // or not. - S32 mMouseDownX; - S32 mMouseDownY; + LLCoordGL mLastIMEPosition; // Last position of the IME editor +}; // end class LLTextEditor - S32 mLastSelectionX; - S32 mLastSelectionY; - BOOL mParseHTML; - LLString mHTML; - - LLWString mPreeditWString; - LLWString mPreeditOverwrittenWString; - std::vector mPreeditPositions; - std::vector mPreeditStandouts; -}; class LLTextSegment { @@ -482,21 +536,20 @@ public: LLTextSegment( const LLColor4& color, S32 start, S32 end ); LLTextSegment( const LLColor3& color, S32 start, S32 end ); - S32 getStart() { return mStart; } - S32 getEnd() { return mEnd; } + S32 getStart() const { return mStart; } + S32 getEnd() const { return mEnd; } void setEnd( S32 end ) { mEnd = end; } - const LLColor4& getColor() { return mStyle.getColor(); } + const LLColor4& getColor() const { return mStyle.getColor(); } void setColor(const LLColor4 &color) { mStyle.setColor(color); } - const LLStyle& getStyle() { return mStyle; } + const LLStyle& getStyle() const { return mStyle; } void setStyle(const LLStyle &style) { mStyle = style; } void setIsDefault(BOOL b) { mIsDefault = b; } - BOOL getIsDefault() { return mIsDefault; } - + BOOL getIsDefault() const { return mIsDefault; } void setToken( LLKeywordToken* token ) { mToken = token; } - LLKeywordToken* getToken() { return mToken; } - BOOL getToolTip( LLString& msg ); + LLKeywordToken* getToken() const { return mToken; } + BOOL getToolTip( LLString& msg ) const; - void dump(); + void dump() const; struct compare { @@ -514,34 +567,5 @@ private: BOOL mIsDefault; }; -class LLTextCmd -{ -public: - LLTextCmd( S32 pos, BOOL group_with_next ) - : mPos(pos), - mGroupWithNext(group_with_next) - { - } - virtual ~LLTextCmd() {} - virtual BOOL execute(LLTextEditor* editor, S32* delta) = 0; - virtual S32 undo(LLTextEditor* editor) = 0; - virtual S32 redo(LLTextEditor* editor) = 0; - virtual BOOL canExtend(S32 pos); - virtual void blockExtensions(); - virtual BOOL extendAndExecute( LLTextEditor* editor, S32 pos, llwchar c, S32* delta ); - virtual BOOL hasExtCharValue( llwchar value ); - - // Define these here so they can access LLTextEditor through the friend relationship - S32 insert(LLTextEditor* editor, S32 pos, const LLWString &wstr); - S32 remove(LLTextEditor* editor, S32 pos, S32 length); - S32 overwrite(LLTextEditor* editor, S32 pos, llwchar wc); - - BOOL groupWithNext() { return mGroupWithNext; } - -protected: - S32 mPos; - BOOL mGroupWithNext; -}; - #endif // LL_TEXTEDITOR_ diff --git a/linden/indra/llui/llui.cpp b/linden/indra/llui/llui.cpp index f6ce985..5904573 100644 --- a/linden/indra/llui/llui.cpp +++ b/linden/indra/llui/llui.cpp @@ -42,6 +42,7 @@ #include "v2math.h" #include "v4color.h" #include "llgl.h" +#include "llglimmediate.h" #include "llrect.h" #include "llimagegl.h" //#include "llviewerimage.h" @@ -148,26 +149,26 @@ void gl_draw_x(const LLRect& rect, const LLColor4& color) { LLGLSNoTexture no_texture; - glColor4fv( color.mV ); + gGL.color4fv( color.mV ); - glBegin( GL_LINES ); - glVertex2i( rect.mLeft, rect.mTop ); - glVertex2i( rect.mRight, rect.mBottom ); - glVertex2i( rect.mLeft, rect.mBottom ); - glVertex2i( rect.mRight, rect.mTop ); - glEnd(); + gGL.begin( GL_LINES ); + gGL.vertex2i( rect.mLeft, rect.mTop ); + gGL.vertex2i( rect.mRight, rect.mBottom ); + gGL.vertex2i( rect.mLeft, rect.mBottom ); + gGL.vertex2i( rect.mRight, rect.mTop ); + gGL.end(); } void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled) { - glColor4fv(color.mV); + gGL.color4fv(color.mV); gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled); } void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled) { - glPushMatrix(); + gGL.pushMatrix(); left += LLFontGL::sCurOrigin.mX; right += LLFontGL::sCurOrigin.mX; bottom += LLFontGL::sCurOrigin.mY; @@ -179,7 +180,7 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixe llfloor((F32)right * LLUI::sGLScaleFactor.mV[VX]) + pixel_offset, llfloor((F32)bottom * LLUI::sGLScaleFactor.mV[VY]) - pixel_offset, filled); - glPopMatrix(); + gGL.popMatrix(); } @@ -191,48 +192,48 @@ void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled ) // Counterclockwise quad will face the viewer if( filled ) { - glBegin( GL_QUADS ); - glVertex2i(left, top); - glVertex2i(left, bottom); - glVertex2i(right, bottom); - glVertex2i(right, top); - glEnd(); + gGL.begin( GL_QUADS ); + gGL.vertex2i(left, top); + gGL.vertex2i(left, bottom); + gGL.vertex2i(right, bottom); + gGL.vertex2i(right, top); + gGL.end(); } else { if( gGLManager.mATIOffsetVerticalLines ) { // Work around bug in ATI driver: vertical lines are offset by (-1,-1) - glBegin( GL_LINES ); + gGL.begin( GL_LINES ); // Verticals - glVertex2i(left + 1, top); - glVertex2i(left + 1, bottom); + gGL.vertex2i(left + 1, top); + gGL.vertex2i(left + 1, bottom); - glVertex2i(right, bottom); - glVertex2i(right, top); + gGL.vertex2i(right, bottom); + gGL.vertex2i(right, top); // Horizontals top--; right--; - glVertex2i(left, bottom); - glVertex2i(right, bottom); + gGL.vertex2i(left, bottom); + gGL.vertex2i(right, bottom); - glVertex2i(left, top); - glVertex2i(right, top); - glEnd(); + gGL.vertex2i(left, top); + gGL.vertex2i(right, top); + gGL.end(); } else { top--; right--; - glBegin( GL_LINE_STRIP ); - glVertex2i(left, top); - glVertex2i(left, bottom); - glVertex2i(right, bottom); - glVertex2i(right, top); - glVertex2i(left, top); - glEnd(); + gGL.begin( GL_LINE_STRIP ); + gGL.vertex2i(left, top); + gGL.vertex2i(left, bottom); + gGL.vertex2i(right, bottom); + gGL.vertex2i(right, top); + gGL.vertex2i(left, top); + gGL.end(); } } stop_glerror(); @@ -240,14 +241,14 @@ void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled ) void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled ) { - glColor4fv( color.mV ); + gGL.color4fv( color.mV ); gl_rect_2d( left, top, right, bottom, filled ); } void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled ) { - glColor4fv( color.mV ); + gGL.color4fv( color.mV ); gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled ); } @@ -267,52 +268,52 @@ void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &st LLColor4 end_color = start_color; end_color.mV[VALPHA] = 0.f; - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); // Right edge, CCW faces screen - glColor4fv(start_color.mV); - glVertex2i(right, top-lines); - glVertex2i(right, bottom); - glColor4fv(end_color.mV); - glVertex2i(right+lines, bottom); - glVertex2i(right+lines, top-lines); + gGL.color4fv(start_color.mV); + gGL.vertex2i(right, top-lines); + gGL.vertex2i(right, bottom); + gGL.color4fv(end_color.mV); + gGL.vertex2i(right+lines, bottom); + gGL.vertex2i(right+lines, top-lines); // Bottom edge, CCW faces screen - glColor4fv(start_color.mV); - glVertex2i(right, bottom); - glVertex2i(left+lines, bottom); - glColor4fv(end_color.mV); - glVertex2i(left+lines, bottom-lines); - glVertex2i(right, bottom-lines); + gGL.color4fv(start_color.mV); + gGL.vertex2i(right, bottom); + gGL.vertex2i(left+lines, bottom); + gGL.color4fv(end_color.mV); + gGL.vertex2i(left+lines, bottom-lines); + gGL.vertex2i(right, bottom-lines); // bottom left Corner - glColor4fv(start_color.mV); - glVertex2i(left+lines, bottom); - glColor4fv(end_color.mV); - glVertex2i(left, bottom); + gGL.color4fv(start_color.mV); + gGL.vertex2i(left+lines, bottom); + gGL.color4fv(end_color.mV); + gGL.vertex2i(left, bottom); // make the bottom left corner not sharp - glVertex2i(left+1, bottom-lines+1); - glVertex2i(left+lines, bottom-lines); + gGL.vertex2i(left+1, bottom-lines+1); + gGL.vertex2i(left+lines, bottom-lines); // bottom right corner - glColor4fv(start_color.mV); - glVertex2i(right, bottom); - glColor4fv(end_color.mV); - glVertex2i(right, bottom-lines); + gGL.color4fv(start_color.mV); + gGL.vertex2i(right, bottom); + gGL.color4fv(end_color.mV); + gGL.vertex2i(right, bottom-lines); // make the rightmost corner not sharp - glVertex2i(right+lines-1, bottom-lines+1); - glVertex2i(right+lines, bottom); + gGL.vertex2i(right+lines-1, bottom-lines+1); + gGL.vertex2i(right+lines, bottom); // top right corner - glColor4fv(start_color.mV); - glVertex2i( right, top-lines ); - glColor4fv(end_color.mV); - glVertex2i( right+lines, top-lines ); + gGL.color4fv(start_color.mV); + gGL.vertex2i( right, top-lines ); + gGL.color4fv(end_color.mV); + gGL.vertex2i( right+lines, top-lines ); // make the corner not sharp - glVertex2i( right+lines-1, top-1 ); - glVertex2i( right, top ); + gGL.vertex2i( right+lines-1, top-1 ); + gGL.vertex2i( right, top ); - glEnd(); + gGL.end(); stop_glerror(); } @@ -329,10 +330,10 @@ void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 ) LLGLSNoTexture no_texture; - glBegin(GL_LINES); - glVertex2i(x1, y1); - glVertex2i(x2, y2); - glEnd(); + gGL.begin(GL_LINES); + gGL.vertex2i(x1, y1); + gGL.vertex2i(x2, y2); + gGL.end(); } void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color ) @@ -348,32 +349,32 @@ void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color ) LLGLSNoTexture no_texture; - glColor4fv( color.mV ); + gGL.color4fv( color.mV ); - glBegin(GL_LINES); - glVertex2i(x1, y1); - glVertex2i(x2, y2); - glEnd(); + gGL.begin(GL_LINES); + gGL.vertex2i(x1, y1); + gGL.vertex2i(x2, y2); + gGL.end(); } void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled) { LLGLSNoTexture no_texture; - glColor4fv(color.mV); + gGL.color4fv(color.mV); if (filled) { - glBegin(GL_TRIANGLES); + gGL.begin(GL_TRIANGLES); } else { - glBegin(GL_LINE_LOOP); + gGL.begin(GL_LINE_LOOP); } - glVertex2i(x1, y1); - glVertex2i(x2, y2); - glVertex2i(x3, y3); - glEnd(); + gGL.vertex2i(x1, y1); + gGL.vertex2i(x2, y2); + gGL.vertex2i(x3, y3); + gGL.end(); } void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac) @@ -382,31 +383,31 @@ void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max length = llmin((S32)(max_frac*(right - left)), length); length = llmin((S32)(max_frac*(top - bottom)), length); - glBegin(GL_LINES); - glVertex2i(left, top); - glVertex2i(left + length, top); + gGL.begin(GL_LINES); + gGL.vertex2i(left, top); + gGL.vertex2i(left + length, top); - glVertex2i(left, top); - glVertex2i(left, top - length); + gGL.vertex2i(left, top); + gGL.vertex2i(left, top - length); - glVertex2i(left, bottom); - glVertex2i(left + length, bottom); + gGL.vertex2i(left, bottom); + gGL.vertex2i(left + length, bottom); - glVertex2i(left, bottom); - glVertex2i(left, bottom + length); + gGL.vertex2i(left, bottom); + gGL.vertex2i(left, bottom + length); - glVertex2i(right, top); - glVertex2i(right - length, top); + gGL.vertex2i(right, top); + gGL.vertex2i(right - length, top); - glVertex2i(right, top); - glVertex2i(right, top - length); + gGL.vertex2i(right, top); + gGL.vertex2i(right, top - length); - glVertex2i(right, bottom); - glVertex2i(right - length, bottom); + gGL.vertex2i(right, bottom); + gGL.vertex2i(right - length, bottom); - glVertex2i(right, bottom); - glVertex2i(right, bottom + length); - glEnd(); + gGL.vertex2i(right, bottom); + gGL.vertex2i(right, bottom + length); + gGL.end(); } @@ -499,136 +500,136 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLIma glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA); } - glPushMatrix(); + gGL.pushMatrix(); { - glTranslatef((F32)x, (F32)y, 0.f); + gGL.translatef((F32)x, (F32)y, 0.f); image->bind(); - glColor4fv(color.mV); + gGL.color4fv(color.mV); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { // draw bottom left - glTexCoord2d(uv_rect.mLeft, uv_rect.mBottom); - glVertex2i(0, 0); + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); + gGL.vertex2i(0, 0); - glTexCoord2f(clipped_scale_rect.mLeft, uv_rect.mBottom); - glVertex2i(draw_scale_rect.mLeft, 0); + gGL.texCoord2f(clipped_scale_rect.mLeft, uv_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mLeft, 0); - glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); - glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); + gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); - glTexCoord2d(uv_rect.mLeft, clipped_scale_rect.mBottom); - glVertex2i(0, draw_scale_rect.mBottom); + gGL.texCoord2f(uv_rect.mLeft, clipped_scale_rect.mBottom); + gGL.vertex2i(0, draw_scale_rect.mBottom); // draw bottom middle - glTexCoord2f(clipped_scale_rect.mLeft, uv_rect.mBottom); - glVertex2i(draw_scale_rect.mLeft, 0); + gGL.texCoord2f(clipped_scale_rect.mLeft, uv_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mLeft, 0); - glTexCoord2d(clipped_scale_rect.mRight, uv_rect.mBottom); - glVertex2i(draw_scale_rect.mRight, 0); + gGL.texCoord2f(clipped_scale_rect.mRight, uv_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mRight, 0); - glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); - glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); + gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); - glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); - glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); + gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); // draw bottom right - glTexCoord2d(clipped_scale_rect.mRight, uv_rect.mBottom); - glVertex2i(draw_scale_rect.mRight, 0); + gGL.texCoord2f(clipped_scale_rect.mRight, uv_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mRight, 0); - glTexCoord2d(uv_rect.mRight, uv_rect.mBottom); - glVertex2i(width, 0); + gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); + gGL.vertex2i(width, 0); - glTexCoord2d(uv_rect.mRight, clipped_scale_rect.mBottom); - glVertex2i(width, draw_scale_rect.mBottom); + gGL.texCoord2f(uv_rect.mRight, clipped_scale_rect.mBottom); + gGL.vertex2i(width, draw_scale_rect.mBottom); - glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); - glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); + gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); // draw left - glTexCoord2d(uv_rect.mLeft, clipped_scale_rect.mBottom); - glVertex2i(0, draw_scale_rect.mBottom); + gGL.texCoord2f(uv_rect.mLeft, clipped_scale_rect.mBottom); + gGL.vertex2i(0, draw_scale_rect.mBottom); - glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); - glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); + gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); - glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); - glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); + gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); - glTexCoord2d(uv_rect.mLeft, clipped_scale_rect.mTop); - glVertex2i(0, draw_scale_rect.mTop); + gGL.texCoord2f(uv_rect.mLeft, clipped_scale_rect.mTop); + gGL.vertex2i(0, draw_scale_rect.mTop); // draw middle - glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); - glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); + gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mBottom); - glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); - glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); + gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); - glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mTop); - glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); + gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mTop); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); - glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); - glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); + gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); // draw right - glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); - glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); + gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mBottom); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mBottom); - glTexCoord2d(uv_rect.mRight, clipped_scale_rect.mBottom); - glVertex2i(width, draw_scale_rect.mBottom); + gGL.texCoord2f(uv_rect.mRight, clipped_scale_rect.mBottom); + gGL.vertex2i(width, draw_scale_rect.mBottom); - glTexCoord2d(uv_rect.mRight, clipped_scale_rect.mTop); - glVertex2i(width, draw_scale_rect.mTop); + gGL.texCoord2f(uv_rect.mRight, clipped_scale_rect.mTop); + gGL.vertex2i(width, draw_scale_rect.mTop); - glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mTop); - glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); + gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mTop); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); // draw top left - glTexCoord2d(uv_rect.mLeft, clipped_scale_rect.mTop); - glVertex2i(0, draw_scale_rect.mTop); + gGL.texCoord2f(uv_rect.mLeft, clipped_scale_rect.mTop); + gGL.vertex2i(0, draw_scale_rect.mTop); - glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); - glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); + gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); - glTexCoord2f(clipped_scale_rect.mLeft, uv_rect.mTop); - glVertex2i(draw_scale_rect.mLeft, height); + gGL.texCoord2f(clipped_scale_rect.mLeft, uv_rect.mTop); + gGL.vertex2i(draw_scale_rect.mLeft, height); - glTexCoord2d(uv_rect.mLeft, uv_rect.mTop); - glVertex2i(0, height); + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); + gGL.vertex2i(0, height); // draw top middle - glTexCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); - glVertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); + gGL.texCoord2f(clipped_scale_rect.mLeft, clipped_scale_rect.mTop); + gGL.vertex2i(draw_scale_rect.mLeft, draw_scale_rect.mTop); - glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mTop); - glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); + gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mTop); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); - glTexCoord2d(clipped_scale_rect.mRight, uv_rect.mTop); - glVertex2i(draw_scale_rect.mRight, height); + gGL.texCoord2f(clipped_scale_rect.mRight, uv_rect.mTop); + gGL.vertex2i(draw_scale_rect.mRight, height); - glTexCoord2f(clipped_scale_rect.mLeft, uv_rect.mTop); - glVertex2i(draw_scale_rect.mLeft, height); + gGL.texCoord2f(clipped_scale_rect.mLeft, uv_rect.mTop); + gGL.vertex2i(draw_scale_rect.mLeft, height); // draw top right - glTexCoord2d(clipped_scale_rect.mRight, clipped_scale_rect.mTop); - glVertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); + gGL.texCoord2f(clipped_scale_rect.mRight, clipped_scale_rect.mTop); + gGL.vertex2i(draw_scale_rect.mRight, draw_scale_rect.mTop); - glTexCoord2d(uv_rect.mRight, clipped_scale_rect.mTop); - glVertex2i(width, draw_scale_rect.mTop); + gGL.texCoord2f(uv_rect.mRight, clipped_scale_rect.mTop); + gGL.vertex2i(width, draw_scale_rect.mTop); - glTexCoord2d(uv_rect.mRight, uv_rect.mTop); - glVertex2i(width, height); + gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); + gGL.vertex2i(width, height); - glTexCoord2d(clipped_scale_rect.mRight, uv_rect.mTop); - glVertex2i(draw_scale_rect.mRight, height); + gGL.texCoord2f(clipped_scale_rect.mRight, uv_rect.mTop); + gGL.vertex2i(draw_scale_rect.mRight, height); } - glEnd(); + gGL.end(); } - glPopMatrix(); + gGL.popMatrix(); if (solid_color) { @@ -651,39 +652,39 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre LLGLSUIDefault gls_ui; - glPushMatrix(); + gGL.pushMatrix(); { - glTranslatef((F32)x, (F32)y, 0.f); + gGL.translatef((F32)x, (F32)y, 0.f); if( degrees ) { F32 offset_x = F32(width/2); F32 offset_y = F32(height/2); - glTranslatef( offset_x, offset_y, 0.f); + gGL.translatef( offset_x, offset_y, 0.f); glRotatef( degrees, 0.f, 0.f, 1.f ); - glTranslatef( -offset_x, -offset_y, 0.f ); + gGL.translatef( -offset_x, -offset_y, 0.f ); } image->bind(); - glColor4fv(color.mV); + gGL.color4fv(color.mV); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { - glTexCoord2f(uv_rect.mRight, uv_rect.mTop); - glVertex2i(width, height ); + gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); + gGL.vertex2i(width, height ); - glTexCoord2f(uv_rect.mLeft, uv_rect.mTop); - glVertex2i(0, height ); + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); + gGL.vertex2i(0, height ); - glTexCoord2f(uv_rect.mLeft, uv_rect.mBottom); - glVertex2i(0, 0); + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); + gGL.vertex2i(0, 0); - glTexCoord2f(uv_rect.mRight, uv_rect.mBottom); - glVertex2i(width, 0); + gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); + gGL.vertex2i(width, 0); } - glEnd(); + gGL.end(); } - glPopMatrix(); + gGL.popMatrix(); } @@ -697,31 +698,31 @@ void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageG LLGLSUIDefault gls_ui; - glPushMatrix(); + gGL.pushMatrix(); { - glTranslatef((F32)x, (F32)y, 0.f); + gGL.translatef((F32)x, (F32)y, 0.f); image->bind(); - glColor4fv(color.mV); + gGL.color4fv(color.mV); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { - glTexCoord2f(uv_rect.mRight, uv_rect.mBottom); - glVertex2i(width, height ); + gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); + gGL.vertex2i(width, height ); - glTexCoord2f(uv_rect.mLeft, uv_rect.mBottom); - glVertex2i(0, height ); + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); + gGL.vertex2i(0, height ); - glTexCoord2f(uv_rect.mLeft, uv_rect.mTop); - glVertex2i(0, 0); + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); + gGL.vertex2i(0, 0); - glTexCoord2f(uv_rect.mRight, uv_rect.mTop); - glVertex2i(width, 0); + gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); + gGL.vertex2i(width, 0); } - glEnd(); + gGL.end(); } - glPopMatrix(); + gGL.popMatrix(); } @@ -734,16 +735,18 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL // Stippled line LLGLEnable stipple(GL_LINE_STIPPLE); - glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]); + gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]); + + gGL.flush(); glLineWidth(2.5f); glLineStipple(2, 0x3333 << shift); - glBegin(GL_LINES); + gGL.begin(GL_LINES); { - glVertex3fv( start.mV ); - glVertex3fv( end.mV ); + gGL.vertex3fv( start.mV ); + gGL.vertex3fv( end.mV ); } - glEnd(); + gGL.end(); LLUI::setLineWidth(1.f); } @@ -751,16 +754,16 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom) { - glColor4fv( LLColor4::white.mV ); + gGL.color4fv( LLColor4::white.mV ); glLogicOp( GL_XOR ); stop_glerror(); - glBegin(GL_QUADS); - glVertex2i(left, top); - glVertex2i(left, bottom); - glVertex2i(right, bottom); - glVertex2i(right, top); - glEnd(); + gGL.begin(GL_QUADS); + gGL.vertex2i(left, top); + gGL.vertex2i(left, bottom); + gGL.vertex2i(right, bottom); + gGL.vertex2i(right, top); + gGL.end(); glLogicOp( GL_COPY ); stop_glerror(); @@ -774,9 +777,9 @@ void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F end_angle += F_TWO_PI; } - glPushMatrix(); + gGL.pushMatrix(); { - glTranslatef(center_x, center_y, 0.f); + gGL.translatef(center_x, center_y, 0.f); // Inexact, but reasonably fast. F32 delta = (end_angle - start_angle) / steps; @@ -787,35 +790,35 @@ void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F if (filled) { - glBegin(GL_TRIANGLE_FAN); - glVertex2f(0.f, 0.f); + gGL.begin(GL_TRIANGLE_FAN); + gGL.vertex2f(0.f, 0.f); // make sure circle is complete steps += 1; } else { - glBegin(GL_LINE_STRIP); + gGL.begin(GL_LINE_STRIP); } while( steps-- ) { // Successive rotations - glVertex2f( x, y ); + gGL.vertex2f( x, y ); F32 x_new = x * cos_delta - y * sin_delta; y = x * sin_delta + y * cos_delta; x = x_new; } - glEnd(); + gGL.end(); } - glPopMatrix(); + gGL.popMatrix(); } void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled) { - glPushMatrix(); + gGL.pushMatrix(); { LLGLSNoTexture gls_no_texture; - glTranslatef(center_x, center_y, 0.f); + gGL.translatef(center_x, center_y, 0.f); // Inexact, but reasonably fast. F32 delta = F_TWO_PI / steps; @@ -826,27 +829,27 @@ void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled if (filled) { - glBegin(GL_TRIANGLE_FAN); - glVertex2f(0.f, 0.f); + gGL.begin(GL_TRIANGLE_FAN); + gGL.vertex2f(0.f, 0.f); // make sure circle is complete steps += 1; } else { - glBegin(GL_LINE_LOOP); + gGL.begin(GL_LINE_LOOP); } while( steps-- ) { // Successive rotations - glVertex2f( x, y ); + gGL.vertex2f( x, y ); F32 x_new = x * cos_delta - y * sin_delta; y = x * sin_delta + y * cos_delta; x = x_new; } - glEnd(); + gGL.end(); } - glPopMatrix(); + gGL.popMatrix(); } // Renders a ring with sides (tube shape) @@ -855,40 +858,40 @@ void gl_deep_circle( F32 radius, F32 depth, S32 steps ) F32 x = radius; F32 y = 0.f; F32 angle_delta = F_TWO_PI / (F32)steps; - glBegin( GL_TRIANGLE_STRIP ); + gGL.begin( GL_TRIANGLE_STRIP ); { S32 step = steps + 1; // An extra step to close the circle. while( step-- ) { - glVertex3f( x, y, depth ); - glVertex3f( x, y, 0.f ); + gGL.vertex3f( x, y, depth ); + gGL.vertex3f( x, y, 0.f ); F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta); y = x * sinf(angle_delta) + y * cosf(angle_delta); x = x_new; } } - glEnd(); + gGL.end(); } void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center ) { - glPushMatrix(); + gGL.pushMatrix(); { - glTranslatef(0.f, 0.f, -width / 2); + gGL.translatef(0.f, 0.f, -width / 2); if( render_center ) { - glColor4fv(center_color.mV); + gGL.color4fv(center_color.mV); gl_deep_circle( radius, width, steps ); } else { gl_washer_2d(radius, radius - width, steps, side_color, side_color); - glTranslatef(0.f, 0.f, width); + gGL.translatef(0.f, 0.f, width); gl_washer_2d(radius - width, radius, steps, side_color, side_color); } } - glPopMatrix(); + gGL.popMatrix(); } // Draw gray and white checkerboard with black border @@ -913,15 +916,17 @@ void gl_rect_2d_checkerboard(const LLRect& rect) LLGLSNoTexture gls_no_texture; // ...white squares - glColor3f( 1.f, 1.f, 1.f ); + gGL.color3f( 1.f, 1.f, 1.f ); gl_rect_2d(rect); // ...gray squares - glColor3f( .7f, .7f, .7f ); + gGL.color3f( .7f, .7f, .7f ); + gGL.flush(); glPolygonStipple( checkerboard ); LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE); gl_rect_2d(rect); + gGL.flush(); } @@ -940,15 +945,15 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& LLGLSNoTexture gls_no_texture; - glBegin( GL_TRIANGLE_STRIP ); + gGL.begin( GL_TRIANGLE_STRIP ); { steps += 1; // An extra step to close the circle. while( steps-- ) { - glColor4fv(outer_color.mV); - glVertex2f( x1, y1 ); - glColor4fv(inner_color.mV); - glVertex2f( x2, y2 ); + gGL.color4fv(outer_color.mV); + gGL.vertex2f( x1, y1 ); + gGL.color4fv(inner_color.mV); + gGL.vertex2f( x2, y2 ); F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; y1 = x1 * SIN_DELTA + y1 * COS_DELTA; @@ -959,7 +964,7 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& x2 = x2_new; } } - glEnd(); + gGL.end(); } // Draws the area between two concentric circles, like @@ -976,15 +981,15 @@ void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 y2 = inner_radius * sin( start_radians ); LLGLSNoTexture gls_no_texture; - glBegin( GL_TRIANGLE_STRIP ); + gGL.begin( GL_TRIANGLE_STRIP ); { steps += 1; // An extra step to close the circle. while( steps-- ) { - glColor4fv(outer_color.mV); - glVertex2f( x1, y1 ); - glColor4fv(inner_color.mV); - glVertex2f( x2, y2 ); + gGL.color4fv(outer_color.mV); + gGL.vertex2f( x1, y1 ); + gGL.color4fv(inner_color.mV); + gGL.vertex2f( x2, y2 ); F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; y1 = x1 * SIN_DELTA + y1 * COS_DELTA; @@ -995,7 +1000,7 @@ void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, x2 = x2_new; } } - glEnd(); + gGL.end(); } // Draws spokes around a circle. @@ -1013,14 +1018,14 @@ void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LL LLGLSNoTexture gls_no_texture; - glBegin( GL_LINES ); + gGL.begin( GL_LINES ); { while( count-- ) { - glColor4fv(outer_color.mV); - glVertex2f( x1, y1 ); - glColor4fv(inner_color.mV); - glVertex2f( x2, y2 ); + gGL.color4fv(outer_color.mV); + gGL.vertex2f( x1, y1 ); + gGL.color4fv(inner_color.mV); + gGL.vertex2f( x2, y2 ); F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA; y1 = x1 * SIN_DELTA + y1 * COS_DELTA; @@ -1031,36 +1036,36 @@ void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LL x2 = x2_new; } } - glEnd(); + gGL.end(); } void gl_rect_2d_simple_tex( S32 width, S32 height ) { - glBegin( GL_QUADS ); + gGL.begin( GL_QUADS ); - glTexCoord2f(1.f, 1.f); - glVertex2i(width, height); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(width, height); - glTexCoord2f(0.f, 1.f); - glVertex2i(0, height); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(0, height); - glTexCoord2f(0.f, 0.f); - glVertex2i(0, 0); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(0, 0); - glTexCoord2f(1.f, 0.f); - glVertex2i(width, 0); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(width, 0); - glEnd(); + gGL.end(); } void gl_rect_2d_simple( S32 width, S32 height ) { - glBegin( GL_QUADS ); - glVertex2i(width, height); - glVertex2i(0, height); - glVertex2i(0, 0); - glVertex2i(width, 0); - glEnd(); + gGL.begin( GL_QUADS ); + gGL.vertex2i(width, height); + gGL.vertex2i(0, height); + gGL.vertex2i(0, 0); + gGL.vertex2i(width, 0); + gGL.end(); } void gl_segmented_rect_2d_tex(const S32 left, @@ -1075,9 +1080,9 @@ void gl_segmented_rect_2d_tex(const S32 left, S32 width = llabs(right - left); S32 height = llabs(top - bottom); - glPushMatrix(); + gGL.pushMatrix(); - glTranslatef((F32)left, (F32)bottom, 0.f); + gGL.translatef((F32)left, (F32)bottom, 0.f); LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height); if (border_uv_scale.mV[VX] > 0.5f) @@ -1097,128 +1102,128 @@ void gl_segmented_rect_2d_tex(const S32 left, LLVector2 width_vec((F32)width, 0.f); LLVector2 height_vec(0.f, (F32)height); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { // draw bottom left - glTexCoord2f(0.f, 0.f); - glVertex2f(0.f, 0.f); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2f(0.f, 0.f); - glTexCoord2f(border_uv_scale.mV[VX], 0.f); - glVertex2fv(border_width_left.mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv(border_width_left.mV); - glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - glVertex2fv((border_width_left + border_height_bottom).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + border_height_bottom).mV); - glTexCoord2f(0.f, border_uv_scale.mV[VY]); - glVertex2fv(border_height_bottom.mV); + gGL.texCoord2f(0.f, border_uv_scale.mV[VY]); + gGL.vertex2fv(border_height_bottom.mV); // draw bottom middle - glTexCoord2f(border_uv_scale.mV[VX], 0.f); - glVertex2fv(border_width_left.mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv(border_width_left.mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], 0.f); - glVertex2fv((width_vec - border_width_right).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv((width_vec - border_width_right).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - glVertex2fv((width_vec - border_width_right + border_height_bottom).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); - glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - glVertex2fv((border_width_left + border_height_bottom).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + border_height_bottom).mV); // draw bottom right - glTexCoord2f(1.f - border_uv_scale.mV[VX], 0.f); - glVertex2fv((width_vec - border_width_right).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv((width_vec - border_width_right).mV); - glTexCoord2f(1.f, 0.f); - glVertex2fv(width_vec.mV); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2fv(width_vec.mV); - glTexCoord2f(1.f, border_uv_scale.mV[VY]); - glVertex2fv((width_vec + border_height_bottom).mV); + gGL.texCoord2f(1.f, border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec + border_height_bottom).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - glVertex2fv((width_vec - border_width_right + border_height_bottom).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); // draw left - glTexCoord2f(0.f, border_uv_scale.mV[VY]); - glVertex2fv(border_height_bottom.mV); + gGL.texCoord2f(0.f, border_uv_scale.mV[VY]); + gGL.vertex2fv(border_height_bottom.mV); - glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - glVertex2fv((border_width_left + border_height_bottom).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + border_height_bottom).mV); - glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - glVertex2fv((border_width_left + height_vec - border_height_top).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); - glTexCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); - glVertex2fv((height_vec - border_height_top).mV); + gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((height_vec - border_height_top).mV); // draw middle - glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - glVertex2fv((border_width_left + border_height_bottom).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + border_height_bottom).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - glVertex2fv((width_vec - border_width_right + border_height_bottom).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - glVertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); - glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - glVertex2fv((border_width_left + height_vec - border_height_top).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); // draw right - glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - glVertex2fv((width_vec - border_width_right + border_height_bottom).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); - glTexCoord2f(1.f, border_uv_scale.mV[VY]); - glVertex2fv((width_vec + border_height_bottom).mV); + gGL.texCoord2f(1.f, border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec + border_height_bottom).mV); - glTexCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); - glVertex2fv((width_vec + height_vec - border_height_top).mV); + gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec + height_vec - border_height_top).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - glVertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); // draw top left - glTexCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); - glVertex2fv((height_vec - border_height_top).mV); + gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((height_vec - border_height_top).mV); - glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - glVertex2fv((border_width_left + height_vec - border_height_top).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); - glTexCoord2f(border_uv_scale.mV[VX], 1.f); - glVertex2fv((border_width_left + height_vec).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((border_width_left + height_vec).mV); - glTexCoord2f(0.f, 1.f); - glVertex2fv((height_vec).mV); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2fv((height_vec).mV); // draw top middle - glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - glVertex2fv((border_width_left + height_vec - border_height_top).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - glVertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f); - glVertex2fv((width_vec - border_width_right + height_vec).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((width_vec - border_width_right + height_vec).mV); - glTexCoord2f(border_uv_scale.mV[VX], 1.f); - glVertex2fv((border_width_left + height_vec).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((border_width_left + height_vec).mV); // draw top right - glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - glVertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); - glTexCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); - glVertex2fv((width_vec + height_vec - border_height_top).mV); + gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec + height_vec - border_height_top).mV); - glTexCoord2f(1.f, 1.f); - glVertex2fv((width_vec + height_vec).mV); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2fv((width_vec + height_vec).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f); - glVertex2fv((width_vec - border_width_right + height_vec).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((width_vec - border_width_right + height_vec).mV); } - glEnd(); + gGL.end(); - glPopMatrix(); + gGL.popMatrix(); } void gl_segmented_rect_2d_fragment_tex(const S32 left, @@ -1235,9 +1240,9 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left, S32 width = llabs(right - left); S32 height = llabs(top - bottom); - glPushMatrix(); + gGL.pushMatrix(); - glTranslatef((F32)left, (F32)bottom, 0.f); + gGL.translatef((F32)left, (F32)bottom, 0.f); LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height); if (border_uv_scale.mV[VX] > 0.5f) @@ -1265,7 +1270,7 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left, LLVector2 x_min; LLVector2 x_max; - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { if (start_fragment < middle_start) { @@ -1275,43 +1280,43 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left, x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left; // draw bottom left - glTexCoord2f(u_min, 0.f); - glVertex2fv(x_min.mV); + gGL.texCoord2f(u_min, 0.f); + gGL.vertex2fv(x_min.mV); - glTexCoord2f(border_uv_scale.mV[VX], 0.f); - glVertex2fv(x_max.mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv(x_max.mV); - glTexCoord2f(u_max, border_uv_scale.mV[VY]); - glVertex2fv((x_max + border_height_bottom).mV); + gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); - glTexCoord2f(u_min, border_uv_scale.mV[VY]); - glVertex2fv((x_min + border_height_bottom).mV); + gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); // draw left - glTexCoord2f(u_min, border_uv_scale.mV[VY]); - glVertex2fv((x_min + border_height_bottom).mV); + gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); - glTexCoord2f(u_max, border_uv_scale.mV[VY]); - glVertex2fv((x_max + border_height_bottom).mV); + gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); - glTexCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); - glVertex2fv((x_max + height_vec - border_height_top).mV); + gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - glTexCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); - glVertex2fv((x_min + height_vec - border_height_top).mV); + gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); // draw top left - glTexCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); - glVertex2fv((x_min + height_vec - border_height_top).mV); + gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - glTexCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); - glVertex2fv((x_max + height_vec - border_height_top).mV); + gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - glTexCoord2f(u_max, 1.f); - glVertex2fv((x_max + height_vec).mV); + gGL.texCoord2f(u_max, 1.f); + gGL.vertex2fv((x_max + height_vec).mV); - glTexCoord2f(u_min, 1.f); - glVertex2fv((x_min + height_vec).mV); + gGL.texCoord2f(u_min, 1.f); + gGL.vertex2fv((x_min + height_vec).mV); } if (end_fragment > middle_start || start_fragment < middle_end) @@ -1320,43 +1325,43 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left, x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec; // draw bottom middle - glTexCoord2f(border_uv_scale.mV[VX], 0.f); - glVertex2fv(x_min.mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv(x_min.mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], 0.f); - glVertex2fv((x_max).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv((x_max).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - glVertex2fv((x_max + border_height_bottom).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); - glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - glVertex2fv((x_min + border_height_bottom).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); // draw middle - glTexCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - glVertex2fv((x_min + border_height_bottom).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); - glVertex2fv((x_max + border_height_bottom).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - glVertex2fv((x_max + height_vec - border_height_top).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - glVertex2fv((x_min + height_vec - border_height_top).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); // draw top middle - glTexCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - glVertex2fv((x_min + height_vec - border_height_top).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); - glVertex2fv((x_max + height_vec - border_height_top).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - glTexCoord2f(1.f - border_uv_scale.mV[VX], 1.f); - glVertex2fv((x_max + height_vec).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((x_max + height_vec).mV); - glTexCoord2f(border_uv_scale.mV[VX], 1.f); - glVertex2fv((x_min + height_vec).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((x_min + height_vec).mV); } if (end_fragment > middle_end) @@ -1367,48 +1372,48 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left, x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right); // draw bottom right - glTexCoord2f(u_min, 0.f); - glVertex2fv((x_min).mV); + gGL.texCoord2f(u_min, 0.f); + gGL.vertex2fv((x_min).mV); - glTexCoord2f(u_max, 0.f); - glVertex2fv(x_max.mV); + gGL.texCoord2f(u_max, 0.f); + gGL.vertex2fv(x_max.mV); - glTexCoord2f(u_max, border_uv_scale.mV[VY]); - glVertex2fv((x_max + border_height_bottom).mV); + gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); - glTexCoord2f(u_min, border_uv_scale.mV[VY]); - glVertex2fv((x_min + border_height_bottom).mV); + gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); // draw right - glTexCoord2f(u_min, border_uv_scale.mV[VY]); - glVertex2fv((x_min + border_height_bottom).mV); + gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); - glTexCoord2f(u_max, border_uv_scale.mV[VY]); - glVertex2fv((x_max + border_height_bottom).mV); + gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); - glTexCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); - glVertex2fv((x_max + height_vec - border_height_top).mV); + gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - glTexCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); - glVertex2fv((x_min + height_vec - border_height_top).mV); + gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); // draw top right - glTexCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); - glVertex2fv((x_min + height_vec - border_height_top).mV); + gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); - glTexCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); - glVertex2fv((x_max + height_vec - border_height_top).mV); + gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); - glTexCoord2f(u_max, 1.f); - glVertex2fv((x_max + height_vec).mV); + gGL.texCoord2f(u_max, 1.f); + gGL.vertex2fv((x_max + height_vec).mV); - glTexCoord2f(u_min, 1.f); - glVertex2fv((x_min + height_vec).mV); + gGL.texCoord2f(u_min, 1.f); + gGL.vertex2fv((x_min + height_vec).mV); } } - glEnd(); + gGL.end(); - glPopMatrix(); + gGL.popMatrix(); } void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, @@ -1421,126 +1426,128 @@ void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& bo LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero; LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero; - glBegin(GL_QUADS); + + gGL.begin(GL_QUADS); { // draw bottom left - glTexCoord2f(0.f, 0.f); - glVertex3f(0.f, 0.f, 0.f); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex3f(0.f, 0.f, 0.f); - glTexCoord2f(border_scale.mV[VX], 0.f); - glVertex3fv(left_border_width.mV); + gGL.texCoord2f(border_scale.mV[VX], 0.f); + gGL.vertex3fv(left_border_width.mV); - glTexCoord2f(border_scale.mV[VX], border_scale.mV[VY]); - glVertex3fv((left_border_width + bottom_border_height).mV); + gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + bottom_border_height).mV); - glTexCoord2f(0.f, border_scale.mV[VY]); - glVertex3fv(bottom_border_height.mV); + gGL.texCoord2f(0.f, border_scale.mV[VY]); + gGL.vertex3fv(bottom_border_height.mV); // draw bottom middle - glTexCoord2f(border_scale.mV[VX], 0.f); - glVertex3fv(left_border_width.mV); + gGL.texCoord2f(border_scale.mV[VX], 0.f); + gGL.vertex3fv(left_border_width.mV); - glTexCoord2f(1.f - border_scale.mV[VX], 0.f); - glVertex3fv((width_vec - right_border_width).mV); + gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f); + gGL.vertex3fv((width_vec - right_border_width).mV); - glTexCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); - glVertex3fv((width_vec - right_border_width + bottom_border_height).mV); + gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); - glTexCoord2f(border_scale.mV[VX], border_scale.mV[VY]); - glVertex3fv((left_border_width + bottom_border_height).mV); + gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + bottom_border_height).mV); // draw bottom right - glTexCoord2f(1.f - border_scale.mV[VX], 0.f); - glVertex3fv((width_vec - right_border_width).mV); + gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f); + gGL.vertex3fv((width_vec - right_border_width).mV); - glTexCoord2f(1.f, 0.f); - glVertex3fv(width_vec.mV); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3fv(width_vec.mV); - glTexCoord2f(1.f, border_scale.mV[VY]); - glVertex3fv((width_vec + bottom_border_height).mV); + gGL.texCoord2f(1.f, border_scale.mV[VY]); + gGL.vertex3fv((width_vec + bottom_border_height).mV); - glTexCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); - glVertex3fv((width_vec - right_border_width + bottom_border_height).mV); + gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); // draw left - glTexCoord2f(0.f, border_scale.mV[VY]); - glVertex3fv(bottom_border_height.mV); + gGL.texCoord2f(0.f, border_scale.mV[VY]); + gGL.vertex3fv(bottom_border_height.mV); - glTexCoord2f(border_scale.mV[VX], border_scale.mV[VY]); - glVertex3fv((left_border_width + bottom_border_height).mV); + gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + bottom_border_height).mV); - glTexCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); - glVertex3fv((left_border_width + height_vec - top_border_height).mV); + gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); - glTexCoord2f(0.f, 1.f - border_scale.mV[VY]); - glVertex3fv((height_vec - top_border_height).mV); + gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]); + gGL.vertex3fv((height_vec - top_border_height).mV); // draw middle - glTexCoord2f(border_scale.mV[VX], border_scale.mV[VY]); - glVertex3fv((left_border_width + bottom_border_height).mV); + gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + bottom_border_height).mV); - glTexCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); - glVertex3fv((width_vec - right_border_width + bottom_border_height).mV); + gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); - glTexCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); - glVertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); + gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); - glTexCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); - glVertex3fv((left_border_width + height_vec - top_border_height).mV); + gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); // draw right - glTexCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); - glVertex3fv((width_vec - right_border_width + bottom_border_height).mV); + gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV); - glTexCoord2f(1.f, border_scale.mV[VY]); - glVertex3fv((width_vec + bottom_border_height).mV); + gGL.texCoord2f(1.f, border_scale.mV[VY]); + gGL.vertex3fv((width_vec + bottom_border_height).mV); - glTexCoord2f(1.f, 1.f - border_scale.mV[VY]); - glVertex3fv((width_vec + height_vec - top_border_height).mV); + gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]); + gGL.vertex3fv((width_vec + height_vec - top_border_height).mV); - glTexCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); - glVertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); + gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); // draw top left - glTexCoord2f(0.f, 1.f - border_scale.mV[VY]); - glVertex3fv((height_vec - top_border_height).mV); + gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]); + gGL.vertex3fv((height_vec - top_border_height).mV); - glTexCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); - glVertex3fv((left_border_width + height_vec - top_border_height).mV); + gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); - glTexCoord2f(border_scale.mV[VX], 1.f); - glVertex3fv((left_border_width + height_vec).mV); + gGL.texCoord2f(border_scale.mV[VX], 1.f); + gGL.vertex3fv((left_border_width + height_vec).mV); - glTexCoord2f(0.f, 1.f); - glVertex3fv((height_vec).mV); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3fv((height_vec).mV); // draw top middle - glTexCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); - glVertex3fv((left_border_width + height_vec - top_border_height).mV); + gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV); - glTexCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); - glVertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); + gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); - glTexCoord2f(1.f - border_scale.mV[VX], 1.f); - glVertex3fv((width_vec - right_border_width + height_vec).mV); + gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f); + gGL.vertex3fv((width_vec - right_border_width + height_vec).mV); - glTexCoord2f(border_scale.mV[VX], 1.f); - glVertex3fv((left_border_width + height_vec).mV); + gGL.texCoord2f(border_scale.mV[VX], 1.f); + gGL.vertex3fv((left_border_width + height_vec).mV); // draw top right - glTexCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); - glVertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); + gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]); + gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV); - glTexCoord2f(1.f, 1.f - border_scale.mV[VY]); - glVertex3fv((width_vec + height_vec - top_border_height).mV); + gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]); + gGL.vertex3fv((width_vec + height_vec - top_border_height).mV); - glTexCoord2f(1.f, 1.f); - glVertex3fv((width_vec + height_vec).mV); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex3fv((width_vec + height_vec).mV); - glTexCoord2f(1.f - border_scale.mV[VX], 1.f); - glVertex3fv((width_vec - right_border_width + height_vec).mV); + gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f); + gGL.vertex3fv((width_vec - right_border_width + height_vec).mV); } - glEnd(); + gGL.end(); + } void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec) @@ -1588,7 +1595,7 @@ void LLUI::cleanupClass() //static void LLUI::translate(F32 x, F32 y, F32 z) { - glTranslatef(x,y,z); + gGL.translatef(x,y,z); LLFontGL::sCurOrigin.mX += (S32) x; LLFontGL::sCurOrigin.mY += (S32) y; LLFontGL::sCurOrigin.mZ += z; @@ -1597,14 +1604,14 @@ void LLUI::translate(F32 x, F32 y, F32 z) //static void LLUI::pushMatrix() { - glPushMatrix(); + gGL.pushMatrix(); LLFontGL::sOriginStack.push_back(LLFontGL::sCurOrigin); } //static void LLUI::popMatrix() { - glPopMatrix(); + gGL.popMatrix(); LLFontGL::sCurOrigin = *LLFontGL::sOriginStack.rbegin(); LLFontGL::sOriginStack.pop_back(); } @@ -1627,6 +1634,7 @@ void LLUI::setScaleFactor(const LLVector2 &scale_factor) //static void LLUI::setLineWidth(F32 width) { + gGL.flush(); glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f)); } @@ -1644,7 +1652,7 @@ void LLUI::setCursorPositionScreen(S32 x, S32 y) } //static -void LLUI::setCursorPositionLocal(LLView* viewp, S32 x, S32 y) +void LLUI::setCursorPositionLocal(const LLView* viewp, S32 x, S32 y) { S32 screen_x, screen_y; viewp->localPointToScreen(x, y, &screen_x, &screen_y); @@ -1847,12 +1855,12 @@ void LLUIImage::setScaleRegion(const LLRectf& region) } //TODO: move drawing implementation inside class -void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) +void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const { gl_draw_image(x, y, mImage, color, mClipRegion); } -void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) +void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const { if (mUniformScaling) { @@ -1871,7 +1879,7 @@ void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) } } -void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) +void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const { gl_draw_scaled_image_with_border( x, y, @@ -1883,7 +1891,7 @@ void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& c mScaleRegion); } -void LLUIImage::drawSolid(S32 x, S32 y, const LLColor4& color) +void LLUIImage::drawSolid(S32 x, S32 y, const LLColor4& color) const { gl_draw_scaled_image_with_border( x, y, @@ -1895,12 +1903,12 @@ void LLUIImage::drawSolid(S32 x, S32 y, const LLColor4& color) mScaleRegion); } -S32 LLUIImage::getWidth() +S32 LLUIImage::getWidth() const { return mImage->getWidth(0); } -S32 LLUIImage::getHeight() +S32 LLUIImage::getHeight() const { return mImage->getHeight(0); } diff --git a/linden/indra/llui/llui.h b/linden/indra/llui/llui.h index 9d98620..c419cb6 100644 --- a/linden/indra/llui/llui.h +++ b/linden/indra/llui/llui.h @@ -1,6 +1,6 @@ /** * @file llui.h - * @brief UI implementation + * @brief GL function declarations and other general static UI services. * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -43,7 +43,10 @@ #include #include "llimagegl.h" -class LLColor4; +// LLUIFactory +#include "llsd.h" + +class LLColor4; class LLVector3; class LLVector2; class LLUUID; @@ -147,11 +150,15 @@ inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL extern BOOL gShowTextEditCursor; class LLImageProviderInterface; + typedef void (*LLUIAudioCallback)(const LLUUID& uuid); class LLUI { public: + // + // Methods + // static void initClass(LLControlGroup* config, LLControlGroup* colors, LLControlGroup* assets, @@ -169,10 +176,10 @@ public: //helper functions (should probably move free standing rendering helper functions here) static LLString locateSkin(const LLString& filename); static void setCursorPositionScreen(S32 x, S32 y); - static void setCursorPositionLocal(LLView* viewp, S32 x, S32 y); + static void setCursorPositionLocal(const LLView* viewp, S32 x, S32 y); static void setScaleFactor(const LLVector2& scale_factor); static void setLineWidth(F32 width); - static LLUUID findAssetUUIDByName(const LLString& name); + static LLUUID findAssetUUIDByName(const LLString& name); static LLUIImage* getUIImageByName(const LLString& name); static LLVector2 getWindowSize(); static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y); @@ -181,7 +188,9 @@ public: static void glRectToScreen(const LLRect& gl, LLRect *screen); static void setHtmlHelp(LLHtmlHelp* html_help); -public: + // + // Data + // static LLControlGroup* sConfigGroup; static LLControlGroup* sColorsGroup; static LLControlGroup* sAssetsGroup; @@ -215,6 +224,8 @@ typedef enum e_widget_type WIDGET_TYPE_SLIDER, // actually LLSliderCtrl WIDGET_TYPE_SLIDER_BAR, // actually LLSlider WIDGET_TYPE_VOLUME_SLIDER,//actually LLVolumeSliderCtrl + WIDGET_TYPE_MULTI_SLIDER, // actually LLMultiSliderCtrl + WIDGET_TYPE_MULTI_SLIDER_BAR, // actually LLMultiSlider WIDGET_TYPE_SPINNER, WIDGET_TYPE_TEXT_EDITOR, WIDGET_TYPE_TEXTURE_PICKER, @@ -287,93 +298,179 @@ typedef enum e_widget_type WIDGET_TYPE_COUNT } EWidgetType; -// Manages generation of UI elements by LLSD, such that there is -// only one instance per uniquely identified LLSD parameter -// Class T is the instance type being managed, and INSTANCE_ADDAPTOR -// wraps an instance of the class with handlers for show/hide semantics, etc. -template -class LLUIInstanceMgr +// FactoryPolicy is a static class that controls the creation and lookup of UI elements, +// such as floaters. +// The key parameter is used to provide a unique identifier and/or associated construction +// parameters for a given UI instance +// +// Specialize this traits for different types, or provide a class with an identical interface +// in the place of the traits parameter +// +// For example: +// +// template <> +// class FactoryPolicy /* FactoryPolicy specialized for MyClass */ +// { +// public: +// static MyClass* findInstance(const LLSD& key = LLSD()) +// { +// /* return instance of MyClass associated with key */ +// } +// +// static MyClass* createInstance(const LLSD& key = LLSD()) +// { +// /* create new instance of MyClass using key for construction parameters */ +// } +// } +// +// class MyClass : public LLUIFactory +// { +// /* uses FactoryPolicy by default */ +// } + +template +class FactoryPolicy +{ +public: + // basic factory methods + static T* findInstance(const LLSD& key); // unimplemented, provide specialiation + static T* createInstance(const LLSD& key); // unimplemented, provide specialiation +}; + +// VisibilityPolicy controls the visibility of UI elements, such as floaters. +// The key parameter is used to store the unique identifier of a given UI instance +// +// Specialize this traits for different types, or duplicate this interface for specific instances +// (see above) + +template +class VisibilityPolicy +{ +public: + // visibility methods + static bool visible(T* instance, const LLSD& key); // unimplemented, provide specialiation + static void show(T* instance, const LLSD& key); // unimplemented, provide specialiation + static void hide(T* instance, const LLSD& key); // unimplemented, provide specialiation +}; + +// Manages generation of UI elements by LLSD, such that (generally) there is +// a unique instance per distinct LLSD parameter +// Class T is the instance type being managed, and the FACTORY_POLICY and VISIBILITY_POLICY +// classes provide static methods for creating, accessing, showing and hiding the associated +// element T +template , class VISIBILITY_POLICY = VisibilityPolicy > +class LLUIFactory { public: - LLUIInstanceMgr() + // give names to the template parameters so derived classes can refer to them + // except this doesn't work in gcc + typedef FACTORY_POLICY factory_policy_t; + typedef VISIBILITY_POLICY visibility_policy_t; + + LLUIFactory() { } - virtual ~LLUIInstanceMgr() + virtual ~LLUIFactory() { } // default show and hide methods - static T* showInstance(const LLSD& seed = LLSD()) + static T* showInstance(const LLSD& key = LLSD()) { - T* instance = INSTANCE_ADAPTOR::getInstance(seed); - INSTANCE_ADAPTOR::show(instance); + T* instance = getInstance(key); + if (instance != NULL) + { + VISIBILITY_POLICY::show(instance, key); + } return instance; } - static void hideInstance(const LLSD& seed = LLSD()) + static void hideInstance(const LLSD& key = LLSD()) { - T* instance = INSTANCE_ADAPTOR::getInstance(seed); - INSTANCE_ADAPTOR::hide(instance); + T* instance = getInstance(key); + if (instance != NULL) + { + VISIBILITY_POLICY::hide(instance, key); + } } - static void toggleInstance(const LLSD& seed = LLSD()) + static void toggleInstance(const LLSD& key = LLSD()) { - if (INSTANCE_ADAPTOR::instanceVisible(seed)) + if (instanceVisible(key)) { - INSTANCE_ADAPTOR::hideInstance(seed); + hideInstance(key); } else { - INSTANCE_ADAPTOR::showInstance(seed); + showInstance(key); } } - static BOOL instanceVisible(const LLSD& seed = LLSD()) + static bool instanceVisible(const LLSD& key = LLSD()) { - T* instance = INSTANCE_ADAPTOR::findInstance(seed); - return instance != NULL && INSTANCE_ADAPTOR::visible(instance); + T* instance = FACTORY_POLICY::findInstance(key); + return instance != NULL && VISIBILITY_POLICY::visible(instance, key); } - static T* getInstance(const LLSD& seed = LLSD()) + static T* getInstance(const LLSD& key = LLSD()) { - T* instance = INSTANCE_ADAPTOR::findInstance(seed); + T* instance = FACTORY_POLICY::findInstance(key); if (instance == NULL) { - instance = INSTANCE_ADAPTOR::createInstance(seed); + instance = FACTORY_POLICY::createInstance(key); } return instance; } }; -// Creates a UI singleton by ignoring the identifying parameter -// and always generating the same instance via the LLUIInstanceMgr interface. -// Note that since UI elements can be destroyed by their hierarchy, this singleton -// pattern uses a static pointer to an instance that will be re-created as needed. -template -class LLUISingleton: public LLUIInstanceMgr + +// Creates a UI singleton by ignoring the identifying parameter +// and always generating the same instance via the LLUIFactory interface. +// Note that since UI elements can be destroyed by their hierarchy, this singleton +// pattern uses a static pointer to an instance that will be re-created as needed. +// +// Usage Pattern: +// +// class LLFloaterFoo : public LLFloater, public LLUISingleton +// { +// friend class LLUISingleton; +// private: +// LLFloaterFoo(const LLSD& key); +// }; +// +// Note that LLUISingleton takes an option VisibilityPolicy parameter that defines +// how showInstance(), hideInstance(), etc. work. +// +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLUISingleton&oldid=79352 + +template > +class LLUISingleton: public LLUIFactory, VISIBILITY_POLICY> { -public: - // default constructor assumes T is derived from LLUISingleton (a true singleton) - LLUISingleton() : LLUIInstanceMgr() { sInstance = (T*)this; } +protected: + + // T must derive from LLUISingleton + LLUISingleton() { sInstance = static_cast(this); } + ~LLUISingleton() { sInstance = NULL; } - static T* findInstance(const LLSD& seed = LLSD()) +public: + static T* findInstance(const LLSD& key = LLSD()) { return sInstance; } - - static T* createInstance(const LLSD& seed = LLSD()) + + static T* createInstance(const LLSD& key = LLSD()) { if (sInstance == NULL) { - sInstance = new T(seed); + sInstance = new T(key); } return sInstance; } -protected: +private: static T* sInstance; }; @@ -412,14 +509,15 @@ public: void setScaleRegion(const LLRectf& region); LLPointer getImage() { return mImage; } + const LLPointer& getImage() const { return mImage; } - void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR); - void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR); - void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color); - void drawSolid(S32 x, S32 y, const LLColor4& color); + void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const; + void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const; + void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const; + void drawSolid(S32 x, S32 y, const LLColor4& color) const; - S32 getWidth(); - S32 getHeight(); + S32 getWidth() const; + S32 getHeight() const; protected: LLRectf mScaleRegion; @@ -429,6 +527,140 @@ protected: BOOL mNoClip; }; + +template +class LLTombStone : public LLRefCount +{ +public: + LLTombStone(T* target = NULL) : mTarget(target) {} + + void setTarget(T* target) { mTarget = target; } + T* getTarget() const { return mTarget; } +private: + T* mTarget; +}; + +// LLHandles are used to refer to objects whose lifetime you do not control or influence. +// Calling get() on a handle will return a pointer to the referenced object or NULL, +// if the object no longer exists. Note that during the lifetime of the returned pointer, +// you are assuming that the object will not be deleted by any action you perform, +// or any other thread, as normal when using pointers, so avoid using that pointer outside of +// the local code block. +// +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 + +template +class LLHandle +{ +public: + LLHandle() : mTombStone(sDefaultTombStone) {} + const LLHandle& operator =(const LLHandle& other) + { + mTombStone = other.mTombStone; + return *this; + } + + bool isDead() const + { + return mTombStone->getTarget() == NULL; + } + + void markDead() + { + mTombStone = sDefaultTombStone; + } + + T* get() const + { + return mTombStone->getTarget(); + } + + friend bool operator== (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone == rhs.mTombStone; + } + friend bool operator!= (const LLHandle& lhs, const LLHandle& rhs) + { + return !(lhs == rhs); + } + friend bool operator< (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone < rhs.mTombStone; + } + friend bool operator> (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone > rhs.mTombStone; + } +protected: + +protected: + LLPointer > mTombStone; + +private: + static LLPointer > sDefaultTombStone; +}; + +// initialize static "empty" tombstone pointer +template LLPointer > LLHandle::sDefaultTombStone = new LLTombStone(); + + +template +class LLRootHandle : public LLHandle +{ +public: + LLRootHandle(T* object) { bind(object); } + LLRootHandle() {}; + ~LLRootHandle() { unbind(); } + + // this is redundant, since a LLRootHandle *is* an LLHandle + LLHandle getHandle() { return LLHandle(*this); } + + void bind(T* object) + { + // unbind existing tombstone + if (LLHandle::mTombStone.notNull()) + { + if (LLHandle::mTombStone->getTarget() == object) return; + LLHandle::mTombStone->setTarget(NULL); + } + // tombstone reference counted, so no paired delete + LLHandle::mTombStone = new LLTombStone(object); + } + + void unbind() + { + LLHandle::mTombStone->setTarget(NULL); + } + + //don't allow copying of root handles, since there should only be one +private: + LLRootHandle(const LLRootHandle& other) {}; +}; + +// Use this as a mixin for simple classes that need handles and when you don't +// want handles at multiple points of the inheritance hierarchy +template +class LLHandleProvider +{ +protected: + typedef LLHandle handle_type_t; + LLHandleProvider() + { + // provided here to enforce T deriving from LLHandleProvider + } + + LLHandle getHandle() + { + // perform lazy binding to avoid small tombstone allocations for handle + // providers whose handles are never referenced + mHandle.bind(static_cast(this)); + return mHandle; + } + +private: + LLRootHandle mHandle; +}; + //RN: maybe this needs to moved elsewhere? class LLImageProviderInterface { diff --git a/linden/indra/llui/llui.vcproj b/linden/indra/llui/llui.vcproj index dad42c6..f5e7df5 100644 --- a/linden/indra/llui/llui.vcproj +++ b/linden/indra/llui/llui.vcproj @@ -26,6 +26,7 @@ RuntimeLibrary="1" StructMemberAlignment="4" ForceConformanceInForLoopScope="TRUE" + RuntimeTypeInfo="TRUE" UsePrecompiledHeader="0" WarningLevel="3" WarnAsError="TRUE" @@ -69,6 +70,7 @@ RuntimeLibrary="0" StructMemberAlignment="0" ForceConformanceInForLoopScope="TRUE" + RuntimeTypeInfo="TRUE" UsePrecompiledHeader="0" WarningLevel="3" WarnAsError="TRUE" @@ -113,6 +115,7 @@ RuntimeLibrary="0" StructMemberAlignment="0" ForceConformanceInForLoopScope="TRUE" + RuntimeTypeInfo="TRUE" UsePrecompiledHeader="0" WarningLevel="3" WarnAsError="TRUE" @@ -196,6 +199,12 @@ RelativePath=".\llmodaldialog.cpp"> + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llui/llui_vc9.vcproj b/linden/indra/llui/llui_vc9.vcproj index cfaaf66..cedc726 100644 --- a/linden/indra/llui/llui_vc9.vcproj +++ b/linden/indra/llui/llui_vc9.vcproj @@ -1,596 +1,612 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llui/lluictrl.cpp b/linden/indra/llui/lluictrl.cpp index 63db1cc..0e6c155 100644 --- a/linden/indra/llui/lluictrl.cpp +++ b/linden/indra/llui/lluictrl.cpp @@ -32,20 +32,9 @@ //#include "llviewerprecompiledheaders.h" #include "linden_common.h" - #include "lluictrl.h" - -#include "llgl.h" -#include "llui.h" -#include "lluiconstants.h" #include "llfocusmgr.h" -#include "v3color.h" - -#include "llstring.h" -#include "llfontgl.h" -#include "llkeyboard.h" -const U32 MAX_STRING_LENGTH = 10; LLFocusableElement::LLFocusableElement() : mFocusLostCallback(NULL), @@ -55,6 +44,11 @@ LLFocusableElement::LLFocusableElement() { } +//virtual +LLFocusableElement::~LLFocusableElement() +{ +} + void LLFocusableElement::onFocusReceived() { if( mFocusReceivedCallback ) @@ -138,6 +132,18 @@ void LLUICtrl::onCommit() } } +//virtual +BOOL LLUICtrl::isCtrl() const +{ + return TRUE; +} + +//virtual +LLSD LLUICtrl::getValue() const +{ + return LLSD(); +} + // virtual BOOL LLUICtrl::setTextArg( const LLString& key, const LLStringExplicit& text ) { @@ -176,7 +182,7 @@ BOOL LLUICtrl::hasFocus() const void LLUICtrl::setFocus(BOOL b) { // focus NEVER goes to ui ctrls that are disabled! - if (!mEnabled) + if (!getEnabled()) { return; } @@ -266,6 +272,17 @@ BOOL LLUICtrl::acceptsTextInput() const return FALSE; } +//virtual +BOOL LLUICtrl::isDirty() const +{ + return FALSE; +}; + +//virtual +void LLUICtrl::resetDirty() +{ +} + // virtual void LLUICtrl::onTabInto() { @@ -285,8 +302,6 @@ void LLUICtrl::setIsChrome(BOOL is_chrome) // virtual BOOL LLUICtrl::getIsChrome() const { - // am I or any of my ancestors flagged as "chrome"? - if (mIsChrome) return TRUE; LLView* parent_ctrl = getParent(); while(parent_ctrl) @@ -300,11 +315,12 @@ BOOL LLUICtrl::getIsChrome() const if(parent_ctrl) { - // recurse into parent_ctrl and ask if it is in a chrome subtree - return ((LLUICtrl*)parent_ctrl)->getIsChrome(); + return mIsChrome || ((LLUICtrl*)parent_ctrl)->getIsChrome(); + } + else + { + return mIsChrome ; } - - return FALSE; } // this comparator uses the crazy disambiguating logic of LLCompareByTabOrder, @@ -316,7 +332,7 @@ public: CompareByDefaultTabGroup(LLView::child_tab_order_t order, S32 default_tab_group): LLCompareByTabOrder(order), mDefaultTabGroup(default_tab_group) {} -protected: +private: /*virtual*/ bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const { S32 ag = a.first; // tab group for a @@ -330,8 +346,10 @@ protected: S32 mDefaultTabGroup; }; -// sorter for plugging into the query -class DefaultTabGroupFirstSorter : public LLQuerySorter, public LLSingleton + +// Sorter for plugging into the query. +// I'd have defined it local to the one method that uses it but that broke the VS 05 compiler. -MG +class LLUICtrl::DefaultTabGroupFirstSorter : public LLQuerySorter, public LLSingleton { public: /*virtual*/ void operator() (LLView * parent, viewList_t &children) const @@ -340,14 +358,47 @@ public: } }; - -BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields) +BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash) { // try to select default tab group child - LLCtrlQuery query = LLView::getTabOrderQuery(); + LLCtrlQuery query = getTabOrderQuery(); // sort things such that the default tab group is at the front query.setSorter(DefaultTabGroupFirstSorter::getInstance()); - LLView::child_list_t result = query(this); + child_list_t result = query(this); + if(result.size() > 0) + { + LLUICtrl * ctrl = static_cast(result.front()); + if(!ctrl->hasFocus()) + { + ctrl->setFocus(TRUE); + ctrl->onTabInto(); + if(focus_flash) + { + gFocusMgr.triggerFocusFlash(); + } + } + return TRUE; + } + // search for text field first + if(prefer_text_fields) + { + LLCtrlQuery query = getTabOrderQuery(); + query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); + child_list_t result = query(this); + if(result.size() > 0) + { + LLUICtrl * ctrl = static_cast(result.front()); + if(!ctrl->hasFocus()) + { + ctrl->setFocus(TRUE); + ctrl->onTabInto(); + gFocusMgr.triggerFocusFlash(); + } + return TRUE; + } + } + // no text field found, or we don't care about text fields + result = getTabOrderQuery().run(this); if(result.size() > 0) { LLUICtrl * ctrl = static_cast(result.front()); @@ -359,10 +410,85 @@ BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields) } return TRUE; } - // fall back on default behavior if we didn't find anything - return LLView::focusFirstItem(prefer_text_fields); + return FALSE; } +BOOL LLUICtrl::focusLastItem(BOOL prefer_text_fields) +{ + // search for text field first + if(prefer_text_fields) + { + LLCtrlQuery query = getTabOrderQuery(); + query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); + child_list_t result = query(this); + if(result.size() > 0) + { + LLUICtrl * ctrl = static_cast(result.back()); + if(!ctrl->hasFocus()) + { + ctrl->setFocus(TRUE); + ctrl->onTabInto(); + gFocusMgr.triggerFocusFlash(); + } + return TRUE; + } + } + // no text field found, or we don't care about text fields + child_list_t result = getTabOrderQuery().run(this); + if(result.size() > 0) + { + LLUICtrl * ctrl = static_cast(result.back()); + if(!ctrl->hasFocus()) + { + ctrl->setFocus(TRUE); + ctrl->onTabInto(); + gFocusMgr.triggerFocusFlash(); + } + return TRUE; + } + return FALSE; +} + +BOOL LLUICtrl::focusNextItem(BOOL text_fields_only) +{ + // this assumes that this method is called on the focus root. + LLCtrlQuery query = getTabOrderQuery(); + if(text_fields_only || LLUI::sConfigGroup->getBOOL("TabToTextFieldsOnly")) + { + query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); + } + child_list_t result = query(this); + return focusNext(result); +} + +BOOL LLUICtrl::focusPrevItem(BOOL text_fields_only) +{ + // this assumes that this method is called on the focus root. + LLCtrlQuery query = getTabOrderQuery(); + if(text_fields_only || LLUI::sConfigGroup->getBOOL("TabToTextFieldsOnly")) + { + query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); + } + child_list_t result = query(this); + return focusPrev(result); +} + +const LLUICtrl* LLUICtrl::findRootMostFocusRoot() const +{ + const LLUICtrl* focus_root = NULL; + const LLUICtrl* next_view = this; + while(next_view) + { + if (next_view->isFocusRoot()) + { + focus_root = next_view; + } + next_view = next_view->getParentUICtrl(); + } + return focus_root; +} + + /* // Don't let the children handle the tool tip. Handle it here instead. BOOL LLUICtrl::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen) @@ -379,7 +505,7 @@ BOOL LLUICtrl::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_sc 0, 0, &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); localPointToScreen( - mRect.getWidth(), mRect.getHeight(), + getRect().getWidth(), getRect().getHeight(), &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); handled = TRUE; @@ -423,7 +549,26 @@ LLPanel* LLUICtrl::getParentPanel() const { parent = parent->getParent(); } - return reinterpret_cast(parent); + return (LLPanel*)(parent); +} + +// Skip over any parents that are not LLUICtrl's +// Used in focus logic since only LLUICtrl elements can have focus +LLUICtrl* LLUICtrl::getParentUICtrl() const +{ + LLView* parent = getParent(); + while (parent) + { + if (parent->isCtrl()) + { + return (LLUICtrl*)(parent); + } + else + { + parent = parent->getParent(); + } + } + return NULL; } // virtual diff --git a/linden/indra/llui/lluictrl.h b/linden/indra/llui/lluictrl.h index 55e804c..0c43297 100644 --- a/linden/indra/llui/lluictrl.h +++ b/linden/indra/llui/lluictrl.h @@ -37,28 +37,13 @@ #include "llrect.h" #include "llsd.h" -// -// Classes -// -class LLFontGL; -class LLButton; -class LLTextBox; -class LLLineEditor; -class LLUICtrl; -class LLPanel; -class LLCtrlSelectionInterface; -class LLCtrlListInterface; -class LLCtrlScrollInterface; - -typedef void (*LLUICtrlCallback)(LLUICtrl* ctrl, void* userdata); -typedef BOOL (*LLUICtrlValidate)(LLUICtrl* ctrl, void* userdata); class LLFocusableElement { friend class LLFocusMgr; // allow access to focus change handlers public: LLFocusableElement(); - virtual ~LLFocusableElement() {}; + virtual ~LLFocusableElement(); virtual void setFocus( BOOL b ); virtual BOOL hasFocus() const; @@ -80,63 +65,74 @@ class LLUICtrl : public LLView, public LLFocusableElement { public: + typedef void (*LLUICtrlCallback)(LLUICtrl* ctrl, void* userdata); + typedef BOOL (*LLUICtrlValidate)(LLUICtrl* ctrl, void* userdata); + LLUICtrl(); LLUICtrl( const LLString& name, const LLRect& rect, BOOL mouse_opaque, LLUICtrlCallback callback, void* callback_userdata, U32 reshape=FOLLOWS_NONE); - virtual ~LLUICtrl(); + /*virtual*/ ~LLUICtrl(); // LLView interface - //virtual BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect); - virtual void initFromXML(LLXMLNodePtr node, LLView* parent); - virtual LLXMLNodePtr getXML(bool save_children = true) const; - - virtual LLSD getValue() const { return LLSD(); } - - // Defaults to no-op - virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ); - - // Defaults to no-op - virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); + /*virtual*/ void initFromXML(LLXMLNodePtr node, LLView* parent); + /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; + /*virtual*/ BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); + /*virtual*/ void onFocusReceived(); + /*virtual*/ void onFocusLost(); + /*virtual*/ BOOL isCtrl() const; + /*virtual*/ void setTentative(BOOL b); + /*virtual*/ BOOL getTentative() const; + + // From LLFocusableElement + /*virtual*/ void setFocus( BOOL b ); + /*virtual*/ BOOL hasFocus() const; + + // New virtuals - // Defaults to return NULL - virtual LLCtrlSelectionInterface* getSelectionInterface(); - virtual LLCtrlListInterface* getListInterface(); - virtual LLCtrlScrollInterface* getScrollInterface(); + // Return NULL by default (overrride if the class has the appropriate interface) + virtual class LLCtrlSelectionInterface* getSelectionInterface(); + virtual class LLCtrlListInterface* getListInterface(); + virtual class LLCtrlScrollInterface* getScrollInterface(); - virtual void setFocus( BOOL b ); - virtual BOOL hasFocus() const; + virtual LLSD getValue() const; + virtual BOOL setTextArg( const LLString& key, const LLStringExplicit& text ); + virtual void setIsChrome(BOOL is_chrome); - virtual void onFocusReceived(); - virtual void onFocusLost(); + virtual BOOL acceptsTextInput() const; // Defaults to false + // A control is dirty if the user has modified its value. + // Editable controls should override this. + virtual BOOL isDirty() const; // Defauls to false + virtual void resetDirty(); //Defaults to no-op + + // Call appropriate callbacks virtual void onLostTop(); // called when registered as top ctrl and user clicks elsewhere - - virtual void setTabStop( BOOL b ); - virtual BOOL hasTabStop() const; - - // Defaults to false - virtual BOOL acceptsTextInput() const; - - // Default to no-op + virtual void onCommit(); + + // Default to no-op: virtual void onTabInto(); virtual void clear(); + virtual void setDoubleClickCallback( void (*cb)(void*) ); + virtual void setColor(const LLColor4& color); + virtual void setMinValue(LLSD min_value); + virtual void setMaxValue(LLSD max_value); - virtual void setIsChrome(BOOL is_chrome); - virtual BOOL getIsChrome() const; - - virtual void onCommit(); + BOOL focusNextItem(BOOL text_entry_only); + BOOL focusPrevItem(BOOL text_entry_only); + BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE ); + BOOL focusLastItem(BOOL prefer_text_fields = FALSE); - virtual BOOL isCtrl() const { return TRUE; } - // "Tentative" controls have a proposed value, but haven't committed - // it yet. This is used when multiple objects are selected and we - // want to display a parameter that differs between the objects. - virtual void setTentative(BOOL b); - virtual BOOL getTentative() const; + // Non Virtuals + BOOL getIsChrome() const; + + void setTabStop( BOOL b ); + BOOL hasTabStop() const; // Returns containing panel/floater or NULL if none found. - LLPanel* getParentPanel() const; + class LLPanel* getParentPanel() const; + class LLUICtrl* getParentUICtrl() const; void* getCallbackUserData() const { return mCallbackUserData; } void setCallbackUserData( void* data ) { mCallbackUserData = data; } @@ -144,18 +140,8 @@ public: void setCommitCallback( void (*cb)(LLUICtrl*, void*) ) { mCommitCallback = cb; } void setValidateBeforeCommit( BOOL(*cb)(LLUICtrl*, void*) ) { mValidateCallback = cb; } void setLostTopCallback( void (*cb)(LLUICtrl*, void*) ) { mLostTopCallback = cb; } - - // Defaults to no-op! - virtual void setDoubleClickCallback( void (*cb)(void*) ); - - // Defaults to no-op - virtual void setColor(const LLColor4& color); - - // Defaults to no-op - virtual void setMinValue(LLSD min_value); - virtual void setMaxValue(LLSD max_value); - - /*virtual*/ BOOL focusFirstItem(BOOL prefer_text_fields = FALSE ); + + const LLUICtrl* findRootMostFocusRoot() const; class LLTextInputFilter : public LLQueryFilter, public LLSingleton { @@ -165,11 +151,6 @@ public: } }; - // Returns TRUE if the user has modified this control. Editable controls should override this. - virtual BOOL isDirty() const { return FALSE; }; - // Clear the dirty state - virtual void resetDirty() {}; - protected: void (*mCommitCallback)( LLUICtrl* ctrl, void* userdata ); @@ -177,13 +158,14 @@ protected: BOOL (*mValidateCallback)( LLUICtrl* ctrl, void* userdata ); void* mCallbackUserData; - BOOL mTentative; - BOOL mTabStop; private: - BOOL mIsChrome; + BOOL mTabStop; + BOOL mIsChrome; + BOOL mTentative; + class DefaultTabGroupFirstSorter; }; #endif // LL_LLUICTRL_H diff --git a/linden/indra/llui/lluictrlfactory.cpp b/linden/indra/llui/lluictrlfactory.cpp index a51d8e4..cfee76a 100644 --- a/linden/indra/llui/lluictrlfactory.cpp +++ b/linden/indra/llui/lluictrlfactory.cpp @@ -59,6 +59,8 @@ #include "llscrolllistctrl.h" #include "llslider.h" #include "llsliderctrl.h" +#include "llmultislider.h" +#include "llmultisliderctrl.h" #include "llspinctrl.h" #include "lltabcontainer.h" #include "lltabcontainervertical.h" @@ -67,7 +69,6 @@ #include "llui.h" #include "llviewborder.h" - const char XML_HEADER[] = "\n"; // *NOTE: If you add a new class derived from LLPanel, add a check for its @@ -93,6 +94,8 @@ const LLString LLUICtrlFactory::sUICtrlNames[WIDGET_TYPE_COUNT] = LLString("slider"), //WIDGET_TYPE_SLIDER, actually LLSliderCtrl LLString("slider_bar"), //WIDGET_TYPE_SLIDER_BAR, actually LLSlider LLString("volume_slider"), //WIDGET_TYPE_VOLUME_SLIDER, actually LLSlider + "volume" param + LLString("multi_slider"), //WIDGET_TYPE_MULTI_SLIDER, actually LLMultiSliderCtrl + LLString("multi_slider_bar"), //WIDGET_TYPE_MULTI_SLIDER_BAR, actually LLMultiSlider LLString("spinner"), //WIDGET_TYPE_SPINNER, actually LLSpinCtrl LLString("text_editor"), //WIDGET_TYPE_TEXT_EDITOR LLString("texture_picker"),//WIDGET_TYPE_TEXTURE_PICKER @@ -207,6 +210,8 @@ LLUICtrlFactory::LLUICtrlFactory() LLUICtrlCreator::registerCreator(LL_SLIDER_CTRL_TAG, this); LLUICtrlCreator::registerCreator(LL_SLIDER_TAG, this); LLUICtrlCreator::registerCreator(LL_VOLUME_SLIDER_CTRL_TAG, this); + LLUICtrlCreator::registerCreator(LL_MULTI_SLIDER_CTRL_TAG, this); + LLUICtrlCreator::registerCreator(LL_MULTI_SLIDER_TAG, this); LLUICtrlCreator::registerCreator(LL_SPIN_CTRL_TAG, this); LLUICtrlCreator::registerCreator(LL_TEXT_BOX_TAG, this); LLUICtrlCreator::registerCreator(LL_RADIO_GROUP_TAG, this); @@ -214,7 +219,7 @@ LLUICtrlFactory::LLUICtrlFactory() LLUICtrlCreator::registerCreator(LL_UI_CTRL_LOCATE_TAG, this); LLUICtrlCreator::registerCreator(LL_PAD_TAG, this); LLUICtrlCreator::registerCreator(LL_VIEW_BORDER_TAG, this); - LLUICtrlCreator::registerCreator(LL_TAB_CONTAINER_COMMON_TAG, this); + LLUICtrlCreator::registerCreator(LL_TAB_CONTAINER_COMMON_TAG, this); LLUICtrlCreator::registerCreator(LL_SCROLLABLE_CONTAINER_VIEW_TAG, this); LLUICtrlCreator::registerCreator(LL_PANEL_TAG, this); LLUICtrlCreator::registerCreator(LL_MENU_GL_TAG, this); @@ -223,7 +228,6 @@ LLUICtrlFactory::LLUICtrlFactory() LLUICtrlCreator::registerCreator(LL_LAYOUT_STACK_TAG, this); setupPaths(); - } void LLUICtrlFactory::setupPaths() @@ -234,14 +238,7 @@ void LLUICtrlFactory::setupPaths() BOOL success = LLXMLNode::parseFile(filename, root, NULL); mXUIPaths.clear(); - if (!success) - { - LLString slash = gDirUtilp->getDirDelimiter(); - LLString dir = gDirUtilp->getAppRODataDir() + slash + "skins" + slash + "xui" + slash + "en-us" + slash; - llwarns << "XUI::config file unable to open." << llendl; - mXUIPaths.push_back(dir); - } - else + if (success) { LLXMLNodePtr path; LLString app_dir = gDirUtilp->getAppRODataDir(); @@ -267,16 +264,15 @@ void LLUICtrlFactory::setupPaths() } } } - - + else // parsing failed + { + LLString slash = gDirUtilp->getDirDelimiter(); + LLString dir = gDirUtilp->getAppRODataDir() + slash + "skins" + slash + "xui" + slash + "en-us" + slash; + llwarns << "XUI::config file unable to open." << llendl; + mXUIPaths.push_back(dir); + } } -//----------------------------------------------------------------------------- -// ~LLUICtrlFactory() -//----------------------------------------------------------------------------- -LLUICtrlFactory::~LLUICtrlFactory() -{ -} //----------------------------------------------------------------------------- @@ -284,7 +280,6 @@ LLUICtrlFactory::~LLUICtrlFactory() //----------------------------------------------------------------------------- bool LLUICtrlFactory::getLayeredXMLNode(const LLString &filename, LLXMLNodePtr& root) { - if (!LLXMLNode::parseFile(mXUIPaths.front() + filename, root, NULL)) { if (!LLXMLNode::parseFile(filename, root, NULL)) @@ -347,7 +342,7 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const LLString &filename if (LLUI::sShowXUINames) { - floaterp->mToolTipMsg = filename; + floaterp->setToolTip(filename); } if (factory_map) @@ -355,7 +350,7 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const LLString &filename mFactoryStack.pop_front(); } - LLViewHandle handle = floaterp->getHandle(); + LLHandle handle = floaterp->getHandle(); mBuiltFloaters[handle] = filename; } @@ -411,10 +406,10 @@ BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const LLString &filename, if (LLUI::sShowXUINames) { - panelp->mToolTipMsg = filename; + panelp->setToolTip(filename); } - LLViewHandle handle = panelp->getHandle(); + LLHandle handle = panelp->getHandle(); mBuiltPanels[handle] = filename; if (factory_map) @@ -446,8 +441,6 @@ LLMenuGL *LLUICtrlFactory::buildMenu(const LLString &filename, LLView* parentp) return NULL; } - - if (root->hasName("menu")) { menu = (LLMenuGL*)LLMenuGL::fromXML(root, parentp, this); @@ -459,7 +452,7 @@ LLMenuGL *LLUICtrlFactory::buildMenu(const LLString &filename, LLView* parentp) if (LLUI::sShowXUINames) { - menu->mToolTipMsg = filename; + menu->setToolTip(filename); } return menu; @@ -470,7 +463,6 @@ LLMenuGL *LLUICtrlFactory::buildMenu(const LLString &filename, LLView* parentp) //----------------------------------------------------------------------------- LLPieMenu *LLUICtrlFactory::buildPieMenu(const LLString &filename, LLView* parentp) { - LLXMLNodePtr root; if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) @@ -494,29 +486,13 @@ LLPieMenu *LLUICtrlFactory::buildPieMenu(const LLString &filename, LLView* paren if (LLUI::sShowXUINames) { - menu->mToolTipMsg = filename; + menu->setToolTip(filename); } return menu; } //----------------------------------------------------------------------------- -// removePanel() -//----------------------------------------------------------------------------- -void LLUICtrlFactory::removePanel(LLPanel* panelp) -{ - mBuiltPanels.erase(panelp->getHandle()); -} - -//----------------------------------------------------------------------------- -// removeFloater() -//----------------------------------------------------------------------------- -void LLUICtrlFactory::removeFloater(LLFloater* floaterp) -{ - mBuiltFloaters.erase(floaterp->getHandle()); -} - -//----------------------------------------------------------------------------- // rebuild() //----------------------------------------------------------------------------- void LLUICtrlFactory::rebuild() @@ -525,48 +501,48 @@ void LLUICtrlFactory::rebuild() for (built_panel_it = mBuiltPanels.begin(); built_panel_it != mBuiltPanels.end(); ++built_panel_it) + { + LLString filename = built_panel_it->second; + LLPanel* panelp = built_panel_it->first.get(); + if (!panelp) { - LLString filename = built_panel_it->second; - LLPanel* panelp = LLPanel::getPanelByHandle(built_panel_it->first); - if (!panelp) - { - continue; - } - llinfos << "Rebuilding UI panel " << panelp->getName() - << " from " << filename - << llendl; - BOOL visible = panelp->getVisible(); - panelp->setVisible(FALSE); - panelp->setFocus(FALSE); - panelp->deleteAllChildren(); - - buildPanel(panelp, filename.c_str(), &panelp->getFactoryMap()); - panelp->setVisible(visible); + continue; } + llinfos << "Rebuilding UI panel " << panelp->getName() + << " from " << filename + << llendl; + BOOL visible = panelp->getVisible(); + panelp->setVisible(FALSE); + panelp->setFocus(FALSE); + panelp->deleteAllChildren(); + + buildPanel(panelp, filename.c_str(), &panelp->getFactoryMap()); + panelp->setVisible(visible); + } built_floater_t::iterator built_floater_it; for (built_floater_it = mBuiltFloaters.begin(); built_floater_it != mBuiltFloaters.end(); ++built_floater_it) + { + LLFloater* floaterp = built_floater_it->first.get(); + if (!floaterp) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(built_floater_it->first); - if (!floaterp) - { - continue; - } - LLString filename = built_floater_it->second; - llinfos << "Rebuilding UI floater " << floaterp->getName() - << " from " << filename - << llendl; - BOOL visible = floaterp->getVisible(); - floaterp->setVisible(FALSE); - floaterp->setFocus(FALSE); - floaterp->deleteAllChildren(); - - gFloaterView->removeChild(floaterp); - buildFloater(floaterp, filename, &floaterp->getFactoryMap()); - floaterp->setVisible(visible); + continue; } + LLString filename = built_floater_it->second; + llinfos << "Rebuilding UI floater " << floaterp->getName() + << " from " << filename + << llendl; + BOOL visible = floaterp->getVisible(); + floaterp->setVisible(FALSE); + floaterp->setFocus(FALSE); + floaterp->deleteAllChildren(); + + gFloaterView->removeChild(floaterp); + buildFloater(floaterp, filename, &floaterp->getFactoryMap()); + floaterp->setVisible(visible); + } } //----------------------------------------------------------------------------- @@ -674,113 +650,103 @@ BOOL LLUICtrlFactory::getAttributeColor(LLXMLNodePtr node, const LLString& name, //============================================================================ -LLButton* LLUICtrlFactory::getButtonByName(LLPanel* panelp, const LLString& name) +LLButton* LLUICtrlFactory::getButtonByName(const LLPanel* panelp, const LLString& name) { - return (LLButton*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_BUTTON); + return panelp->getChild(name); } -LLCheckBoxCtrl* LLUICtrlFactory::getCheckBoxByName(LLPanel* panelp, const LLString& name) +LLCheckBoxCtrl* LLUICtrlFactory::getCheckBoxByName(const LLPanel* panelp, const LLString& name) { - return (LLCheckBoxCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_CHECKBOX); + return panelp->getChild(name); } -LLComboBox* LLUICtrlFactory::getComboBoxByName(LLPanel* panelp, const LLString& name) +LLComboBox* LLUICtrlFactory::getComboBoxByName(const LLPanel* panelp, const LLString& name) { - return (LLComboBox*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_COMBO_BOX); + return panelp->getChild(name); } -LLIconCtrl* LLUICtrlFactory::getIconByName(LLPanel* panelp, const LLString& name) +LLIconCtrl* LLUICtrlFactory::getIconByName(const LLPanel* panelp, const LLString& name) { - return (LLIconCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_ICON); + return panelp->getChild(name); } -LLLineEditor* LLUICtrlFactory::getLineEditorByName(LLPanel* panelp, const LLString& name) +LLLineEditor* LLUICtrlFactory::getLineEditorByName(const LLPanel* panelp, const LLString& name) { - return (LLLineEditor*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_LINE_EDITOR); + return panelp->getChild(name); } -LLNameListCtrl* LLUICtrlFactory::getNameListByName(LLPanel* panelp, const LLString& name) +LLRadioGroup* LLUICtrlFactory::getRadioGroupByName(const LLPanel* panelp, const LLString& name) { - return (LLNameListCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_NAME_LIST); + return panelp->getChild(name); } -LLRadioGroup* LLUICtrlFactory::getRadioGroupByName(LLPanel* panelp, const LLString& name) +LLScrollListCtrl* LLUICtrlFactory::getScrollListByName(const LLPanel* panelp, const LLString& name) { - return (LLRadioGroup*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_RADIO_GROUP); + return panelp->getChild(name); } -LLScrollListCtrl* LLUICtrlFactory::getScrollListByName(LLPanel* panelp, const LLString& name) +LLSliderCtrl* LLUICtrlFactory::getSliderByName(const LLPanel* panelp, const LLString& name) { - return (LLScrollListCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SCROLL_LIST); + return panelp->getChild(name); } -LLSliderCtrl* LLUICtrlFactory::getSliderByName(LLPanel* panelp, const LLString& name) +LLSlider* LLUICtrlFactory::getSliderBarByName(const LLPanel* panelp, const LLString& name) { - return (LLSliderCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SLIDER); + return panelp->getChild(name); } -LLSlider* LLUICtrlFactory::getSliderBarByName(LLPanel* panelp, const LLString& name) +LLSpinCtrl* LLUICtrlFactory::getSpinnerByName(const LLPanel* panelp, const LLString& name) { - return (LLSlider*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SLIDER_BAR); + return panelp->getChild(name); } -LLSpinCtrl* LLUICtrlFactory::getSpinnerByName(LLPanel* panelp, const LLString& name) +LLTextBox* LLUICtrlFactory::getTextBoxByName(const LLPanel* panelp, const LLString& name) { - return (LLSpinCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SPINNER); + return panelp->getChild(name); } -LLTextBox* LLUICtrlFactory::getTextBoxByName(LLPanel* panelp, const LLString& name) +LLTextEditor* LLUICtrlFactory::getTextEditorByName(const LLPanel* panelp, const LLString& name) { - return (LLTextBox*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_TEXT_BOX); + return panelp->getChild(name); } -LLTextEditor* LLUICtrlFactory::getTextEditorByName(LLPanel* panelp, const LLString& name) +LLTabContainer* LLUICtrlFactory::getTabContainerByName(const LLPanel* panelp, const LLString& name) { - return (LLTextEditor*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_TEXT_EDITOR); -} - -LLTabContainerCommon* LLUICtrlFactory::getTabContainerByName(LLPanel* panelp, const LLString& name) -{ - return (LLTabContainerCommon*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_TAB_CONTAINER); -} - -LLScrollableContainerView* LLUICtrlFactory::getScrollableContainerByName(LLPanel* panelp, const LLString& name) -{ - return (LLScrollableContainerView*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SCROLL_CONTAINER); + return panelp->getChild(name); } -LLTextureCtrl* LLUICtrlFactory::getTexturePickerByName(LLPanel* panelp, const LLString& name) +LLScrollableContainerView* LLUICtrlFactory::getScrollableContainerByName(const LLPanel* panelp, const LLString& name) { - return (LLTextureCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_TEXTURE_PICKER); + return panelp->getChild(name); } -LLPanel* LLUICtrlFactory::getPanelByName(LLPanel* panelp, const LLString& name) +LLPanel* LLUICtrlFactory::getPanelByName(const LLPanel* panelp, const LLString& name) { - return (LLPanel*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_PANEL); + return panelp->getChild(name); } -LLColorSwatchCtrl* LLUICtrlFactory::getColorSwatchByName(LLPanel* panelp, const LLString& name) +LLMenuItemCallGL* LLUICtrlFactory::getMenuItemCallByName(const LLPanel* panelp, const LLString& name) { - return (LLColorSwatchCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_COLOR_SWATCH); + return panelp->getChild(name); } -LLWebBrowserCtrl* LLUICtrlFactory::getWebBrowserCtrlByName(LLPanel* panelp, const LLString& name) +LLScrollingPanelList* LLUICtrlFactory::getScrollingPanelList(const LLPanel* panelp, const LLString& name) { - return (LLWebBrowserCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_WEBBROWSER); + return panelp->getChild(name); } -LLMenuItemCallGL* LLUICtrlFactory::getMenuItemCallByName(LLPanel* panelp, const LLString& name) +LLMultiSliderCtrl* LLUICtrlFactory::getMultiSliderByName(const LLPanel* panelp, const LLString& name) { - return (LLMenuItemCallGL*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_MENU_ITEM_CALL); + return panelp->getChild(name); } -LLScrollingPanelList* LLUICtrlFactory::getScrollingPanelList(LLPanel* panelp, const LLString& name) +LLMultiSlider* LLUICtrlFactory::getMultiSliderBarByName(const LLPanel* panelp, const LLString& name) { - return (LLScrollingPanelList*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_SCROLLING_PANEL_LIST); + return panelp->getChild(name); } -LLCtrlListInterface* LLUICtrlFactory::getListInterfaceByName(LLPanel* panelp, const LLString& name) +LLCtrlListInterface* LLUICtrlFactory::getListInterfaceByName(const LLPanel* panelp, const LLString& name) { LLView* viewp = panelp->getCtrlByNameAndType(name, WIDGET_TYPE_DONTCARE); if (viewp && viewp->isCtrl()) @@ -790,7 +756,7 @@ LLCtrlListInterface* LLUICtrlFactory::getListInterfaceByName(LLPanel* panelp, co return NULL; } -LLCtrlSelectionInterface* LLUICtrlFactory::getSelectionInterfaceByName(LLPanel* panelp, const LLString& name) +LLCtrlSelectionInterface* LLUICtrlFactory::getSelectionInterfaceByName(const LLPanel* panelp, const LLString& name) { LLView* viewp = panelp->getCtrlByNameAndType(name, WIDGET_TYPE_DONTCARE); if (viewp && viewp->isCtrl()) @@ -800,7 +766,7 @@ LLCtrlSelectionInterface* LLUICtrlFactory::getSelectionInterfaceByName(LLPanel* return NULL; } -LLCtrlScrollInterface* LLUICtrlFactory::getScrollInterfaceByName(LLPanel* panelp, const LLString& name) +LLCtrlScrollInterface* LLUICtrlFactory::getScrollInterfaceByName(const LLPanel* panelp, const LLString& name) { LLView* viewp = panelp->getCtrlByNameAndType(name, WIDGET_TYPE_DONTCARE); if (viewp && viewp->isCtrl()) diff --git a/linden/indra/llui/lluictrlfactory.h b/linden/indra/llui/lluictrlfactory.h index fbb8d96..e6a2cd3 100644 --- a/linden/indra/llui/lluictrlfactory.h +++ b/linden/indra/llui/lluictrlfactory.h @@ -38,68 +38,35 @@ #include "llcallbackmap.h" #include "llfloater.h" -class LLControlGroup; class LLView; -class LLFontGL; - -class LLFloater; class LLPanel; -class LLButton; -class LLCheckBoxCtrl; -class LLComboBox; -class LLIconCtrl; -class LLLineEditor; -class LLMenuGL; -class LLMenuBarGL; -class LLMenuItemCallGL; -class LLNameListCtrl; -class LLPieMenu; -class LLRadioGroup; -class LLSearchEditor; -class LLScrollableContainerView; -class LLScrollListCtrl; -class LLSlider; -class LLSliderCtrl; -class LLSpinCtrl; -class LLTextBox; -class LLTextEditor; -class LLTextureCtrl; -class LLWebBrowserCtrl; -class LLViewBorder; -class LLColorSwatchCtrl; -class LLScrollingPanelList; -class LLCtrlListInterface; -class LLCtrlSelectionInterface; -class LLCtrlScrollInterface; - -// Widget class LLUICtrlFactory { public: LLUICtrlFactory(); // do not call! needs to be public so run-time can clean up the singleton - virtual ~LLUICtrlFactory(); + virtual ~LLUICtrlFactory() {} void setupPaths(); void buildFloater(LLFloater* floaterp, const LLString &filename, - const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE); - + const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE); BOOL buildPanel(LLPanel* panelp, const LLString &filename, const LLCallbackMap::map_t* factory_map = NULL); - LLMenuGL *buildMenu(const LLString &filename, LLView* parentp); + void removePanel(LLPanel* panelp) { mBuiltPanels.erase(panelp->getHandle()); } + void removeFloater(LLFloater* floaterp) { mBuiltFloaters.erase(floaterp->getHandle()); } - LLPieMenu *buildPieMenu(const LLString &filename, LLView* parentp); + class LLMenuGL *buildMenu(const LLString &filename, LLView* parentp); + class LLPieMenu *buildPieMenu(const LLString &filename, LLView* parentp); // Does what you want for LLFloaters and LLPanels // Returns 0 on success S32 saveToXML(LLView* viewp, const LLString& filename); - void removePanel(LLPanel* panelp); - void removeFloater(LLFloater* floaterp); + // Rebuilds all currently built panels. void rebuild(); static EWidgetType getWidgetType(const LLString& ctrl_type); @@ -107,38 +74,44 @@ public: static BOOL getAttributeColor(LLXMLNodePtr node, const LLString& name, LLColor4& color); // specific typed getters - static LLButton* getButtonByName( LLPanel* panelp, const LLString& name); - static LLCheckBoxCtrl* getCheckBoxByName( LLPanel* panelp, const LLString& name); - static LLComboBox* getComboBoxByName( LLPanel* panelp, const LLString& name); - static LLIconCtrl* getIconByName( LLPanel* panelp, const LLString& name); - static LLLineEditor* getLineEditorByName( LLPanel* panelp, const LLString& name); - static LLNameListCtrl* getNameListByName( LLPanel* panelp, const LLString& name); - static LLRadioGroup* getRadioGroupByName( LLPanel* panelp, const LLString& name); - static LLScrollListCtrl* getScrollListByName( LLPanel* panelp, const LLString& name); - static LLSliderCtrl* getSliderByName( LLPanel* panelp, const LLString& name); - static LLSlider* getSliderBarByName( LLPanel* panelp, const LLString& name); - static LLSpinCtrl* getSpinnerByName( LLPanel* panelp, const LLString& name); - static LLTextBox* getTextBoxByName( LLPanel* panelp, const LLString& name); - static LLTextEditor* getTextEditorByName( LLPanel* panelp, const LLString& name); - static LLTabContainerCommon* getTabContainerByName( LLPanel* panelp, const LLString& name); - static LLScrollableContainerView* getScrollableContainerByName(LLPanel* panelp, const LLString& name); - static LLTextureCtrl* getTexturePickerByName( LLPanel* panelp, const LLString& name); - static LLPanel* getPanelByName(LLPanel* panelp, const LLString& name); - static LLColorSwatchCtrl* getColorSwatchByName(LLPanel* panelp, const LLString& name); - static LLWebBrowserCtrl* getWebBrowserCtrlByName(LLPanel* panelp, const LLString& name); - static LLMenuItemCallGL* getMenuItemCallByName(LLPanel* panelp, const LLString& name); - static LLScrollingPanelList* getScrollingPanelList(LLPanel* panelp, const LLString& name); + static class LLButton* getButtonByName( const LLPanel* panelp, const LLString& name); + static class LLCheckBoxCtrl* getCheckBoxByName( const LLPanel* panelp, const LLString& name); + static class LLComboBox* getComboBoxByName( const LLPanel* panelp, const LLString& name); + static class LLIconCtrl* getIconByName( const LLPanel* panelp, const LLString& name); + static class LLLineEditor* getLineEditorByName( const LLPanel* panelp, const LLString& name); + static class LLRadioGroup* getRadioGroupByName( const LLPanel* panelp, const LLString& name); + static class LLScrollListCtrl* getScrollListByName( const LLPanel* panelp, const LLString& name); + static class LLSliderCtrl* getSliderByName( const LLPanel* panelp, const LLString& name); + static class LLSlider* getSliderBarByName( const LLPanel* panelp, const LLString& name); + static class LLSpinCtrl* getSpinnerByName( const LLPanel* panelp, const LLString& name); + static class LLTextBox* getTextBoxByName( const LLPanel* panelp, const LLString& name); + static class LLTextEditor* getTextEditorByName( const LLPanel* panelp, const LLString& name); + static class LLTabContainer* getTabContainerByName( const LLPanel* panelp, const LLString& name); + static class LLScrollableContainerView* getScrollableContainerByName(const LLPanel* panelp, const LLString& name); + static class LLPanel* getPanelByName( const LLPanel* panelp, const LLString& name); + static class LLMenuItemCallGL* getMenuItemCallByName( const LLPanel* panelp, const LLString& name); + static class LLScrollingPanelList* getScrollingPanelList( const LLPanel* panelp, const LLString& name); + static class LLMultiSliderCtrl* getMultiSliderByName( const LLPanel* panelp, const LLString& name); + static class LLMultiSlider* getMultiSliderBarByName(const LLPanel* panelp, const LLString& name); // interface getters - static LLCtrlListInterface* getListInterfaceByName(LLPanel* panelp, const LLString& name); - static LLCtrlSelectionInterface* getSelectionInterfaceByName(LLPanel* panelp, const LLString& name); - static LLCtrlScrollInterface* getScrollInterfaceByName(LLPanel* panelp, const LLString& name); + static LLCtrlListInterface* getListInterfaceByName( const LLPanel* panelp, const LLString& name); + static LLCtrlSelectionInterface* getSelectionInterfaceByName(const LLPanel* panelp, const LLString& name); + static LLCtrlScrollInterface* getScrollInterfaceByName(const LLPanel* panelp, const LLString& name); LLPanel* createFactoryPanel(LLString name); virtual LLView* createCtrlWidget(LLPanel *parent, LLXMLNodePtr node); virtual void createWidget(LLPanel *parent, LLXMLNodePtr node); + template T* createDummyWidget(const LLString& name) + { + return NULL; + //static LLPanel dummy_panel; + //LLXMLNodePtr new_node_ptr = new LLXMLNode(T::getWidgetTag(), FALSE); + //return createWidget(&dummy_panel, new_node_ptr); + } + // Creator library typedef LLView* (*creator_function_t)(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); void registerCreator(LLString ctrlname, creator_function_t function); @@ -147,10 +120,21 @@ public: protected: + template + class LLUICtrlCreator + { + public: + static void registerCreator(LLString name, LLUICtrlFactory *factory) + { + factory->registerCreator(name, T::fromXML); + } + }; + +private: - typedef std::map built_panel_t; + typedef std::map, LLString> built_panel_t; built_panel_t mBuiltPanels; - typedef std::map built_floater_t; + typedef std::map, LLString> built_floater_t; built_floater_t mBuiltFloaters; std::deque mFactoryStack; @@ -162,14 +146,5 @@ protected: static std::vector mXUIPaths; }; -template -class LLUICtrlCreator -{ -public: - static void registerCreator(LLString name, LLUICtrlFactory *factory) - { - factory->registerCreator(name, T::fromXML); - } -}; -#endif //LL_LLWIDGETFACTORY_H +#endif //LLUICTRLFACTORY_H diff --git a/linden/indra/llui/lluifwd.h b/linden/indra/llui/lluifwd.h new file mode 100644 index 0000000..758a0e4 --- /dev/null +++ b/linden/indra/llui/lluifwd.h @@ -0,0 +1,63 @@ +/** + * @file lluifwd.h + * @brief Forward declarations of common LLUI widget types. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLUIFWD_H +#define LLUIFWD_H + +class LLButton; +class LLCheckBoxCtrl; +class LLComboBox; +class LLDragHandle; +class LLFloater; +class LLIconCtrl; +class LLLineEditor; +class LLMenuGL; +class LLPanel; +class LLRadioGroup; +class LLResizeBar; +class LLResizeHandle; +class LLScrollbar; +class LLScrollContainer; +class LLScrollingPanelList; +class LLScrollListCtrl; +class LLSlider; +class LLSliderCtrl; +class LLSpinCtrl; +class LLTabContainer; +class LLTabContainerVertical; +class LLTextBox; +class LLTextEditor; +class LLTextureCtrl; +class LLUICtrl; +class LLView; +class LLViewBorder; + +#endif diff --git a/linden/indra/llui/lluistring.cpp b/linden/indra/llui/lluistring.cpp index d3b5a52..2eb7f28 100644 --- a/linden/indra/llui/lluistring.cpp +++ b/linden/indra/llui/lluistring.cpp @@ -1,6 +1,6 @@ /** * @file lluistring.cpp - * @brief LLUIString base class + * @brief LLUIString implementation. * * $LicenseInfo:firstyear=2006&license=viewergpl$ * @@ -30,14 +30,11 @@ */ #include "linden_common.h" - #include "lluistring.h" const LLString::format_map_t LLUIString::sNullArgs; -// public - LLUIString::LLUIString(const LLString& instring, const LLString::format_map_t& args) : mOrig(instring), mArgs(args) @@ -98,13 +95,6 @@ void LLUIString::clear() mWResult.clear(); } -void LLUIString::clearArgs() -{ - mArgs.clear(); -} - -// private - void LLUIString::format() { mResult = mOrig; diff --git a/linden/indra/llui/lluistring.h b/linden/indra/llui/lluistring.h index 4e9bb55..e8a86f4 100644 --- a/linden/indra/llui/lluistring.h +++ b/linden/indra/llui/lluistring.h @@ -1,7 +1,7 @@ /** * @file lluistring.h * @author: Steve Bennetts - * @brief LLUIString base class + * @brief A fancy wrapper for LLString supporting argument substitutions. * * $LicenseInfo:firstyear=2006&license=viewergpl$ * @@ -33,12 +33,6 @@ #ifndef LL_LLUISTRING_H #define LL_LLUISTRING_H -// lluistring.h -// -// Copyright 2006, Linden Research, Inc. -// Original aurthor: Steve - -#include "stdtypes.h" #include "llstring.h" #include @@ -89,7 +83,7 @@ public: S32 length() const { return mWResult.size(); } void clear(); - void clearArgs(); + void clearArgs() { mArgs.clear(); } // These utuilty functions are included for text editing. // They do not affect mOrig and do not perform argument substitution diff --git a/linden/indra/llui/lluixmltags.h b/linden/indra/llui/lluixmltags.h index 1afcb00..cfc57b1 100644 --- a/linden/indra/llui/lluixmltags.h +++ b/linden/indra/llui/lluixmltags.h @@ -31,94 +31,95 @@ #ifndef LL_UI_XML_TAGS_H #define LL_UI_XML_TAGS_H -#define LL_BUTTON_TAG LLString("button") -#define LL_UI_CTRL_LOCATE_TAG LLString("locate") -#define LL_PAD_TAG LLString("pad") -#define LL_CHECK_BOX_CTRL_TAG LLString("check_box") -#define LL_COMBO_BOX_TAG LLString("combo_box") -#define LL_DRAG_HANDLE_TOP_TAG LLString("drag_handle_top") -#define LL_DRAG_HANDLE_LEFT_TAG LLString("drag_handle_left") -#define LL_FLOATER_TAG LLString("floater") -#define LL_FLOATER_VIEW_TAG LLString("floater_view") -#define LL_MULTI_FLOATER_TAG LLString("multi_floater") -#define LL_ICON_CTRL_TAG LLString("icon") -#define LL_LINE_EDITOR_TAG LLString("line_editor") -#define LL_SEARCH_EDITOR_TAG LLString("search_editor") -#define LL_MENU_ITEM_TAG LLString("menu_item") -#define LL_MENU_GL_TAG LLString("menu") -#define LL_MENU_BAR_GL_TAG LLString("menu_bar") -#define LL_MENU_HOLDER_GL_TAG LLString("menu_holder") -#define LL_PANEL_TAG LLString("panel") -#define LL_RADIO_GROUP_TAG LLString("radio_group") -#define LL_RESIZE_BAR_TAG LLString("resize_bar") -#define LL_RESIZE_HANDLE_TAG LLString("resize_handle") -#define LL_SCROLLBAR_TAG LLString("scrollbar") -#define LL_SCROLLABLE_CONTAINER_VIEW_TAG LLString("scroll_container") -#define LL_SCROLL_LIST_CTRL_TAG LLString("scroll_list") -#define LL_SLIDER_CTRL_TAG LLString("slider") -#define LL_SLIDER_TAG LLString("slider_bar") -#define LL_SPIN_CTRL_TAG LLString("spinner") -#define LL_TAB_CONTAINER_COMMON_TAG LLString("tab_container") -#define LL_TEXT_BOX_TAG LLString("text") -#define LL_TEXT_EDITOR_TAG LLString("text_editor") -#define LL_VIEW_BORDER_TAG LLString("view_border") -#define LL_COLOR_SWATCH_TAG LLString("color_swatch") -#define LL_INVENTORY_PANEL_TAG LLString("inventory_panel") -#define LL_NAME_EDITOR_TAG LLString("name_editor") -#define LL_NAME_LIST_TAG LLString("name_list") -#define LL_TEXTURE_PICKER_TAG LLString("texture_picker") -#define LL_VOLUME_SLIDER_CTRL_TAG LLString("volume_slider") -#define LL_WEB_BROWSER_CTRL_TAG LLString("web_browser") -#define LL_STAT_VIEW_TAG LLString("stat_view") -#define LL_INVENTORY_PANEL_TAG LLString("inventory_panel") -#define LL_PROGRESS_VIEW_TAG LLString("progress_view") -#define LL_STAT_BAR_TAG LLString("stat_bar") -#define LL_STATUS_BAR_TAG LLString("status_bar") -#define LL_VIEWER_TEXT_EDITOR_TAG LLString("viewer_text_editor") -#define LL_TALK_VIEW_TAG LLString("talk_view") -#define LL_COLOR_SWATCH_CTRL_TAG LLString("color_swatch") -#define LL_GL_TEX_MEM_BAR_TAG LLString("tex_mem_bar") -#define LL_TEXTURE_CTRL_TAG LLString("texture_picker") -#define LL_TEXTURE_VIEW_TAG LLString("texture_view") -#define LL_NAME_LIST_CTRL_TAG LLString("name_list") -#define LL_STAT_GRAPH_TAG LLString("stat_graph") -#define LL_NAME_EDITOR_TAG LLString("name_editor") -#define LL_DROP_TARGET_TAG LLString("drop_target") -#define LL_OVERLAY_BAR_TAG LLString("overlay_bar") -#define LL_NET_MAP_TAG LLString("net_map") -#define LL_HUD_VIEW_TAG LLString("hud_view") -#define LL_MEMORY_VIEW_TAG LLString("memory_view") -#define LL_MEDIA_REMOTE_CTRL_TAG LLString("media_remote") -#define LL_MORPH_VIEW_TAG LLString("morph_view") -#define LL_FRAME_STAT_VIEW_TAG LLString("frame_stat_view") -#define LL_FOLDER_VIEW_TAG LLString("folder_view") -#define LL_SNAPSHOT_LIVE_PREVIEW_TAG LLString("snapshot_preview") -#define LL_HOVER_VIEW_TAG LLString("hover_view") -#define LL_VELOCITY_BAR_TAG LLString("velocity_bar") -#define LL_PERMISSIONS_VIEW_TAG LLString("permissions_view") -#define LL_SCROLLING_PANEL_LIST_TAG LLString("scrolling_panel_list") -#define LL_CONTAINER_VIEW_TAG LLString("container_view") -#define LL_CONSOLE_TAG LLString("console") -#define LL_DEBUG_VIEW_TAG LLString("debug_view") -#define LL_AUDIOSTATUS_TAG LLString("audio_status") -#define LL_FAST_TIMER_VIEW_TAG LLString("fast_timer_view") -#define LL_MENU_ITEM_TEAR_OFF_GL_TAG LLString("tearoff_menu") -#define LL_MENU_ITEM_BLANK_GL_TAG LLString("menu_item_blank") -#define LL_MENU_ITEM_CALL_GL_TAG LLString("menu_item_call") -#define LL_MENU_ITEM_CHECK_GL_TAG LLString("menu_item_check") -#define LL_MENU_ITEM_BRANCH_GL_TAG LLString("menu_item_branch") -#define LL_MENU_ITEM_BRANCH_DOWN_GL_TAG LLString("menu_item_branch_down") -#define LL_PIE_MENU_BRANCH_TAG LLString("pie_menu_branch") -#define LL_PIE_MENU_TAG LLString("pie_menu") -#define LL_MENU_ITEM_SEPARATOR_GL_TAG LLString("menu_item_separator") -#define LL_MENU_ITEM_VERTICAL_SEPARATOR_GL_TAG LLString("menu_item_vertical_separator") -#define LL_ROOT_VIEW_TAG LLString("root_view") -#define LL_FOLDER_VIEW_ITEM_TAG LLString("folder_item") -#define LL_FOLDER_VIEW_FOLDER_TAG LLString("folder") -#define LL_TEXTURE_BAR_TAG LLString("texture_bar") -#define LL_JOYSTICK_SLIDE LLString("joystick_slide") -#define LL_JOYSTICK_TURN LLString("joystick_turn") -#define LL_GROUP_DROP_TARGET_TAG LLString("group_drop_target") -#define LL_LAYOUT_STACK_TAG LLString("layout_stack") +const LLString + LL_BUTTON_TAG("button"), + LL_UI_CTRL_LOCATE_TAG("locate"), + LL_PAD_TAG("pad"), + LL_CHECK_BOX_CTRL_TAG("check_box"), + LL_COMBO_BOX_TAG("combo_box"), + LL_DRAG_HANDLE_TOP_TAG("drag_handle_top"), + LL_DRAG_HANDLE_LEFT_TAG("drag_handle_left"), + LL_FLOATER_TAG("floater"), + LL_FLOATER_VIEW_TAG("floater_view"), + LL_MULTI_FLOATER_TAG("multi_floater"), + LL_ICON_CTRL_TAG("icon"), + LL_LINE_EDITOR_TAG("line_editor"), + LL_SEARCH_EDITOR_TAG("search_editor"), + LL_MENU_ITEM_TAG("menu_item"), + LL_MENU_GL_TAG("menu"), + LL_MENU_BAR_GL_TAG("menu_bar"), + LL_MENU_HOLDER_GL_TAG("menu_holder"), + LL_PANEL_TAG("panel"), + LL_RADIO_GROUP_TAG("radio_group"), + LL_RESIZE_BAR_TAG("resize_bar"), + LL_RESIZE_HANDLE_TAG("resize_handle"), + LL_SCROLLBAR_TAG("scrollbar"), + LL_SCROLLABLE_CONTAINER_VIEW_TAG("scroll_container"), + LL_SCROLL_LIST_CTRL_TAG("scroll_list"), + LL_SLIDER_CTRL_TAG("slider"), + LL_SLIDER_TAG("slider_bar"), + LL_MULTI_SLIDER_CTRL_TAG("multi_slider"), + LL_MULTI_SLIDER_TAG("multi_slider_bar"), + LL_SPIN_CTRL_TAG("spinner"), + LL_TAB_CONTAINER_COMMON_TAG("tab_container"), + LL_TEXT_BOX_TAG("text"), + LL_TEXT_EDITOR_TAG("text_editor"), + LL_VIEW_BORDER_TAG("view_border"), + LL_COLOR_SWATCH_TAG("color_swatch"), + LL_INVENTORY_PANEL_TAG("inventory_panel"), + LL_NAME_EDITOR_TAG("name_editor"), + LL_NAME_LIST_TAG("name_list"), + LL_TEXTURE_PICKER_TAG("texture_picker"), + LL_VOLUME_SLIDER_CTRL_TAG("volume_slider"), + LL_WEB_BROWSER_CTRL_TAG("web_browser"), + LL_STAT_VIEW_TAG("stat_view"), + LL_PROGRESS_VIEW_TAG("progress_view"), + LL_STAT_BAR_TAG("stat_bar"), + LL_STATUS_BAR_TAG("status_bar"), + LL_VIEWER_TEXT_EDITOR_TAG("viewer_text_editor"), + LL_TALK_VIEW_TAG("talk_view"), + LL_COLOR_SWATCH_CTRL_TAG("color_swatch"), + LL_GL_TEX_MEM_BAR_TAG("tex_mem_bar"), + LL_TEXTURE_CTRL_TAG("texture_picker"), + LL_TEXTURE_VIEW_TAG("texture_view"), + LL_NAME_LIST_CTRL_TAG("name_list"), + LL_STAT_GRAPH_TAG("stat_graph"), + LL_DROP_TARGET_TAG("drop_target"), + LL_OVERLAY_BAR_TAG("overlay_bar"), + LL_NET_MAP_TAG("net_map"), + LL_HUD_VIEW_TAG("hud_view"), + LL_MEMORY_VIEW_TAG("memory_view"), + LL_MEDIA_REMOTE_CTRL_TAG("media_remote"), + LL_MORPH_VIEW_TAG("morph_view"), + LL_FRAME_STAT_VIEW_TAG("frame_stat_view"), + LL_FOLDER_VIEW_TAG("folder_view"), + LL_SNAPSHOT_LIVE_PREVIEW_TAG("snapshot_preview"), + LL_HOVER_VIEW_TAG("hover_view"), + LL_VELOCITY_BAR_TAG("velocity_bar"), + LL_PERMISSIONS_VIEW_TAG("permissions_view"), + LL_SCROLLING_PANEL_LIST_TAG("scrolling_panel_list"), + LL_CONTAINER_VIEW_TAG("container_view"), + LL_CONSOLE_TAG("console"), + LL_DEBUG_VIEW_TAG("debug_view"), + LL_AUDIOSTATUS_TAG("audio_status"), + LL_FAST_TIMER_VIEW_TAG("fast_timer_view"), + LL_MENU_ITEM_TEAR_OFF_GL_TAG("tearoff_menu"), + LL_MENU_ITEM_BLANK_GL_TAG("menu_item_blank"), + LL_MENU_ITEM_CALL_GL_TAG("menu_item_call"), + LL_MENU_ITEM_CHECK_GL_TAG("menu_item_check"), + LL_MENU_ITEM_BRANCH_GL_TAG("menu_item_branch"), + LL_MENU_ITEM_BRANCH_DOWN_GL_TAG("menu_item_branch_down"), + LL_PIE_MENU_BRANCH_TAG("pie_menu_branch"), + LL_PIE_MENU_TAG("pie_menu"), + LL_MENU_ITEM_SEPARATOR_GL_TAG("menu_item_separator"), + LL_MENU_ITEM_VERTICAL_SEPARATOR_GL_TAG("menu_item_vertical_separator"), + LL_ROOT_VIEW_TAG("root_view"), + LL_FOLDER_VIEW_ITEM_TAG("folder_item"), + LL_FOLDER_VIEW_FOLDER_TAG("folder"), + LL_TEXTURE_BAR_TAG("texture_bar"), + LL_JOYSTICK_SLIDE("joystick_slide"), + LL_JOYSTICK_TURN("joystick_turn"), + LL_GROUP_DROP_TARGET_TAG("group_drop_target"), + LL_LAYOUT_STACK_TAG("layout_stack"); #define LL_FLYOUT_BUTTON_TAG "flyout_button" #endif diff --git a/linden/indra/llui/llundo.cpp b/linden/indra/llui/llundo.cpp index a267ae2..4fdf9d3 100644 --- a/linden/indra/llui/llundo.cpp +++ b/linden/indra/llui/llundo.cpp @@ -1,6 +1,5 @@ /** * @file llundo.cpp - * @brief LLUndo class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -29,12 +28,8 @@ * $/LicenseInfo$ */ -// Generic interface for undo/redo circular buffer - #include "linden_common.h" - #include "llundo.h" -#include "llerror.h" // TODO: @@ -82,7 +77,7 @@ LLUndoBuffer::~LLUndoBuffer() //----------------------------------------------------------------------------- // getNextAction() //----------------------------------------------------------------------------- -LLUndoAction *LLUndoBuffer::getNextAction(BOOL setClusterBegin) +LLUndoBuffer::LLUndoAction* LLUndoBuffer::getNextAction(BOOL setClusterBegin) { LLUndoAction *nextAction = mActions[mNextAction]; diff --git a/linden/indra/llui/llundo.h b/linden/indra/llui/llundo.h index 2bf04bc..6921259 100644 --- a/linden/indra/llui/llundo.h +++ b/linden/indra/llui/llundo.h @@ -1,6 +1,6 @@ /** * @file llundo.h - * @brief LLUndo class header file + * @brief Generic interface for undo/redo circular buffer. * * $LicenseInfo:firstyear=2000&license=viewergpl$ * @@ -32,34 +32,24 @@ #ifndef LL_LLUNDO_H #define LL_LLUNDO_H -class LLUndoAction -{ - friend class LLUndoBuffer; -protected: - S32 mClusterID; -protected: - LLUndoAction(): mClusterID(0) {}; - virtual ~LLUndoAction(){}; - -public: - static LLUndoAction *create() { return NULL; } - - virtual void undo() = 0; - virtual void redo() = 0; - virtual void cleanup() {}; -}; class LLUndoBuffer { -protected: - LLUndoAction **mActions; // array of pointers to undoactions - S32 mNumActions; // total number of actions in ring buffer - S32 mNextAction; // next action to perform undo/redo on - S32 mLastAction; // last action actually added to undo buffer - S32 mFirstAction; // beginning of ring buffer (don't undo any further) - S32 mOperationID; // current operation id, for undoing and redoing in clusters - public: + class LLUndoAction + { + friend class LLUndoBuffer; + public: + virtual void undo() = 0; + virtual void redo() = 0; + virtual void cleanup() {}; + protected: + LLUndoAction(): mClusterID(0) {}; + virtual ~LLUndoAction(){}; + private: + S32 mClusterID; + }; + LLUndoBuffer( LLUndoAction (*create_func()), S32 initial_count ); virtual ~LLUndoBuffer(); @@ -70,6 +60,14 @@ public: BOOL canRedo() { return (mNextAction != mLastAction); } void flushActions(); + +private: + LLUndoAction **mActions; // array of pointers to undoactions + S32 mNumActions; // total number of actions in ring buffer + S32 mNextAction; // next action to perform undo/redo on + S32 mLastAction; // last action actually added to undo buffer + S32 mFirstAction; // beginning of ring buffer (don't undo any further) + S32 mOperationID; // current operation id, for undoing and redoing in clusters }; #endif //LL_LLUNDO_H diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp index 39398b0..fbcb69e 100644 --- a/linden/indra/llui/llview.cpp +++ b/linden/indra/llui/llview.cpp @@ -37,6 +37,7 @@ #include #include +#include "llglimmediate.h" #include "llevent.h" #include "llfontgl.h" #include "llfocusmgr.h" @@ -61,48 +62,11 @@ BOOL LLView::sForceReshape = FALSE; LLView* LLView::sEditingUIView = NULL; S32 LLView::sLastLeftXML = S32_MIN; S32 LLView::sLastBottomXML = S32_MIN; -std::map LLView::sViewHandleMap; - -S32 LLViewHandle::sNextID = 0; -LLViewHandle LLViewHandle::sDeadHandle; #if LL_DEBUG BOOL LLView::sIsDrawing = FALSE; #endif -//static -LLView* LLView::getViewByHandle(LLViewHandle handle) -{ - if (handle == LLViewHandle::sDeadHandle) - { - return NULL; - } - std::map::iterator iter = sViewHandleMap.find(handle); - if (iter != sViewHandleMap.end()) - { - return iter->second; - } - else - { - return NULL; - } -} - -//static -BOOL LLView::deleteViewByHandle(LLViewHandle handle) -{ - std::map::iterator iter = sViewHandleMap.find(handle); - if (iter != sViewHandleMap.end()) - { - delete iter->second; // will remove from map - return TRUE; - } - else - { - return FALSE; - } -} - LLView::LLView() : mParentView(NULL), mReshapeFlags(FOLLOWS_NONE), @@ -115,11 +79,8 @@ LLView::LLView() : mLastVisible(TRUE), mUseBoundingRect(FALSE), mVisible(TRUE), - mHidden(FALSE), mNextInsertionOrdinal(0) { - mViewHandle.init(); - sViewHandleMap[mViewHandle] = this; } LLView::LLView(const LLString& name, BOOL mouse_opaque) : @@ -135,11 +96,8 @@ LLView::LLView(const LLString& name, BOOL mouse_opaque) : mLastVisible(TRUE), mUseBoundingRect(FALSE), mVisible(TRUE), - mHidden(FALSE), mNextInsertionOrdinal(0) { - mViewHandle.init(); - sViewHandleMap[mViewHandle] = this; } @@ -159,11 +117,8 @@ LLView::LLView( mLastVisible(TRUE), mUseBoundingRect(FALSE), mVisible(TRUE), - mHidden(FALSE), mNextInsertionOrdinal(0) { - mViewHandle.init(); - sViewHandleMap[mViewHandle] = this; } @@ -183,8 +138,6 @@ LLView::~LLView() gFocusMgr.removeMouseCaptureWithoutCallback( this ); } - sViewHandleMap.erase(mViewHandle); - deleteAllChildren(); if (mParentView != NULL) @@ -203,7 +156,7 @@ LLView::~LLView() } // virtual -BOOL LLView::isView() +BOOL LLView::isView() const { return TRUE; } @@ -215,16 +168,12 @@ BOOL LLView::isCtrl() const } // virtual -BOOL LLView::isPanel() +BOOL LLView::isPanel() const { return FALSE; } -void LLView::setMouseOpaque(BOOL b) -{ - mMouseOpaque = b; -} - +// virtual void LLView::setToolTip(const LLStringExplicit& msg) { mToolTipMsg = msg; @@ -248,52 +197,6 @@ void LLView::setRect(const LLRect& rect) updateBoundingRect(); } - -void LLView::setFollows(U32 flags) -{ - mReshapeFlags = flags; -} - -void LLView::setFollowsNone() -{ - mReshapeFlags = FOLLOWS_NONE; -} - -void LLView::setFollowsLeft() -{ - mReshapeFlags |= FOLLOWS_LEFT; -} - -void LLView::setFollowsTop() -{ - mReshapeFlags |= FOLLOWS_TOP; -} - -void LLView::setFollowsRight() -{ - mReshapeFlags |= FOLLOWS_RIGHT; -} - -void LLView::setFollowsBottom() -{ - mReshapeFlags |= FOLLOWS_BOTTOM; -} - -void LLView::setFollowsAll() -{ - mReshapeFlags |= FOLLOWS_ALL; -} - -void LLView::setSoundFlags(U8 flags) -{ - mSoundFlags = flags; -} - -void LLView::setName(LLString name) -{ - mName = name; -} - void LLView::setUseBoundingRect( BOOL use_bounding_rect ) { if (mUseBoundingRect != use_bounding_rect) @@ -308,11 +211,6 @@ BOOL LLView::getUseBoundingRect() return mUseBoundingRect; } -const LLString& LLView::getToolTip() -{ - return mToolTipMsg.getString(); -} - // virtual const LLString& LLView::getName() const { @@ -452,8 +350,6 @@ void LLView::removeCtrl(LLUICtrl* ctrl) } } -S32 LLView::getDefaultTabGroup() const { return mDefaultTabGroup; } - LLView::ctrl_list_t LLView::getCtrlList() const { ctrl_list_t controls; @@ -476,12 +372,6 @@ LLView::ctrl_list_t LLView::getCtrlListSorted() const return controls; } -LLCompareByTabOrder::LLCompareByTabOrder(LLView::child_tab_order_t order): mTabOrder(order) {} - -bool LLCompareByTabOrder::compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const -{ - return a < b; -} // This method compares two LLViews by the tab order specified in the comparator object. The // code for this is a little convoluted because each argument can have four states: @@ -537,68 +427,69 @@ BOOL LLView::isInEnabledChain() const return TRUE; } -BOOL LLView::isFocusRoot() const +// virtual +BOOL LLView::canFocusChildren() const { - return mIsFocusRoot; + return TRUE; } -LLView* LLView::findRootMostFocusRoot() +//virtual +void LLView::setTentative(BOOL b) { - LLView* focus_root = NULL; - LLView* next_view = this; - while(next_view) - { - if (next_view->isFocusRoot()) - { - focus_root = next_view; - } - next_view = next_view->getParent(); - } - return focus_root; } -BOOL LLView::canFocusChildren() const +//virtual +BOOL LLView::getTentative() const { - return TRUE; + return FALSE; } -BOOL LLView::focusNextRoot() +//virtual +void LLView::setEnabled(BOOL enabled) { - LLView::child_list_t result = LLView::getFocusRootsQuery().run(this); - return LLView::focusNext(result); + mEnabled = enabled; } -BOOL LLView::focusPrevRoot() +//virtual +BOOL LLView::setLabelArg( const LLString& key, const LLStringExplicit& text ) { - LLView::child_list_t result = LLView::getFocusRootsQuery().run(this); - return LLView::focusPrev(result); + return FALSE; } -BOOL LLView::focusNextItem(BOOL text_fields_only) +//virtual +LLRect LLView::getSnapRect() const { - // this assumes that this method is called on the focus root. - LLCtrlQuery query = LLView::getTabOrderQuery(); - if(text_fields_only || LLUI::sConfigGroup->getBOOL("TabToTextFieldsOnly")) - { - query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); - } - LLView::child_list_t result = query(this); + return mRect; +} + +//virtual +LLRect LLView::getRequiredRect() +{ + return mRect; +} + +//virtual +void LLView::onFocusLost() +{ +} + +//virtual +void LLView::onFocusReceived() +{ +} + +BOOL LLView::focusNextRoot() +{ + LLView::child_list_t result = LLView::getFocusRootsQuery().run(this); return LLView::focusNext(result); } -BOOL LLView::focusPrevItem(BOOL text_fields_only) +BOOL LLView::focusPrevRoot() { - // this assumes that this method is called on the focus root. - LLCtrlQuery query = LLView::getTabOrderQuery(); - if(text_fields_only || LLUI::sConfigGroup->getBOOL("TabToTextFieldsOnly")) - { - query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); - } - LLView::child_list_t result = query(this); + LLView::child_list_t result = LLView::getFocusRootsQuery().run(this); return LLView::focusPrev(result); } - // static BOOL LLView::focusNext(LLView::child_list_t & result) { @@ -674,80 +565,6 @@ BOOL LLView::focusPrev(LLView::child_list_t & result) return FALSE; } -BOOL LLView::focusFirstItem(BOOL prefer_text_fields) -{ - // search for text field first - if(prefer_text_fields) - { - LLCtrlQuery query = LLView::getTabOrderQuery(); - query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); - LLView::child_list_t result = query(this); - if(result.size() > 0) - { - LLUICtrl * ctrl = static_cast(result.front()); - if(!ctrl->hasFocus()) - { - ctrl->setFocus(TRUE); - ctrl->onTabInto(); - gFocusMgr.triggerFocusFlash(); - } - return TRUE; - } - } - // no text field found, or we don't care about text fields - LLView::child_list_t result = LLView::getTabOrderQuery().run(this); - if(result.size() > 0) - { - LLUICtrl * ctrl = static_cast(result.front()); - if(!ctrl->hasFocus()) - { - ctrl->setFocus(TRUE); - ctrl->onTabInto(); - gFocusMgr.triggerFocusFlash(); - } - return TRUE; - } - return FALSE; -} - -BOOL LLView::focusLastItem(BOOL prefer_text_fields) -{ - // search for text field first - if(prefer_text_fields) - { - LLCtrlQuery query = LLView::getTabOrderQuery(); - query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance()); - LLView::child_list_t result = query(this); - if(result.size() > 0) - { - LLUICtrl * ctrl = static_cast(result.back()); - if(!ctrl->hasFocus()) - { - ctrl->setFocus(TRUE); - ctrl->onTabInto(); - gFocusMgr.triggerFocusFlash(); - } - return TRUE; - } - } - // no text field found, or we don't care about text fields - LLView::child_list_t result = LLView::getTabOrderQuery().run(this); - if(result.size() > 0) - { - LLUICtrl * ctrl = static_cast(result.back()); - if(!ctrl->hasFocus()) - { - ctrl->setFocus(TRUE); - ctrl->onTabInto(); - gFocusMgr.triggerFocusFlash(); - } - return TRUE; - } - return FALSE; -} - - - // delete all children. Override this function if you need to // perform any extra clean up such as cached pointers to selected // children, etc. @@ -773,23 +590,6 @@ void LLView::setAllChildrenEnabled(BOOL b) } // virtual -void LLView::setTentative(BOOL b) -{ -} - -// virtual -BOOL LLView::getTentative() const -{ - return FALSE; -} - -// virtual -void LLView::setEnabled(BOOL enabled) -{ - mEnabled = enabled; -} - -// virtual void LLView::setVisible(BOOL visible) { if ( mVisible != visible ) @@ -812,18 +612,6 @@ void LLView::setVisible(BOOL visible) } // virtual -void LLView::setHidden(BOOL hidden) -{ - mHidden = hidden; -} - -// virtual -BOOL LLView::setLabelArg(const LLString& key, const LLStringExplicit& text) -{ - return FALSE; -} - -// virtual void LLView::onVisibilityChange ( BOOL new_visibility ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) @@ -845,9 +633,9 @@ void LLView::translate(S32 x, S32 y) } // virtual -BOOL LLView::canSnapTo(LLView* other_view) +BOOL LLView::canSnapTo(const LLView* other_view) const { - return other_view->getVisible(); + return other_view != this && other_view->getVisible(); } // virtual @@ -956,7 +744,7 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent) if( called_from_parent ) { // Downward traversal - if (getVisible() && mEnabled) + if (getVisible() && getEnabled()) { handled = childrenHandleKey( key, mask ) != NULL; } @@ -995,7 +783,7 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) if( called_from_parent ) { // Downward traversal - if (getVisible() && mEnabled) + if (getVisible() && getEnabled()) { handled = childrenHandleUnicodeChar( uni_char ) != NULL; } @@ -1058,16 +846,16 @@ LLView* LLView::childrenHandleDragAndDrop(S32 x, S32 y, MASK mask, LLView* handled_view = FALSE; // CRO this is an experiment to allow drag and drop into object inventory based on the DragAndDrop tool's permissions rather than the parent if( getVisible() ) -// if( getVisible() && mEnabled ) +// if( getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if( viewp->pointInView(local_x, local_y) && viewp->getVisible() && - viewp->mEnabled && + viewp->getEnabled() && viewp->handleDragAndDrop(local_x, local_y, mask, drop, cargo_type, cargo_data, @@ -1142,7 +930,7 @@ BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask) BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks) { BOOL handled = FALSE; - if( getVisible() && mEnabled ) + if( getVisible() && getEnabled() ) { handled = childrenHandleScrollWheel( x, y, clicks ) != NULL; if( !handled && blockMouseEvent(x, y) ) @@ -1176,13 +964,13 @@ BOOL LLView::handleRightMouseUp(S32 x, S32 y, MASK mask) LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) { LLView* handled_view = NULL; - if (getVisible() && mEnabled ) + if (getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if (viewp->pointInView(local_x, local_y) && viewp->handleScrollWheel( local_x, local_y, clicks )) { @@ -1202,13 +990,13 @@ LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask) { LLView* handled_view = NULL; - if (getVisible() && mEnabled ) + if (getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if(viewp->pointInView(local_x, local_y) && viewp->getVisible() && viewp->getEnabled() && @@ -1232,7 +1020,7 @@ LLView* LLView::childrenHandleKey(KEY key, MASK mask) { LLView* handled_view = NULL; - if ( getVisible() && mEnabled ) + if ( getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { @@ -1257,7 +1045,7 @@ LLView* LLView::childrenHandleUnicodeChar(llwchar uni_char) { LLView* handled_view = NULL; - if ( getVisible() && mEnabled ) + if ( getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { @@ -1284,12 +1072,12 @@ LLView* LLView::childrenHandleMouseDown(S32 x, S32 y, MASK mask) for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if (viewp->pointInView(local_x, local_y) && viewp->getVisible() && - viewp->mEnabled && + viewp->getEnabled() && viewp->handleMouseDown( local_x, local_y, mask )) { if (sDebugMouseHandling) @@ -1307,16 +1095,16 @@ LLView* LLView::childrenHandleRightMouseDown(S32 x, S32 y, MASK mask) { LLView* handled_view = NULL; - if (getVisible() && mEnabled ) + if (getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if (viewp->pointInView(local_x, local_y) && viewp->getVisible() && - viewp->mEnabled && + viewp->getEnabled() && viewp->handleRightMouseDown( local_x, local_y, mask )) { if (sDebugMouseHandling) @@ -1335,16 +1123,16 @@ LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask) { LLView* handled_view = NULL; - if (getVisible() && mEnabled ) + if (getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if (viewp->pointInView(local_x, local_y) && viewp->getVisible() && - viewp->mEnabled && + viewp->getEnabled() && viewp->handleDoubleClick( local_x, local_y, mask )) { if (sDebugMouseHandling) @@ -1362,18 +1150,18 @@ LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask) LLView* LLView::childrenHandleMouseUp(S32 x, S32 y, MASK mask) { LLView* handled_view = NULL; - if( getVisible() && mEnabled ) + if( getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if (!viewp->pointInView(local_x, local_y)) continue; if (!viewp->getVisible()) continue; - if (!viewp->mEnabled) + if (!viewp->getEnabled()) continue; if (viewp->handleMouseUp( local_x, local_y, mask )) { @@ -1392,16 +1180,16 @@ LLView* LLView::childrenHandleMouseUp(S32 x, S32 y, MASK mask) LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask) { LLView* handled_view = NULL; - if( getVisible() && mEnabled ) + if( getVisible() && getEnabled() ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { LLView* viewp = *child_it; - S32 local_x = x - viewp->mRect.mLeft; - S32 local_y = y - viewp->mRect.mBottom; + S32 local_x = x - viewp->getRect().mLeft; + S32 local_y = y - viewp->getRect().mBottom; if (viewp->pointInView(local_x, local_y) && viewp->getVisible() && - viewp->mEnabled && + viewp->getEnabled() && viewp->handleRightMouseUp( local_x, local_y, mask )) { if (sDebugMouseHandling) @@ -1424,8 +1212,8 @@ void LLView::draw() drawDebugRect(); // Check for bogus rectangle - if (mRect.mRight <= mRect.mLeft - || mRect.mTop <= mRect.mBottom) + if (getRect().mRight <= getRect().mLeft + || getRect().mTop <= getRect().mBottom) { llwarns << "Bogus rectangle for " << getName() << " with " << mRect << llendl; } @@ -1503,28 +1291,28 @@ void LLView::drawDebugRect() border_color.mV[sDepth%3] = 1.f; } - glColor4fv( border_color.mV ); + gGL.color4fv( border_color.mV ); - glBegin(GL_LINES); - glVertex2i(0, debug_rect.getHeight() - 1); - glVertex2i(0, 0); + gGL.begin(GL_LINES); + gGL.vertex2i(0, debug_rect.getHeight() - 1); + gGL.vertex2i(0, 0); - glVertex2i(0, 0); - glVertex2i(debug_rect.getWidth() - 1, 0); + gGL.vertex2i(0, 0); + gGL.vertex2i(debug_rect.getWidth() - 1, 0); - glVertex2i(debug_rect.getWidth() - 1, 0); - glVertex2i(debug_rect.getWidth() - 1, debug_rect.getHeight() - 1); + gGL.vertex2i(debug_rect.getWidth() - 1, 0); + gGL.vertex2i(debug_rect.getWidth() - 1, debug_rect.getHeight() - 1); - glVertex2i(debug_rect.getWidth() - 1, debug_rect.getHeight() - 1); - glVertex2i(0, debug_rect.getHeight() - 1); - glEnd(); + gGL.vertex2i(debug_rect.getWidth() - 1, debug_rect.getHeight() - 1); + gGL.vertex2i(0, debug_rect.getHeight() - 1); + gGL.end(); // Draw the name if it's not a leaf node if (mChildList.size() && !sEditingUI) { //char temp[256]; S32 x, y; - glColor4fv( border_color.mV ); + gGL.color4fv( border_color.mV ); x = debug_rect.getWidth()/2; y = debug_rect.getHeight()/2; LLString debug_text = llformat("%s (%d x %d)", getName().c_str(), @@ -1562,14 +1350,14 @@ void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_dr void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) { // compute how much things changed and apply reshape logic to children - S32 delta_width = width - mRect.getWidth(); - S32 delta_height = height - mRect.getHeight(); + S32 delta_width = width - getRect().getWidth(); + S32 delta_height = height - getRect().getHeight(); if (delta_width || delta_height || sForceReshape) { // adjust our rectangle - mRect.mRight = mRect.mLeft + width; - mRect.mTop = mRect.mBottom + height; + mRect.mRight = getRect().mLeft + width; + mRect.mTop = getRect().mBottom + height; // move child views according to reshape flags for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) @@ -1615,8 +1403,8 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) // for now, same as bottom } - S32 delta_x = child_rect.mLeft - viewp->mRect.mLeft; - S32 delta_y = child_rect.mBottom - viewp->mRect.mBottom; + S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft; + S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom; viewp->translate( delta_x, delta_y ); viewp->reshape(child_rect.getWidth(), child_rect.getHeight()); } @@ -1633,11 +1421,6 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) updateBoundingRect(); } -LLRect LLView::getRequiredRect() -{ - return mRect; -} - void LLView::updateBoundingRect() { if (isDead()) return; @@ -1690,16 +1473,16 @@ void LLView::updateBoundingRect() } } -const LLRect LLView::getScreenRect() const +LLRect LLView::getScreenRect() const { // *FIX: check for one-off error LLRect screen_rect; localPointToScreen(0, 0, &screen_rect.mLeft, &screen_rect.mBottom); - localPointToScreen(mRect.getWidth(), mRect.getHeight(), &screen_rect.mRight, &screen_rect.mTop); + localPointToScreen(getRect().getWidth(), getRect().getHeight(), &screen_rect.mRight, &screen_rect.mTop); return screen_rect; } -const LLRect LLView::getLocalBoundingRect() const +LLRect LLView::getLocalBoundingRect() const { LLRect local_bounding_rect = getBoundingRect(); local_bounding_rect.translate(-mRect.mLeft, -mRect.mBottom); @@ -1708,20 +1491,20 @@ const LLRect LLView::getLocalBoundingRect() const } -const LLRect LLView::getLocalRect() const +LLRect LLView::getLocalRect() const { - LLRect local_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect local_rect(0, getRect().getHeight(), getRect().getWidth(), 0); return local_rect; } -const LLRect LLView::getLocalSnapRect() const +LLRect LLView::getLocalSnapRect() const { LLRect local_snap_rect = getSnapRect(); - local_snap_rect.translate(-mRect.mLeft, -mRect.mBottom); + local_snap_rect.translate(-getRect().mLeft, -getRect().mBottom); return local_snap_rect; } -BOOL LLView::hasAncestor(const LLView* parentp) +BOOL LLView::hasAncestor(const LLView* parentp) const { if (!parentp) { @@ -1760,7 +1543,7 @@ BOOL LLView::childHasKeyboardFocus( const LLString& childname ) const BOOL LLView::hasChild(const LLString& childname, BOOL recurse) const { - return getChildByName(childname, recurse) ? TRUE : FALSE; + return getChildByName(childname, recurse) != NULL; } //----------------------------------------------------------------------------- @@ -1818,55 +1601,55 @@ BOOL LLView::blockMouseEvent(S32 x, S32 y) const // virtual void LLView::screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const { - *local_x = screen_x - mRect.mLeft; - *local_y = screen_y - mRect.mBottom; + *local_x = screen_x - getRect().mLeft; + *local_y = screen_y - getRect().mBottom; const LLView* cur = this; while( cur->mParentView ) { cur = cur->mParentView; - *local_x -= cur->mRect.mLeft; - *local_y -= cur->mRect.mBottom; + *local_x -= cur->getRect().mLeft; + *local_y -= cur->getRect().mBottom; } } void LLView::localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const { - *screen_x = local_x + mRect.mLeft; - *screen_y = local_y + mRect.mBottom; + *screen_x = local_x + getRect().mLeft; + *screen_y = local_y + getRect().mBottom; const LLView* cur = this; while( cur->mParentView ) { cur = cur->mParentView; - *screen_x += cur->mRect.mLeft; - *screen_y += cur->mRect.mBottom; + *screen_x += cur->getRect().mLeft; + *screen_y += cur->getRect().mBottom; } } void LLView::screenRectToLocal(const LLRect& screen, LLRect* local) const { *local = screen; - local->translate( -mRect.mLeft, -mRect.mBottom ); + local->translate( -getRect().mLeft, -getRect().mBottom ); const LLView* cur = this; while( cur->mParentView ) { cur = cur->mParentView; - local->translate( -cur->mRect.mLeft, -cur->mRect.mBottom ); + local->translate( -cur->getRect().mLeft, -cur->getRect().mBottom ); } } void LLView::localRectToScreen(const LLRect& local, LLRect* screen) const { *screen = local; - screen->translate( mRect.mLeft, mRect.mBottom ); + screen->translate( getRect().mLeft, getRect().mBottom ); const LLView* cur = this; while( cur->mParentView ) { cur = cur->mParentView; - screen->translate( cur->mRect.mLeft, cur->mRect.mBottom ); + screen->translate( cur->getRect().mLeft, cur->getRect().mBottom ); } } @@ -1880,12 +1663,15 @@ LLView* LLView::getRootView() return view; } -//static -LLWindow* LLView::getWindow(void) +BOOL LLView::deleteViewByHandle(LLHandle handle) { - return LLUI::sWindow; + LLView* viewp = handle.get(); + + delete viewp; + return viewp != NULL; } + // Moves the view so that it is entirely inside of constraint. // If the view will not fit because it's too big, aligns with the top and left. // (Why top and left? That's where the drag bars are for floaters.) @@ -1898,50 +1684,50 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs { const S32 KEEP_ONSCREEN_PIXELS = 16; - if( mRect.mRight - KEEP_ONSCREEN_PIXELS < constraint.mLeft ) + if( getRect().mRight - KEEP_ONSCREEN_PIXELS < constraint.mLeft ) { - delta_x = constraint.mLeft - (mRect.mRight - KEEP_ONSCREEN_PIXELS); + delta_x = constraint.mLeft - (getRect().mRight - KEEP_ONSCREEN_PIXELS); } else - if( mRect.mLeft + KEEP_ONSCREEN_PIXELS > constraint.mRight ) + if( getRect().mLeft + KEEP_ONSCREEN_PIXELS > constraint.mRight ) { - delta_x = constraint.mRight - (mRect.mLeft + KEEP_ONSCREEN_PIXELS); - delta_x += llmax( 0, mRect.getWidth() - constraint.getWidth() ); + delta_x = constraint.mRight - (getRect().mLeft + KEEP_ONSCREEN_PIXELS); + delta_x += llmax( 0, getRect().getWidth() - constraint.getWidth() ); } - if( mRect.mTop > constraint.mTop ) + if( getRect().mTop > constraint.mTop ) { - delta_y = constraint.mTop - mRect.mTop; + delta_y = constraint.mTop - getRect().mTop; } else - if( mRect.mTop - KEEP_ONSCREEN_PIXELS < constraint.mBottom ) + if( getRect().mTop - KEEP_ONSCREEN_PIXELS < constraint.mBottom ) { - delta_y = constraint.mBottom - (mRect.mTop - KEEP_ONSCREEN_PIXELS); - delta_y -= llmax( 0, mRect.getHeight() - constraint.getHeight() ); + delta_y = constraint.mBottom - (getRect().mTop - KEEP_ONSCREEN_PIXELS); + delta_y -= llmax( 0, getRect().getHeight() - constraint.getHeight() ); } } else { - if( mRect.mLeft < constraint.mLeft ) + if( getRect().mLeft < constraint.mLeft ) { - delta_x = constraint.mLeft - mRect.mLeft; + delta_x = constraint.mLeft - getRect().mLeft; } else - if( mRect.mRight > constraint.mRight ) + if( getRect().mRight > constraint.mRight ) { - delta_x = constraint.mRight - mRect.mRight; - delta_x += llmax( 0, mRect.getWidth() - constraint.getWidth() ); + delta_x = constraint.mRight - getRect().mRight; + delta_x += llmax( 0, getRect().getWidth() - constraint.getWidth() ); } - if( mRect.mTop > constraint.mTop ) + if( getRect().mTop > constraint.mTop ) { - delta_y = constraint.mTop - mRect.mTop; + delta_y = constraint.mTop - getRect().mTop; } else - if( mRect.mBottom < constraint.mBottom ) + if( getRect().mBottom < constraint.mBottom ) { - delta_y = constraint.mBottom - mRect.mBottom; - delta_y -= llmax( 0, mRect.getHeight() - constraint.getHeight() ); + delta_y = constraint.mBottom - getRect().mBottom; + delta_y -= llmax( 0, getRect().getHeight() - constraint.getHeight() ); } } @@ -1953,10 +1739,18 @@ BOOL LLView::translateIntoRect(const LLRect& constraint, BOOL allow_partial_outs return FALSE; } -BOOL LLView::localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view) +void LLView::centerWithin(const LLRect& bounds) { - LLView* cur_view = this; - LLView* root_view = NULL; + S32 left = bounds.mLeft + (bounds.getWidth() - getRect().getWidth()) / 2; + S32 bottom = bounds.mBottom + (bounds.getHeight() - getRect().getHeight()) / 2; + + translate( left - getRect().mLeft, bottom - getRect().mBottom ); +} + +BOOL LLView::localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view) const +{ + const LLView* cur_view = this; + const LLView* root_view = NULL; while (cur_view) { @@ -2047,8 +1841,8 @@ LLXMLNodePtr LLView::getXML(bool save_children) const node->createChild("height", TRUE)->setIntValue(getRect().getHeight()); LLView* parent = getParent(); - S32 left = mRect.mLeft; - S32 bottom = mRect.mBottom; + S32 left = getRect().mLeft; + S32 bottom = getRect().mBottom; if (parent) bottom -= parent->getRect().getHeight(); node->createChild("left", TRUE)->setIntValue(left); @@ -2084,7 +1878,6 @@ LLXMLNodePtr LLView::getXML(bool save_children) const node->createChild("follows", TRUE)->setStringValue(buffer.str()); } // Export all widgets as enabled and visible - code must disable. - node->createChild("hidden", TRUE)->setBoolValue(mHidden); node->createChild("mouse_opaque", TRUE)->setBoolValue(mMouseOpaque ); if (!mToolTipMsg.getString().empty()) { @@ -2095,7 +1888,7 @@ LLXMLNodePtr LLView::getXML(bool save_children) const node->createChild("sound_flags", TRUE)->setIntValue((S32)mSoundFlags); } - node->createChild("enabled", TRUE)->setBoolValue(mEnabled); + node->createChild("enabled", TRUE)->setBoolValue(getEnabled()); if (!mControlName.empty()) { @@ -2183,6 +1976,15 @@ const LLCtrlQuery & LLView::getTabOrderQuery() return query; } +// This class is only used internally by getFocusRootsQuery below. +class LLFocusRootsFilter : public LLQueryFilter, public LLSingleton +{ + /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const + { + return filterResult_t(view->isCtrl() && view->isFocusRoot(), !view->isFocusRoot()); + } +}; + // static const LLCtrlQuery & LLView::getFocusRootsQuery() { @@ -2190,7 +1992,7 @@ const LLCtrlQuery & LLView::getFocusRootsQuery() if(query.getPreFilters().size() == 0) { query.addPreFilter(LLVisibleFilter::getInstance()); query.addPreFilter(LLEnabledFilter::getInstance()); - query.addPreFilter(LLView::LLFocusRootsFilter::getInstance()); + query.addPreFilter(LLFocusRootsFilter::getInstance()); query.addPostFilter(LLRootsFilter::getInstance()); } return query; @@ -2200,167 +2002,189 @@ const LLCtrlQuery & LLView::getFocusRootsQuery() void LLView::userSetShape(const LLRect& new_rect) { reshape(new_rect.getWidth(), new_rect.getHeight()); - translate(new_rect.mLeft - mRect.mLeft, new_rect.mBottom - mRect.mBottom); + translate(new_rect.mLeft - getRect().mLeft, new_rect.mBottom - getRect().mBottom); } LLView* LLView::findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding) { + new_rect = mRect; LLView* snap_view = NULL; if (!mParentView) { - new_rect = mRect; - return snap_view; + return NULL; } - - // If the view is near the edge of its parent, snap it to - // the edge. - LLRect test_rect = getSnapRect(); - LLRect view_rect = getSnapRect(); - test_rect.stretch(padding); - view_rect.stretch(padding); - - BOOL snapped_x = FALSE; - BOOL snapped_y = FALSE; - - LLRect parent_local_snap_rect = mParentView->getLocalSnapRect(); - - if (snap_type == SNAP_PARENT || snap_type == SNAP_PARENT_AND_SIBLINGS) + + S32 delta_x = 0; + S32 delta_y = 0; + if (mouse_dir.mX >= 0) { - if (llabs(parent_local_snap_rect.mRight - test_rect.mRight) <= threshold && (parent_local_snap_rect.mRight - test_rect.mRight) * mouse_dir.mX >= 0) - { - view_rect.translate(parent_local_snap_rect.mRight - view_rect.mRight, 0); - snap_view = mParentView; - snapped_x = TRUE; - } - - if (llabs(test_rect.mLeft - parent_local_snap_rect.mLeft) <= threshold && test_rect.mLeft * mouse_dir.mX <= 0) - { - view_rect.translate(parent_local_snap_rect.mLeft - view_rect.mLeft, 0); - snap_view = mParentView; - snapped_x = TRUE; - } - - if (llabs(test_rect.mBottom - parent_local_snap_rect.mBottom) <= threshold && test_rect.mBottom * mouse_dir.mY <= 0) - { - view_rect.translate(0, parent_local_snap_rect.mBottom - view_rect.mBottom); - snap_view = mParentView; - snapped_y = TRUE; - } - - if (llabs(parent_local_snap_rect.mTop - test_rect.mTop) <= threshold && (parent_local_snap_rect.mTop - test_rect.mTop) * mouse_dir.mY >= 0) - { - view_rect.translate(0, parent_local_snap_rect.mTop - view_rect.mTop); - snap_view = mParentView; - snapped_y = TRUE; - } + S32 new_right = mRect.mRight; + LLView* view = findSnapEdge(new_right, mouse_dir, SNAP_RIGHT, snap_type, threshold, padding); + delta_x = new_right - mRect.mRight; + snap_view = view ? view : snap_view; } - if (snap_type == SNAP_SIBLINGS || snap_type == SNAP_PARENT_AND_SIBLINGS) - { - for ( child_list_const_iter_t child_it = mParentView->getChildList()->begin(); - child_it != mParentView->getChildList()->end(); ++child_it) - { - LLView* siblingp = *child_it; - // skip self - if (siblingp == this || !siblingp->getVisible() || !canSnapTo(siblingp)) - { - continue; - } - - LLRect sibling_rect = siblingp->getSnapRect(); - - if (!snapped_x && llabs(test_rect.mRight - sibling_rect.mLeft) <= threshold && (test_rect.mRight - sibling_rect.mLeft) * mouse_dir.mX <= 0) - { - view_rect.translate(sibling_rect.mLeft - view_rect.mRight, 0); - if (!snapped_y) - { - if (llabs(test_rect.mTop - sibling_rect.mTop) <= threshold && (test_rect.mTop - sibling_rect.mTop) * mouse_dir.mY <= 0) - { - view_rect.translate(0, sibling_rect.mTop - test_rect.mTop); - snapped_y = TRUE; - } - else if (llabs(test_rect.mBottom - sibling_rect.mBottom) <= threshold && (test_rect.mBottom - sibling_rect.mBottom) * mouse_dir.mY <= 0) - { - view_rect.translate(0, sibling_rect.mBottom - test_rect.mBottom); - snapped_y = TRUE; - } - } - snap_view = siblingp; - snapped_x = TRUE; - } - if (!snapped_x && llabs(test_rect.mLeft - sibling_rect.mRight) <= threshold && (test_rect.mLeft - sibling_rect.mRight) * mouse_dir.mX <= 0) - { - view_rect.translate(sibling_rect.mRight - view_rect.mLeft, 0); - if (!snapped_y) - { - if (llabs(test_rect.mTop - sibling_rect.mTop) <= threshold && (test_rect.mTop - sibling_rect.mTop) * mouse_dir.mY <= 0) - { - view_rect.translate(0, sibling_rect.mTop - test_rect.mTop); - snapped_y = TRUE; - } - else if (llabs(test_rect.mBottom - sibling_rect.mBottom) <= threshold && (test_rect.mBottom - sibling_rect.mBottom) * mouse_dir.mY <= 0) - { - view_rect.translate(0, sibling_rect.mBottom - test_rect.mBottom); - snapped_y = TRUE; - } - } - snap_view = siblingp; - snapped_x = TRUE; - } + if (mouse_dir.mX <= 0) + { + S32 new_left = mRect.mLeft; + LLView* view = findSnapEdge(new_left, mouse_dir, SNAP_LEFT, snap_type, threshold, padding); + delta_x = new_left - mRect.mLeft; + snap_view = view ? view : snap_view; + } - if (!snapped_y && llabs(test_rect.mBottom - sibling_rect.mTop) <= threshold && (test_rect.mBottom - sibling_rect.mTop) * mouse_dir.mY <= 0) - { - view_rect.translate(0, sibling_rect.mTop - view_rect.mBottom); - if (!snapped_x) - { - if (llabs(test_rect.mLeft - sibling_rect.mLeft) <= threshold && (test_rect.mLeft - sibling_rect.mLeft) * mouse_dir.mX <= 0) - { - view_rect.translate(sibling_rect.mLeft - test_rect.mLeft, 0); - snapped_x = TRUE; - } - else if (llabs(test_rect.mRight - sibling_rect.mRight) <= threshold && (test_rect.mRight - sibling_rect.mRight) * mouse_dir.mX <= 0) - { - view_rect.translate(sibling_rect.mRight - test_rect.mRight, 0); - snapped_x = TRUE; - } - } - snap_view = siblingp; - snapped_y = TRUE; - } + if (mouse_dir.mY >= 0) + { + S32 new_top = mRect.mTop; + LLView* view = findSnapEdge(new_top, mouse_dir, SNAP_TOP, snap_type, threshold, padding); + delta_y = new_top - mRect.mTop; + snap_view = view ? view : snap_view; + } - if (!snapped_y && llabs(test_rect.mTop - sibling_rect.mBottom) <= threshold && (test_rect.mTop - sibling_rect.mBottom) * mouse_dir.mY <= 0) - { - view_rect.translate(0, sibling_rect.mBottom - view_rect.mTop); - if (!snapped_x) - { - if (llabs(test_rect.mLeft - sibling_rect.mLeft) <= threshold && (test_rect.mLeft - sibling_rect.mLeft) * mouse_dir.mX <= 0) - { - view_rect.translate(sibling_rect.mLeft - test_rect.mLeft, 0); - snapped_x = TRUE; - } - else if (llabs(test_rect.mRight - sibling_rect.mRight) <= threshold && (test_rect.mRight - sibling_rect.mRight) * mouse_dir.mX <= 0) - { - view_rect.translate(sibling_rect.mRight - test_rect.mRight, 0); - snapped_x = TRUE; - } - } - snap_view = siblingp; - snapped_y = TRUE; - } - - if (snapped_x && snapped_y) - { - break; - } - } + if (mouse_dir.mY <= 0) + { + S32 new_bottom = mRect.mBottom; + LLView* view = findSnapEdge(new_bottom, mouse_dir, SNAP_BOTTOM, snap_type, threshold, padding); + delta_y = new_bottom - mRect.mBottom; + snap_view = view ? view : snap_view; } - // shrink actual view rect back down - view_rect.stretch(-padding); - new_rect = view_rect; + new_rect.translate(delta_x, delta_y); return snap_view; + + //// If the view is near the edge of its parent, snap it to + //// the edge. + //LLRect test_rect = getSnapRect(); + //LLRect view_rect = getSnapRect(); + //test_rect.stretch(padding); + //view_rect.stretch(padding); + + //S32 x_threshold = threshold; + //S32 y_threshold = threshold; + + //LLRect parent_local_snap_rect = mParentView->getLocalSnapRect(); + + //if (snap_type == SNAP_PARENT || snap_type == SNAP_PARENT_AND_SIBLINGS) + //{ + // if (llabs(parent_local_snap_rect.mRight - test_rect.mRight) <= x_threshold && (parent_local_snap_rect.mRight - test_rect.mRight) * mouse_dir.mX >= 0) + // { + // view_rect.translate(parent_local_snap_rect.mRight - view_rect.mRight, 0); + // snap_view = mParentView; + // x_threshold = llabs(parent_local_snap_rect.mRight - test_rect.mRight); + // } + + // if (llabs(test_rect.mLeft - parent_local_snap_rect.mLeft) <= x_threshold && test_rect.mLeft * mouse_dir.mX <= 0) + // { + // view_rect.translate(parent_local_snap_rect.mLeft - view_rect.mLeft, 0); + // snap_view = mParentView; + // x_threshold = llabs(test_rect.mLeft - parent_local_snap_rect.mLeft); + // } + + // if (llabs(test_rect.mBottom - parent_local_snap_rect.mBottom) <= y_threshold && test_rect.mBottom * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, parent_local_snap_rect.mBottom - view_rect.mBottom); + // snap_view = mParentView; + // y_threshold = llabs(test_rect.mBottom - parent_local_snap_rect.mBottom); + // } + + // if (llabs(parent_local_snap_rect.mTop - test_rect.mTop) <= y_threshold && (parent_local_snap_rect.mTop - test_rect.mTop) * mouse_dir.mY >= 0) + // { + // view_rect.translate(0, parent_local_snap_rect.mTop - view_rect.mTop); + // snap_view = mParentView; + // y_threshold = llabs(parent_local_snap_rect.mTop - test_rect.mTop); + // } + //} + //if (snap_type == SNAP_SIBLINGS || snap_type == SNAP_PARENT_AND_SIBLINGS) + //{ + // for ( child_list_const_iter_t child_it = mParentView->getChildList()->begin(); + // child_it != mParentView->getChildList()->end(); ++child_it) + // { + // LLView* siblingp = *child_it; + + // // skip non-snappable views (self, invisible views, etc) + // if (!canSnapTo(siblingp)) continue; + + // LLRect sibling_rect = siblingp->getSnapRect(); + + // if (llabs(test_rect.mRight - sibling_rect.mLeft) <= x_threshold + // && (test_rect.mRight - sibling_rect.mLeft) * mouse_dir.mX <= 0) + // { + // view_rect.translate(sibling_rect.mLeft - view_rect.mRight, 0); + // if (llabs(test_rect.mTop - sibling_rect.mTop) <= y_threshold && (test_rect.mTop - sibling_rect.mTop) * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, sibling_rect.mTop - test_rect.mTop); + // y_threshold = llabs(test_rect.mTop - sibling_rect.mTop); + // } + // else if (llabs(test_rect.mBottom - sibling_rect.mBottom) <= y_threshold && (test_rect.mBottom - sibling_rect.mBottom) * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, sibling_rect.mBottom - test_rect.mBottom); + // y_threshold = llabs(test_rect.mBottom - sibling_rect.mBottom); + // } + // snap_view = siblingp; + // x_threshold = llabs(test_rect.mRight - sibling_rect.mLeft); + // } + + // if (llabs(test_rect.mLeft - sibling_rect.mRight) <= x_threshold + // && (test_rect.mLeft - sibling_rect.mRight) * mouse_dir.mX <= 0) + // { + // view_rect.translate(sibling_rect.mRight - view_rect.mLeft, 0); + // if (llabs(test_rect.mTop - sibling_rect.mTop) <= y_threshold && (test_rect.mTop - sibling_rect.mTop) * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, sibling_rect.mTop - test_rect.mTop); + // y_threshold = llabs(test_rect.mTop - sibling_rect.mTop); + // } + // else if (llabs(test_rect.mBottom - sibling_rect.mBottom) <= y_threshold && (test_rect.mBottom - sibling_rect.mBottom) * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, sibling_rect.mBottom - test_rect.mBottom); + // y_threshold = llabs(test_rect.mBottom - sibling_rect.mBottom); + // } + // snap_view = siblingp; + // x_threshold = llabs(test_rect.mLeft - sibling_rect.mRight); + // } + + // if (llabs(test_rect.mBottom - sibling_rect.mTop) <= y_threshold + // && (test_rect.mBottom - sibling_rect.mTop) * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, sibling_rect.mTop - view_rect.mBottom); + // if (llabs(test_rect.mLeft - sibling_rect.mLeft) <= x_threshold && (test_rect.mLeft - sibling_rect.mLeft) * mouse_dir.mX <= 0) + // { + // view_rect.translate(sibling_rect.mLeft - test_rect.mLeft, 0); + // x_threshold = llabs(test_rect.mLeft - sibling_rect.mLeft); + // } + // else if (llabs(test_rect.mRight - sibling_rect.mRight) <= x_threshold && (test_rect.mRight - sibling_rect.mRight) * mouse_dir.mX <= 0) + // { + // view_rect.translate(sibling_rect.mRight - test_rect.mRight, 0); + // x_threshold = llabs(test_rect.mRight - sibling_rect.mRight); + // } + // snap_view = siblingp; + // y_threshold = llabs(test_rect.mBottom - sibling_rect.mTop); + // } + + // if (llabs(test_rect.mTop - sibling_rect.mBottom) <= y_threshold + // && (test_rect.mTop - sibling_rect.mBottom) * mouse_dir.mY <= 0) + // { + // view_rect.translate(0, sibling_rect.mBottom - view_rect.mTop); + // if (llabs(test_rect.mLeft - sibling_rect.mLeft) <= x_threshold && (test_rect.mLeft - sibling_rect.mLeft) * mouse_dir.mX <= 0) + // { + // view_rect.translate(sibling_rect.mLeft - test_rect.mLeft, 0); + // x_threshold = llabs(test_rect.mLeft - sibling_rect.mLeft); + // } + // else if (llabs(test_rect.mRight - sibling_rect.mRight) <= x_threshold && (test_rect.mRight - sibling_rect.mRight) * mouse_dir.mX <= 0) + // { + // view_rect.translate(sibling_rect.mRight - test_rect.mRight, 0); + // x_threshold = llabs(test_rect.mRight - sibling_rect.mRight); + // } + // snap_view = siblingp; + // y_threshold = llabs(test_rect.mTop - sibling_rect.mBottom); + // } + // } + //} + + //// shrink actual view rect back down + //view_rect.stretch(-padding); + //new_rect = view_rect; + //return snap_view; } LLView* LLView::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding) @@ -2396,8 +2220,8 @@ LLView* LLView::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESna LLRect test_rect = snap_rect; test_rect.stretch(padding); - BOOL snapped_x = FALSE; - BOOL snapped_y = FALSE; + S32 x_threshold = threshold; + S32 y_threshold = threshold; LLRect parent_local_snap_rect = mParentView->getLocalSnapRect(); @@ -2406,35 +2230,38 @@ LLView* LLView::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESna switch(snap_edge) { case SNAP_RIGHT: - if (llabs(parent_local_snap_rect.mRight - test_rect.mRight) <= threshold && (parent_local_snap_rect.mRight - test_rect.mRight) * mouse_dir.mX >= 0) + if (llabs(parent_local_snap_rect.mRight - test_rect.mRight) <= x_threshold + && (parent_local_snap_rect.mRight - test_rect.mRight) * mouse_dir.mX >= 0) { snap_pos = parent_local_snap_rect.mRight - padding; snap_view = mParentView; - snapped_x = TRUE; + x_threshold = llabs(parent_local_snap_rect.mRight - test_rect.mRight); } break; case SNAP_LEFT: - if (llabs(test_rect.mLeft - parent_local_snap_rect.mLeft) <= threshold && test_rect.mLeft * mouse_dir.mX <= 0) + if (llabs(test_rect.mLeft - parent_local_snap_rect.mLeft) <= x_threshold + && test_rect.mLeft * mouse_dir.mX <= 0) { snap_pos = parent_local_snap_rect.mLeft + padding; snap_view = mParentView; - snapped_x = TRUE; + x_threshold = llabs(test_rect.mLeft - parent_local_snap_rect.mLeft); } break; case SNAP_BOTTOM: - if (llabs(test_rect.mBottom - parent_local_snap_rect.mBottom) <= threshold && test_rect.mBottom * mouse_dir.mY <= 0) + if (llabs(test_rect.mBottom - parent_local_snap_rect.mBottom) <= y_threshold + && test_rect.mBottom * mouse_dir.mY <= 0) { snap_pos = parent_local_snap_rect.mBottom + padding; snap_view = mParentView; - snapped_y = TRUE; + y_threshold = llabs(test_rect.mBottom - parent_local_snap_rect.mBottom); } break; case SNAP_TOP: - if (llabs(parent_local_snap_rect.mTop - test_rect.mTop) <= threshold && (parent_local_snap_rect.mTop - test_rect.mTop) * mouse_dir.mY >= 0) + if (llabs(parent_local_snap_rect.mTop - test_rect.mTop) <= y_threshold && (parent_local_snap_rect.mTop - test_rect.mTop) * mouse_dir.mY >= 0) { snap_pos = parent_local_snap_rect.mTop - padding; snap_view = mParentView; - snapped_y = TRUE; + y_threshold = llabs(parent_local_snap_rect.mTop - test_rect.mTop); } break; default: @@ -2448,111 +2275,100 @@ LLView* LLView::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESna child_it != mParentView->getChildList()->end(); ++child_it) { LLView* siblingp = *child_it; - // skip self - if (siblingp == this || !siblingp->getVisible() || !canSnapTo(siblingp)) - { - continue; - } + + if (!canSnapTo(siblingp)) continue; LLRect sibling_rect = siblingp->getSnapRect(); switch(snap_edge) { case SNAP_RIGHT: - if (!snapped_x) + if (llabs(test_rect.mRight - sibling_rect.mLeft) <= x_threshold + && (test_rect.mRight - sibling_rect.mLeft) * mouse_dir.mX <= 0) { - if (llabs(test_rect.mRight - sibling_rect.mLeft) <= threshold && (test_rect.mRight - sibling_rect.mLeft) * mouse_dir.mX <= 0) + snap_pos = sibling_rect.mLeft - padding; + snap_view = siblingp; + x_threshold = llabs(test_rect.mRight - sibling_rect.mLeft); + } + // if snapped with sibling along other axis, check for shared edge + else if (llabs(sibling_rect.mTop - (test_rect.mBottom - padding)) <= y_threshold + || llabs(sibling_rect.mBottom - (test_rect.mTop + padding)) <= x_threshold) + { + if (llabs(test_rect.mRight - sibling_rect.mRight) <= x_threshold + && (test_rect.mRight - sibling_rect.mRight) * mouse_dir.mX <= 0) { - snap_pos = sibling_rect.mLeft - padding; + snap_pos = sibling_rect.mRight; snap_view = siblingp; - snapped_x = TRUE; - } - // if snapped with sibling along other axis, check for shared edge - else if (llabs(sibling_rect.mTop - (test_rect.mBottom - padding)) <= threshold || - llabs(sibling_rect.mBottom - (test_rect.mTop + padding)) <= threshold) - { - if (llabs(test_rect.mRight - sibling_rect.mRight) <= threshold && (test_rect.mRight - sibling_rect.mRight) * mouse_dir.mX <= 0) - { - snap_pos = sibling_rect.mRight; - snap_view = siblingp; - snapped_x = TRUE; - } + x_threshold = llabs(test_rect.mRight - sibling_rect.mRight); } } break; case SNAP_LEFT: - if (!snapped_x) + if (llabs(test_rect.mLeft - sibling_rect.mRight) <= x_threshold + && (test_rect.mLeft - sibling_rect.mRight) * mouse_dir.mX <= 0) + { + snap_pos = sibling_rect.mRight + padding; + snap_view = siblingp; + x_threshold = llabs(test_rect.mLeft - sibling_rect.mRight); + } + // if snapped with sibling along other axis, check for shared edge + else if (llabs(sibling_rect.mTop - (test_rect.mBottom - padding)) <= y_threshold + || llabs(sibling_rect.mBottom - (test_rect.mTop + padding)) <= y_threshold) { - if (llabs(test_rect.mLeft - sibling_rect.mRight) <= threshold && (test_rect.mLeft - sibling_rect.mRight) * mouse_dir.mX <= 0) + if (llabs(test_rect.mLeft - sibling_rect.mLeft) <= x_threshold + && (test_rect.mLeft - sibling_rect.mLeft) * mouse_dir.mX <= 0) { - snap_pos = sibling_rect.mRight + padding; + snap_pos = sibling_rect.mLeft; snap_view = siblingp; - snapped_x = TRUE; - } - // if snapped with sibling along other axis, check for shared edge - else if (llabs(sibling_rect.mTop - (test_rect.mBottom - padding)) <= threshold || - llabs(sibling_rect.mBottom - (test_rect.mTop + padding)) <= threshold) - { - if (llabs(test_rect.mLeft - sibling_rect.mLeft) <= threshold && (test_rect.mLeft - sibling_rect.mLeft) * mouse_dir.mX <= 0) - { - snap_pos = sibling_rect.mLeft; - snap_view = siblingp; - snapped_x = TRUE; - } + x_threshold = llabs(test_rect.mLeft - sibling_rect.mLeft); } } break; case SNAP_BOTTOM: - if (!snapped_y) + if (llabs(test_rect.mBottom - sibling_rect.mTop) <= y_threshold + && (test_rect.mBottom - sibling_rect.mTop) * mouse_dir.mY <= 0) { - if (llabs(test_rect.mBottom - sibling_rect.mTop) <= threshold && (test_rect.mBottom - sibling_rect.mTop) * mouse_dir.mY <= 0) + snap_pos = sibling_rect.mTop + padding; + snap_view = siblingp; + y_threshold = llabs(test_rect.mBottom - sibling_rect.mTop); + } + // if snapped with sibling along other axis, check for shared edge + else if (llabs(sibling_rect.mRight - (test_rect.mLeft - padding)) <= x_threshold + || llabs(sibling_rect.mLeft - (test_rect.mRight + padding)) <= x_threshold) + { + if (llabs(test_rect.mBottom - sibling_rect.mBottom) <= y_threshold + && (test_rect.mBottom - sibling_rect.mBottom) * mouse_dir.mY <= 0) { - snap_pos = sibling_rect.mTop + padding; + snap_pos = sibling_rect.mBottom; snap_view = siblingp; - snapped_y = TRUE; - } - // if snapped with sibling along other axis, check for shared edge - else if (llabs(sibling_rect.mRight - (test_rect.mLeft - padding)) <= threshold || - llabs(sibling_rect.mLeft - (test_rect.mRight + padding)) <= threshold) - { - if (llabs(test_rect.mBottom - sibling_rect.mBottom) <= threshold && (test_rect.mBottom - sibling_rect.mBottom) * mouse_dir.mY <= 0) - { - snap_pos = sibling_rect.mBottom; - snap_view = siblingp; - snapped_y = TRUE; - } + y_threshold = llabs(test_rect.mBottom - sibling_rect.mBottom); } } break; case SNAP_TOP: - if (!snapped_y) + if (llabs(test_rect.mTop - sibling_rect.mBottom) <= y_threshold + && (test_rect.mTop - sibling_rect.mBottom) * mouse_dir.mY <= 0) + { + snap_pos = sibling_rect.mBottom - padding; + snap_view = siblingp; + y_threshold = llabs(test_rect.mTop - sibling_rect.mBottom); + } + // if snapped with sibling along other axis, check for shared edge + else if (llabs(sibling_rect.mRight - (test_rect.mLeft - padding)) <= x_threshold + || llabs(sibling_rect.mLeft - (test_rect.mRight + padding)) <= x_threshold) { - if (llabs(test_rect.mTop - sibling_rect.mBottom) <= threshold && (test_rect.mTop - sibling_rect.mBottom) * mouse_dir.mY <= 0) + if (llabs(test_rect.mTop - sibling_rect.mTop) <= y_threshold + && (test_rect.mTop - sibling_rect.mTop) * mouse_dir.mY <= 0) { - snap_pos = sibling_rect.mBottom - padding; + snap_pos = sibling_rect.mTop; snap_view = siblingp; - snapped_y = TRUE; - } - // if snapped with sibling along other axis, check for shared edge - else if (llabs(sibling_rect.mRight - (test_rect.mLeft - padding)) <= threshold || - llabs(sibling_rect.mLeft - (test_rect.mRight + padding)) <= threshold) - { - if (llabs(test_rect.mTop - sibling_rect.mTop) <= threshold && (test_rect.mTop - sibling_rect.mTop) * mouse_dir.mY <= 0) - { - snap_pos = sibling_rect.mTop; - snap_view = siblingp; - snapped_y = TRUE; - } + y_threshold = llabs(test_rect.mTop - sibling_rect.mTop); } } break; default: llerrs << "Invalid snap edge" << llendl; } - if (snapped_x && snapped_y) - { - break; - } } } @@ -2560,21 +2376,6 @@ LLView* LLView::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESna return snap_view; } -bool operator==(const LLViewHandle& lhs, const LLViewHandle& rhs) -{ - return lhs.mID == rhs.mID; -} - -bool operator!=(const LLViewHandle& lhs, const LLViewHandle& rhs) -{ - return lhs.mID != rhs.mID; -} - -bool operator<(const LLViewHandle &lhs, const LLViewHandle &rhs) -{ - return lhs.mID < rhs.mID; -} - //----------------------------------------------------------------------------- // Listener dispatch functions //----------------------------------------------------------------------------- @@ -2865,13 +2666,6 @@ void LLView::initFromXML(LLXMLNodePtr node, LLView* parent) setVisible(visible); } - if (node->hasAttribute("hidden")) - { - BOOL hidden; - node->getAttributeBOOL("hidden", hidden); - setHidden(hidden); - } - node->getAttributeBOOL("use_bounding_rect", mUseBoundingRect); node->getAttributeBOOL("mouse_opaque", mMouseOpaque); @@ -3003,12 +2797,6 @@ void LLView::setControlValue(const LLSD& value) } //virtual -LLString LLView::getControlName() const -{ - return mControlName; -} - -//virtual void LLView::setControlName(const LLString& control_name, LLView *context) { if (context == NULL) @@ -3047,11 +2835,6 @@ bool LLView::handleEvent(LLPointer event, const LLSD& userdata) return FALSE; } -void LLView::setValue(const LLSD& value) -{ -} - - void LLView::addBoolControl(LLString name, bool initial_value) { mFloaterControls[name] = new LLControl(name, TYPE_BOOLEAN, initial_value, "Internal floater control"); @@ -3066,3 +2849,14 @@ LLControlBase *LLView::getControl(LLString name) } return NULL; } + +//virtual +void LLView::setValue(const LLSD& value) +{ +} + +//virtual +LLSD LLView::getValue() const +{ + return LLSD(); +} diff --git a/linden/indra/llui/llview.h b/linden/indra/llui/llview.h index 67a4d56..52c7e3d 100644 --- a/linden/indra/llui/llview.h +++ b/linden/indra/llui/llview.h @@ -52,10 +52,6 @@ #include "stdenums.h" #include "lluistring.h" -class LLColor4; -class LLWindow; -class LLUICtrl; -class LLScrollListItem; const U32 FOLLOWS_NONE = 0x00; const U32 FOLLOWS_LEFT = 0x01; @@ -69,29 +65,90 @@ const BOOL NOT_MOUSE_OPAQUE = FALSE; const U32 GL_NAME_UI_RESERVED = 2; -class LLSimpleListener; -class LLEventDispatcher; -class LLViewHandle -{ -public: - LLViewHandle() { mID = 0; } - - void init() { mID = ++sNextID; } - void markDead() { mID = 0; } - BOOL isDead() { return (mID == 0); } - friend bool operator==(const LLViewHandle& lhs, const LLViewHandle& rhs); - friend bool operator!=(const LLViewHandle& lhs, const LLViewHandle& rhs); - friend bool operator<(const LLViewHandle &a, const LLViewHandle &b); - -public: - static LLViewHandle sDeadHandle; +/* +// virtual functions defined in LLView: + +virtual BOOL isCtrl() const; + LLUICtrl +virtual BOOL isPanel(); + LLPanel +virtual void setRect(const LLRect &rect); + LLLineEditor +virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group); +virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group); +virtual void removeCtrl( LLUICtrl* ctrl); + LLPanel +virtual BOOL canFocusChildren() const { return TRUE; } + LLFolderView +virtual void deleteAllChildren(); + LLFolderView, LLPanelInventory +virtual void setTentative(BOOL b) {} + LLUICtrl, LLSliderCtrl, LLSpinCtrl +virtual BOOL getTentative() const { return FALSE; } + LLUICtrl, LLCheckBoxCtrl +virtual void setVisible(BOOL visible); + LLFloater, LLAlertDialog, LLMenuItemGL, LLModalDialog +virtual void setEnabled(BOOL enabled) { mEnabled = enabled; } + LLCheckBoxCtrl, LLComboBox, LLLineEditor, LLMenuGL, LLRadioGroup, etc +virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ) { return FALSE; } + LLUICtrl, LLButton, LLCheckBoxCtrl, LLLineEditor, LLMenuGL, LLSliderCtrl +virtual void onVisibilityChange ( BOOL curVisibilityIn ); + LLMenuGL +virtual LLRect getSnapRect() const { return mRect; } *TODO: Make non virtual + LLFloater +virtual LLRect getRequiredRect() { return mRect; } + LLScrolllistCtrl +virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + LLUICtrl, et. al. +virtual void translate( S32 x, S32 y ); + LLMenuGL +virtual void userSetShape(const LLRect& new_rect); + LLFloater, LLScrollLIstVtrl +virtual LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0); +virtual LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0); + LLScrollListCtrl +virtual BOOL canSnapTo(const LLView* other_view) const { return other_view != this && other_view->getVisible(); } + LLFloater +virtual void snappedTo(LLView* snap_view) {} + LLFloater +virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); + * +virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); + * +virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,EDragAndDropType cargo_type,void* cargo_data,EAcceptance* accept,LLString& tooltip_msg); + * +virtual void draw(); + * +virtual EWidgetType getWidgetType() const = 0; + * +virtual LLString getWidgetTag() const = 0; + * +virtual LLXMLNodePtr getXML(bool save_children = true) const; + * +virtual void initFromXML(LLXMLNodePtr node, LLView* parent); + * +virtual void onFocusLost() {} + LLUICtrl, LLScrollListCtrl, LLMenuGL, LLLineEditor, LLComboBox +virtual void onFocusReceived() {} + LLUICtrl, LLTextEditor, LLScrollListVtrl, LLMenuGL, LLLineEditor +virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; + LLTabContainer, LLPanel, LLMenuGL +virtual void setControlName(const LLString& control, LLView *context); + LLSliderCtrl, LLCheckBoxCtrl +virtual LLString getControlName() const { return mControlName; } + LLSliderCtrl, LLCheckBoxCtrl +virtual bool handleEvent(LLPointer event, const LLSD& userdata); + LLMenuItem +virtual void setValue(const LLSD& value); + * protected: - S32 mID; - - static S32 sNextID; -}; +virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); + * +virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); + * +*/ class LLView : public LLMouseHandler, public LLMortician, public LLSimpleListenerObservable { @@ -128,7 +185,7 @@ public: typedef child_list_t::reverse_iterator child_list_reverse_iter_t; typedef child_list_t::const_reverse_iterator child_list_const_reverse_iter_t; - typedef std::vector ctrl_list_t; + typedef std::vector ctrl_list_t; typedef std::pair tab_order_t; typedef std::pair tab_order_pair_t; @@ -139,105 +196,48 @@ public: typedef child_tab_order_t::reverse_iterator child_tab_order_reverse_iter_t; typedef child_tab_order_t::const_reverse_iterator child_tab_order_const_reverse_iter_t; -private: - LLView* mParentView; - child_list_t mChildList; - -protected: - LLString mName; - // location in pixels, relative to surrounding structure, bottom,left=0,0 - LLRect mRect; - LLRect mBoundingRect; - - U32 mReshapeFlags; - - child_tab_order_t mCtrlOrder; - S32 mDefaultTabGroup; - - BOOL mEnabled; // Enabled means "accepts input that has an effect on the state of the application." - // A disabled view, for example, may still have a scrollbar that responds to mouse events. - BOOL mMouseOpaque; // Opaque views handle all mouse events that are over their rect. - LLUIString mToolTipMsg; // isNull() is true if none. - - U8 mSoundFlags; - BOOL mSaveToXML; - - BOOL mIsFocusRoot; - BOOL mUseBoundingRect; // hit test against bounding rectangle that includes all child elements - -public: - LLViewHandle mViewHandle; - BOOL mLastVisible; - -private: - BOOL mVisible; - BOOL mHidden; // Never show (generally for replacement text only) - - S32 mNextInsertionOrdinal; - -protected: - static LLWindow* sWindow; // All root views must know about their window. - -public: - static BOOL sDebugRects; // Draw debug rects behind everything. - static BOOL sDebugKeys; - static S32 sDepth; - static BOOL sDebugMouseHandling; - static LLString sMouseHandlerMessage; - static S32 sSelectID; - static BOOL sEditingUI; - static LLView* sEditingUIView; - static S32 sLastLeftXML; - static S32 sLastBottomXML; - static std::map sViewHandleMap; - static BOOL sForceReshape; - -public: - static LLView* getViewByHandle(LLViewHandle handle); - static BOOL deleteViewByHandle(LLViewHandle handle); - -public: LLView(); LLView(const LLString& name, BOOL mouse_opaque); LLView(const LLString& name, const LLRect& rect, BOOL mouse_opaque, U32 follows=FOLLOWS_NONE); virtual ~LLView(); - // Hack to support LLFocusMgr - virtual BOOL isView(); + // Hack to support LLFocusMgr (from LLMouseHandler) + /*virtual*/ BOOL isView() const; // Some UI widgets need to be added as controls. Others need to // be added as regular view children. isCtrl should return TRUE // if a widget needs to be added as a ctrl virtual BOOL isCtrl() const; - virtual BOOL isPanel(); + virtual BOOL isPanel() const; // // MANIPULATORS // - void setMouseOpaque( BOOL b ); + void setMouseOpaque( BOOL b ) { mMouseOpaque = b; } + BOOL getMouseOpaque() const { return mMouseOpaque; } void setToolTip( const LLStringExplicit& msg ); BOOL setToolTipArg( const LLStringExplicit& key, const LLStringExplicit& text ); void setToolTipArgs( const LLString::format_map_t& args ); virtual void setRect(const LLRect &rect); - void setFollows(U32 flags); + void setFollows(U32 flags) { mReshapeFlags = flags; } // deprecated, use setFollows() with FOLLOWS_LEFT | FOLLOWS_TOP, etc. - void setFollowsNone(); - void setFollowsLeft(); - void setFollowsTop(); - void setFollowsRight(); - void setFollowsBottom(); - void setFollowsAll(); - - void setSoundFlags(U8 flags); - void setName(LLString name); + void setFollowsNone() { mReshapeFlags = FOLLOWS_NONE; } + void setFollowsLeft() { mReshapeFlags |= FOLLOWS_LEFT; } + void setFollowsTop() { mReshapeFlags |= FOLLOWS_TOP; } + void setFollowsRight() { mReshapeFlags |= FOLLOWS_RIGHT; } + void setFollowsBottom() { mReshapeFlags |= FOLLOWS_BOTTOM; } + void setFollowsAll() { mReshapeFlags |= FOLLOWS_ALL; } + + void setSoundFlags(U8 flags) { mSoundFlags = flags; } + void setName(LLString name) { mName = name; } void setUseBoundingRect( BOOL use_bounding_rect ); BOOL getUseBoundingRect(); - const LLString& getToolTip(); + const LLString& getToolTip() const { return mToolTipMsg.getString(); } void sendChildToFront(LLView* child); void sendChildToBack(LLView* child); @@ -253,61 +253,47 @@ public: virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group); virtual void removeCtrl( LLUICtrl* ctrl); - child_tab_order_t getCtrlOrder() const { return mCtrlOrder; } + child_tab_order_t getCtrlOrder() const { return mCtrlOrder; } ctrl_list_t getCtrlList() const; ctrl_list_t getCtrlListSorted() const; - S32 getDefaultTabGroup() const; + + void setDefaultTabGroup(S32 d) { mDefaultTabGroup = d; } + S32 getDefaultTabGroup() const { return mDefaultTabGroup; } BOOL isInVisibleChain() const; BOOL isInEnabledChain() const; - BOOL isFocusRoot() const; - LLView* findRootMostFocusRoot(); + void setFocusRoot(BOOL b) { mIsFocusRoot = b; } + BOOL isFocusRoot() const { return mIsFocusRoot; } virtual BOOL canFocusChildren() const; - class LLFocusRootsFilter : public LLQueryFilter, public LLSingleton - { - /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const - { - return filterResult_t(view->isCtrl() && view->isFocusRoot(), TRUE); - } - }; - - virtual BOOL focusNextRoot(); - virtual BOOL focusPrevRoot(); - - virtual BOOL focusNextItem(BOOL text_entry_only); - virtual BOOL focusPrevItem(BOOL text_entry_only); - virtual BOOL focusFirstItem(BOOL prefer_text_fields = FALSE ); - virtual BOOL focusLastItem(BOOL prefer_text_fields = FALSE); + BOOL focusNextRoot(); + BOOL focusPrevRoot(); // delete all children. Override this function if you need to // perform any extra clean up such as cached pointers to selected // children, etc. virtual void deleteAllChildren(); - // by default, does nothing virtual void setTentative(BOOL b); - // by default, returns false virtual BOOL getTentative() const; - virtual void setAllChildrenEnabled(BOOL b); + void setAllChildrenEnabled(BOOL b); - virtual void setEnabled(BOOL enabled); virtual void setVisible(BOOL visible); - virtual void setHidden(BOOL hidden); // Never show (replacement text) + BOOL getVisible() const { return mVisible; } + virtual void setEnabled(BOOL enabled); + BOOL getEnabled() const { return mEnabled; } + U8 getSoundFlags() const { return mSoundFlags; } - // by default, does nothing and returns false virtual BOOL setLabelArg( const LLString& key, const LLStringExplicit& text ); virtual void onVisibilityChange ( BOOL curVisibilityIn ); void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); } void popVisible() { setVisible(mLastVisible); mLastVisible = TRUE; } + + LLHandle getHandle() { mHandle.bind(this); return mHandle; } - // - // ACCESSORS - // - BOOL getMouseOpaque() const { return mMouseOpaque; } U32 getFollows() const { return mReshapeFlags; } BOOL followsLeft() const { return mReshapeFlags & FOLLOWS_LEFT; } @@ -318,26 +304,26 @@ public: const LLRect& getRect() const { return mRect; } const LLRect& getBoundingRect() const { return mBoundingRect; } - const LLRect getLocalBoundingRect() const; - const LLRect getScreenRect() const; - const LLRect getLocalRect() const; - virtual const LLRect getSnapRect() const { return mRect; } - virtual const LLRect getLocalSnapRect() const; - - virtual LLRect getRequiredRect(); // Get required size for this object. 0 for width/height means don't care. + LLRect getLocalBoundingRect() const; + LLRect getScreenRect() const; + LLRect getLocalRect() const; + virtual LLRect getSnapRect() const; + LLRect getLocalSnapRect() const; + + // Override and return required size for this object. 0 for width/height means don't care. + virtual LLRect getRequiredRect(); void updateBoundingRect(); LLView* getRootView(); LLView* getParent() const { return mParentView; } - LLView* getFirstChild() { return (mChildList.empty()) ? NULL : *(mChildList.begin()); } + LLView* getFirstChild() const { return (mChildList.empty()) ? NULL : *(mChildList.begin()); } S32 getChildCount() const { return (S32)mChildList.size(); } template void sortChildren(_Pr3 _Pred) { mChildList.sort(_Pred); } - BOOL hasAncestor(const LLView* parentp); - + BOOL hasAncestor(const LLView* parentp) const; BOOL hasChild(const LLString& childname, BOOL recurse = FALSE) const; - BOOL childHasKeyboardFocus( const LLString& childname ) const; + // // UTILITIES // @@ -345,15 +331,15 @@ public: // Default behavior is to use reshape flags to resize child views virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); virtual void translate( S32 x, S32 y ); - virtual void setOrigin( S32 x, S32 y ) { mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); } + void setOrigin( S32 x, S32 y ) { mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); } BOOL translateIntoRect( const LLRect& constraint, BOOL allow_partial_outside ); + void centerWithin(const LLRect& bounds); virtual void userSetShape(const LLRect& new_rect); virtual LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0); virtual LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0); - // Defaults to other_view->getVisible() - virtual BOOL canSnapTo(LLView* other_view); + virtual BOOL canSnapTo(const LLView* other_view) const; virtual void snappedTo(LLView* snap_view); @@ -365,49 +351,97 @@ public: EAcceptance* accept, LLString& tooltip_msg); - // LLMouseHandler functions - // Default behavior is to pass events to children - - /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); - /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ void onMouseCaptureLost(); - /*virtual*/ BOOL hasMouseCapture(); - - // Default behavior is to pass the tooltip event to children, - // then display mToolTipMsg if no child handled it. - /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect); - LLString getShowNamesToolTip(); virtual void draw(); - void drawDebugRect(); - void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE); - - virtual const LLString& getName() const; - virtual EWidgetType getWidgetType() const = 0; virtual LLString getWidgetTag() const = 0; virtual LLXMLNodePtr getXML(bool save_children = true) const; - static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect()); virtual void initFromXML(LLXMLNodePtr node, LLView* parent); void parseFollowsFlags(LLXMLNodePtr node); + // Some widgets, like close box buttons, don't need to be saved + BOOL getSaveToXML() const { return mSaveToXML; } + void setSaveToXML(BOOL b) { mSaveToXML = b; } + + virtual void onFocusLost(); + virtual void onFocusReceived(); + + typedef enum e_hit_test_type + { + HIT_TEST_USE_BOUNDING_RECT, + HIT_TEST_IGNORE_BOUNDING_RECT + }EHitTestType; + + BOOL parentPointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const; + BOOL pointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const; + BOOL blockMouseEvent(S32 x, S32 y) const; + + // See LLMouseHandler virtuals for screenPointToLocal and localPointToScreen + BOOL localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view) const; + BOOL localRectToOtherView( const LLRect& local, LLRect* other, LLView* other_view ) const; + void screenRectToLocal( const LLRect& screen, LLRect* local ) const; + void localRectToScreen( const LLRect& local, LLRect* screen ) const; + + // Listener dispatching functions (Dispatcher deletes pointers to listeners on deregistration or destruction) + LLSimpleListener* getListenerByName(const LLString &callback_name); + void registerEventListener(LLString name, LLSimpleListener* function); + void deregisterEventListener(LLString name); + LLString findEventListener(LLSimpleListener *listener) const; + void addListenerToControl(LLEventDispatcher *observer, const LLString& name, LLSD filter, LLSD userdata); + + void addBoolControl(LLString name, bool initial_value); + LLControlBase *getControl(LLString name); + LLControlBase *findControl(LLString name); + + void setControlValue(const LLSD& value); + virtual void setControlName(const LLString& control, LLView *context); + virtual LLString getControlName() const { return mControlName; } + virtual bool handleEvent(LLPointer event, const LLSD& userdata); + virtual void setValue(const LLSD& value); + virtual LLSD getValue() const; + + const child_list_t* getChildList() const { return &mChildList; } + + // LLMouseHandler functions + // Default behavior is to pass events to children + /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect); // Display mToolTipMsg if no child handles it. + /*virtual*/ const LLString& getName() const; + /*virtual*/ void onMouseCaptureLost(); + /*virtual*/ BOOL hasMouseCapture(); + /*virtual*/ BOOL isView(); // Hack to support LLFocusMgr + /*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const; + /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const; + + template T* getChild(const LLString& name, BOOL recurse = TRUE) const + { + T* result = dynamic_cast(getChildByName(name, TRUE)); + //if (!result) + //{ + // // create dummy widget instance here + // result = gUICtrlFactory->createDummyWidget(name); + //} + return result; + } + + // statics + static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect()); + static LLFontGL* selectFont(LLXMLNodePtr node); static LLFontGL::HAlign selectFontHAlign(LLXMLNodePtr node); static LLFontGL::VAlign selectFontVAlign(LLXMLNodePtr node); static LLFontGL::StyleFlags selectFontStyle(LLXMLNodePtr node); - // Some widgets, like close box buttons, don't need to be saved - BOOL getSaveToXML() const { return mSaveToXML; } - void setSaveToXML(BOOL b) { mSaveToXML = b; } - + // Only saves color if different from default setting. static void addColorXML(LLXMLNodePtr node, const LLColor4& color, const LLString& xml_name, const LLString& control_name); @@ -432,54 +466,17 @@ public: // return query for iterating over focus roots in tab order static const LLCtrlQuery & getFocusRootsQuery(); - BOOL getEnabled() const { return mEnabled; } - BOOL getVisible() const { return mVisible && !mHidden; } - U8 getSoundFlags() const { return mSoundFlags; } - - typedef enum e_hit_test_type - { - HIT_TEST_USE_BOUNDING_RECT, - HIT_TEST_IGNORE_BOUNDING_RECT - }EHitTestType; - - BOOL parentPointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const; - BOOL pointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const; - BOOL blockMouseEvent(S32 x, S32 y) const; - - virtual void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const; - virtual void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const; - virtual BOOL localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view); - virtual void screenRectToLocal( const LLRect& screen, LLRect* local ) const; - virtual void localRectToScreen( const LLRect& local, LLRect* screen ) const; - virtual BOOL localRectToOtherView( const LLRect& local, LLRect* other, LLView* other_view ) const; - - - static LLWindow* getWindow(void); - - // Listener dispatching functions (Dispatcher deletes pointers to listeners on deregistration or destruction) - LLSimpleListener* getListenerByName(const LLString &callback_name); - void registerEventListener(LLString name, LLSimpleListener* function); - void deregisterEventListener(LLString name); - LLString findEventListener(LLSimpleListener *listener) const; - void addListenerToControl(LLEventDispatcher *observer, const LLString& name, LLSD filter, LLSD userdata); - - virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; - - void addBoolControl(LLString name, bool initial_value); - LLControlBase *getControl(LLString name); - virtual LLControlBase *findControl(LLString name); - - void setControlValue(const LLSD& value); - virtual void setControlName(const LLString& control, LLView *context); - virtual LLString getControlName() const; - virtual bool handleEvent(LLPointer event, const LLSD& userdata); - virtual void setValue(const LLSD& value); - const child_list_t* getChildList() const { return &mChildList; } + static BOOL deleteViewByHandle(LLHandle handle); + static LLWindow* getWindow(void) { return LLUI::sWindow; } + protected: virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent); virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent); + void drawDebugRect(); + void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE); + LLView* childrenHandleKey(KEY key, MASK mask); LLView* childrenHandleUnicodeChar(llwchar uni_char); LLView* childrenHandleDragAndDrop(S32 x, S32 y, MASK mask, @@ -497,15 +494,64 @@ protected: LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask); - typedef std::map > dispatch_list_t; - dispatch_list_t mDispatchList; - -protected: typedef std::map control_map_t; control_map_t mFloaterControls; + virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const; + +private: + LLView* mParentView; + child_list_t mChildList; + + LLString mName; + // location in pixels, relative to surrounding structure, bottom,left=0,0 + LLRect mRect; + LLRect mBoundingRect; + + U32 mReshapeFlags; + + child_tab_order_t mCtrlOrder; + S32 mDefaultTabGroup; + + BOOL mEnabled; // Enabled means "accepts input that has an effect on the state of the application." + // A disabled view, for example, may still have a scrollbar that responds to mouse events. + BOOL mMouseOpaque; // Opaque views handle all mouse events that are over their rect. + LLUIString mToolTipMsg; // isNull() is true if none. + + U8 mSoundFlags; + BOOL mSaveToXML; + + BOOL mIsFocusRoot; + BOOL mUseBoundingRect; // hit test against bounding rectangle that includes all child elements + + LLRootHandle mHandle; + BOOL mLastVisible; + + BOOL mVisible; + + S32 mNextInsertionOrdinal; + + static LLWindow* sWindow; // All root views must know about their window. + + typedef std::map > dispatch_list_t; + dispatch_list_t mDispatchList; + LLString mControlName; - friend class LLUICtrlFactory; + + +// Just debugging stuff? We should try to hide anything that's not. -MG +public: + static BOOL sDebugRects; // Draw debug rects behind everything. + static BOOL sDebugKeys; + static S32 sDepth; + static BOOL sDebugMouseHandling; + static LLString sMouseHandlerMessage; + static S32 sSelectID; + static BOOL sEditingUI; + static LLView* sEditingUIView; + static S32 sLastLeftXML; + static S32 sLastBottomXML; + static BOOL sForceReshape; }; @@ -514,12 +560,12 @@ protected: class LLCompareByTabOrder { public: - LLCompareByTabOrder(LLView::child_tab_order_t order); + LLCompareByTabOrder(LLView::child_tab_order_t order) : mTabOrder(order) {} virtual ~LLCompareByTabOrder() {} bool operator() (const LLView* const a, const LLView* const b) const; -protected: - virtual bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const; +private: + virtual bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const { return a < b; } LLView::child_tab_order_t mTabOrder; }; -#endif +#endif //LL_LLVIEW_H diff --git a/linden/indra/llui/llviewborder.cpp b/linden/indra/llui/llviewborder.cpp index b70edec..6c2d9fa 100644 --- a/linden/indra/llui/llviewborder.cpp +++ b/linden/indra/llui/llviewborder.cpp @@ -1,6 +1,5 @@ /** * @file llviewborder.cpp - * @brief LLViewBorder base class * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -29,19 +28,9 @@ * $/LicenseInfo$ */ -// A customizable decorative border. Does not interact with mouse events. - #include "linden_common.h" - #include "llviewborder.h" - -#include "llgl.h" -#include "llui.h" -#include "llimagegl.h" -//#include "llviewerimagelist.h" -#include "llcontrol.h" -#include "llglheaders.h" -#include "v2math.h" +#include "llglimmediate.h" #include "llfocusmgr.h" LLViewBorder::LLViewBorder( const LLString& name, const LLRect& rect, EBevel bevel, EStyle style, S32 width ) @@ -53,7 +42,6 @@ LLViewBorder::LLViewBorder( const LLString& name, const LLRect& rect, EBevel bev mHighlightDark( LLUI::sColorsGroup->getColor( "DefaultHighlightDark" ) ), mShadowLight( LLUI::sColorsGroup->getColor( "DefaultShadowLight" ) ), mShadowDark( LLUI::sColorsGroup->getColor( "DefaultShadowDark" ) ), -// mKeyboardFocusColor(LLUI::sColorsGroup->getColor( "FocusColor" ) ), mBorderWidth( width ), mTexture( NULL ), mHasKeyboardFocus( FALSE ) @@ -61,12 +49,6 @@ LLViewBorder::LLViewBorder( const LLString& name, const LLRect& rect, EBevel bev setFollowsAll(); } -// virtual -BOOL LLViewBorder::isCtrl() const -{ - return FALSE; -} - void LLViewBorder::setColors( const LLColor4& shadow_dark, const LLColor4& highlight_light ) { mShadowDark = shadow_dark; @@ -160,15 +142,15 @@ void LLViewBorder::drawOnePixelLines() } S32 left = 0; - S32 top = mRect.getHeight(); - S32 right = mRect.getWidth(); + S32 top = getRect().getHeight(); + S32 right = getRect().getWidth(); S32 bottom = 0; - glColor4fv( top_color.mV ); + gGL.color4fv( top_color.mV ); gl_line_2d(left, bottom, left, top); gl_line_2d(left, top, right, top); - glColor4fv( bottom_color.mV ); + gGL.color4fv( bottom_color.mV ); gl_line_2d(right, top, right, bottom); gl_line_2d(left, bottom, right, bottom); @@ -219,24 +201,24 @@ void LLViewBorder::drawTwoPixelLines() } S32 left = 0; - S32 top = mRect.getHeight(); - S32 right = mRect.getWidth(); + S32 top = getRect().getHeight(); + S32 right = getRect().getWidth(); S32 bottom = 0; // draw borders - glColor3fv( top_out_color ); + gGL.color3fv( top_out_color ); gl_line_2d(left, bottom, left, top-1); gl_line_2d(left, top-1, right, top-1); - glColor3fv( top_in_color ); + gGL.color3fv( top_in_color ); gl_line_2d(left+1, bottom+1, left+1, top-2); gl_line_2d(left+1, top-2, right-1, top-2); - glColor3fv( bottom_out_color ); + gGL.color3fv( bottom_out_color ); gl_line_2d(right-1, top-1, right-1, bottom); gl_line_2d(left, bottom, right, bottom); - glColor3fv( bottom_in_color ); + gGL.color3fv( bottom_in_color ); gl_line_2d(right-2, top-2, right-2, bottom+1); gl_line_2d(left+1, bottom+1, right-1, bottom+1); } @@ -247,27 +229,27 @@ void LLViewBorder::drawTextures() llassert( FALSE ); // TODO: finish implementing - glColor4fv(UI_VERTEX_COLOR.mV); + gGL.color4fv(UI_VERTEX_COLOR.mV); mTexture->bind(); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); - drawTextureTrapezoid( 0.f, mBorderWidth, mRect.getWidth(), 0, 0 ); - drawTextureTrapezoid( 90.f, mBorderWidth, mRect.getHeight(), (F32)mRect.getWidth(),0 ); - drawTextureTrapezoid( 180.f, mBorderWidth, mRect.getWidth(), (F32)mRect.getWidth(),(F32)mRect.getHeight() ); - drawTextureTrapezoid( 270.f, mBorderWidth, mRect.getHeight(), 0, (F32)mRect.getHeight() ); + drawTextureTrapezoid( 0.f, mBorderWidth, getRect().getWidth(), 0, 0 ); + drawTextureTrapezoid( 90.f, mBorderWidth, getRect().getHeight(), (F32)getRect().getWidth(),0 ); + drawTextureTrapezoid( 180.f, mBorderWidth, getRect().getWidth(), (F32)getRect().getWidth(),(F32)getRect().getHeight() ); + drawTextureTrapezoid( 270.f, mBorderWidth, getRect().getHeight(), 0, (F32)getRect().getHeight() ); } void LLViewBorder::drawTextureTrapezoid( F32 degrees, S32 width, S32 length, F32 start_x, F32 start_y ) { - glPushMatrix(); + gGL.pushMatrix(); { - glTranslatef(start_x, start_y, 0.f); + gGL.translatef(start_x, start_y, 0.f); glRotatef( degrees, 0, 0, 1 ); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { // width, width /---------\ length-width, width // // / \ // @@ -275,24 +257,24 @@ void LLViewBorder::drawTextureTrapezoid( F32 degrees, S32 width, S32 length, F32 // /---------------\ // // 0,0 length, 0 // - glTexCoord2f( 0, 0 ); - glVertex2i( 0, 0 ); + gGL.texCoord2f( 0, 0 ); + gGL.vertex2i( 0, 0 ); - glTexCoord2f( (GLfloat)length, 0 ); - glVertex2i( length, 0 ); + gGL.texCoord2f( (GLfloat)length, 0 ); + gGL.vertex2i( length, 0 ); - glTexCoord2f( (GLfloat)(length - width), (GLfloat)width ); - glVertex2i( length - width, width ); + gGL.texCoord2f( (GLfloat)(length - width), (GLfloat)width ); + gGL.vertex2i( length - width, width ); - glTexCoord2f( (GLfloat)width, (GLfloat)width ); - glVertex2i( width, width ); + gGL.texCoord2f( (GLfloat)width, (GLfloat)width ); + gGL.vertex2i( width, width ); } - glEnd(); + gGL.end(); } - glPopMatrix(); + gGL.popMatrix(); } -bool LLViewBorder::getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel& bevel_style) +BOOL LLViewBorder::getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel& bevel_style) { if (node->hasAttribute("bevel_style")) { @@ -316,25 +298,11 @@ bool LLViewBorder::getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel { bevel_style = LLViewBorder::BEVEL_BRIGHT; } - return true; + return TRUE; } - return false; -} - -void LLViewBorder::setValue(const LLSD& val) -{ - setRect(LLRect(val)); -} - -EWidgetType LLViewBorder::getWidgetType() const -{ - return WIDGET_TYPE_VIEW_BORDER; + return FALSE; } -LLString LLViewBorder::getWidgetTag() const -{ - return LL_VIEW_BORDER_TAG; -} // static LLView* LLViewBorder::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) diff --git a/linden/indra/llui/llviewborder.h b/linden/indra/llui/llviewborder.h index d9c2916..4e5dfee 100644 --- a/linden/indra/llui/llviewborder.h +++ b/linden/indra/llui/llviewborder.h @@ -1,6 +1,6 @@ /** * @file llviewborder.h - * @brief LLViewBorder base class + * @brief A customizable decorative border. Does not interact with mouse events. * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -29,64 +29,56 @@ * $/LicenseInfo$ */ -// A customizable decorative border. Does not interact with mouse events. - #ifndef LL_LLVIEWBORDER_H #define LL_LLVIEWBORDER_H #include "llview.h" -#include "v4color.h" -#include "lluuid.h" -#include "llimagegl.h" -#include "llxmlnode.h" - -class LLUUID; -class LLUICtrlFactory; class LLViewBorder : public LLView { public: enum EBevel { BEVEL_IN, BEVEL_OUT, BEVEL_BRIGHT, BEVEL_NONE }; - enum EStyle { STYLE_LINE, STYLE_TEXTURE }; LLViewBorder( const LLString& name, const LLRect& rect, EBevel bevel = BEVEL_OUT, EStyle style = STYLE_LINE, S32 width = 1 ); - virtual void setValue(const LLSD& val); - virtual EWidgetType getWidgetType() const; - virtual LLString getWidgetTag() const; + virtual void setValue(const LLSD& val) { setRect(LLRect(val)); } + virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_VIEW_BORDER; } + virtual LLString getWidgetTag() const { return LL_VIEW_BORDER_TAG; } - virtual BOOL isCtrl() const; + virtual BOOL isCtrl() const { return FALSE; } // llview functionality virtual void draw(); - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); - static bool getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel& bevel_style); + static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory); + static BOOL getBevelFromAttribute(LLXMLNodePtr node, LLViewBorder::EBevel& bevel_style); void setBorderWidth(S32 width) { mBorderWidth = width; } + S32 getBorderWidth() const { return mBorderWidth; } void setBevel(EBevel bevel) { mBevel = bevel; } + EBevel getBevel() const { return mBevel; } void setColors( const LLColor4& shadow_dark, const LLColor4& highlight_light ); void setColorsExtended( const LLColor4& shadow_light, const LLColor4& shadow_dark, const LLColor4& highlight_light, const LLColor4& highlight_dark ); - void setTexture( const LLUUID &image_id ); + void setTexture( const class LLUUID &image_id ); + + LLColor4 getHighlightLight() {return mHighlightLight;} + LLColor4 getShadowDark() {return mHighlightDark;} - EBevel getBevel() const { return mBevel; } EStyle getStyle() const { return mStyle; } - S32 getBorderWidth() const { return mBorderWidth; } void setKeyboardFocusHighlight( BOOL b ) { mHasKeyboardFocus = b; } -protected: +private: void drawOnePixelLines(); void drawTwoPixelLines(); void drawTextures(); void drawTextureTrapezoid( F32 degrees, S32 width, S32 length, F32 start_x, F32 start_y ); -protected: EBevel mBevel; - EStyle mStyle; + const EStyle mStyle; LLColor4 mHighlightLight; LLColor4 mHighlightDark; LLColor4 mShadowLight; diff --git a/linden/indra/llui/llviewquery.cpp b/linden/indra/llui/llviewquery.cpp index 40c2d61..5c58ad6 100644 --- a/linden/indra/llui/llviewquery.cpp +++ b/linden/indra/llui/llviewquery.cpp @@ -71,22 +71,9 @@ filterResult_t LLWidgetTypeFilter::operator() (const LLView* const view, const v return filterResult_t(view->getWidgetType() == mType, TRUE); } +// // LLViewQuery - -LLViewQuery::LLViewQuery(): mPreFilters(), mPostFilters(), mSorterp() -{ -} - -void LLViewQuery::addPreFilter(const LLQueryFilter* prefilter) { mPreFilters.push_back(prefilter); } - -void LLViewQuery::addPostFilter(const LLQueryFilter* postfilter) { mPostFilters.push_back(postfilter); } - -const LLViewQuery::filterList_t & LLViewQuery::getPreFilters() const { return mPreFilters; } - -const LLViewQuery::filterList_t & LLViewQuery::getPostFilters() const { return mPostFilters; } - -void LLViewQuery::setSorter(const LLQuerySorter* sorterp) { mSorterp = sorterp; } -const LLQuerySorter* LLViewQuery::getSorter() const { return mSorterp; } +// viewList_t LLViewQuery::run(LLView* view) const { diff --git a/linden/indra/llui/llviewquery.h b/linden/indra/llui/llviewquery.h index 2e2b50d..7e947cd 100644 --- a/linden/indra/llui/llviewquery.h +++ b/linden/indra/llui/llviewquery.h @@ -42,12 +42,12 @@ class LLView; typedef std::list viewList_t; typedef std::pair filterResult_t; -// Abstract base class for all filters. +// Abstract base class for all query filters. class LLQueryFilter { public: virtual ~LLQueryFilter() {}; - virtual filterResult_t operator() (const LLView* const view, const viewList_t & children) const =0; + virtual filterResult_t operator() (const LLView* const view, const viewList_t & children) const = 0; }; class LLQuerySorter @@ -105,25 +105,28 @@ public: typedef filterList_t::iterator filterList_iter_t; typedef filterList_t::const_iterator filterList_const_iter_t; - LLViewQuery(); + LLViewQuery() : mPreFilters(), mPostFilters(), mSorterp() {} virtual ~LLViewQuery() {} - void addPreFilter(const LLQueryFilter* prefilter); - void addPostFilter(const LLQueryFilter* postfilter); - const filterList_t & getPreFilters() const; - const filterList_t & getPostFilters() const; + void addPreFilter(const LLQueryFilter* prefilter) { mPreFilters.push_back(prefilter); } + void addPostFilter(const LLQueryFilter* postfilter) { mPostFilters.push_back(postfilter); } + const filterList_t & getPreFilters() const { return mPreFilters; } + const filterList_t & getPostFilters() const { return mPostFilters; } - void setSorter(const LLQuerySorter* sorter); - const LLQuerySorter* getSorter() const; + void setSorter(const LLQuerySorter* sorter) { mSorterp = sorter; } + const LLQuerySorter* getSorter() const { return mSorterp; } viewList_t run(LLView * view) const; // syntactic sugar viewList_t operator () (LLView * view) const { return run(view); } -protected: + // override this method to provide iteration over other types of children virtual void filterChildren(LLView * view, viewList_t & filtered_children) const; + +private: + filterResult_t runFilters(LLView * view, const viewList_t children, const filterList_t filters) const; -protected: + filterList_t mPreFilters; filterList_t mPostFilters; const LLQuerySorter* mSorterp; @@ -135,4 +138,4 @@ public: LLCtrlQuery(); }; -#endif +#endif // LL_LLVIEWQUERY_H diff --git a/linden/indra/llvfs/llvfs_vc8.vcproj b/linden/indra/llvfs/llvfs_vc8.vcproj index 1d48e4a..20ed299 100644 --- a/linden/indra/llvfs/llvfs_vc8.vcproj +++ b/linden/indra/llvfs/llvfs_vc8.vcproj @@ -1,295 +1,295 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llvfs/llvfs_vc9.vcproj b/linden/indra/llvfs/llvfs_vc9.vcproj index 1e87b99..97045e2 100644 --- a/linden/indra/llvfs/llvfs_vc9.vcproj +++ b/linden/indra/llvfs/llvfs_vc9.vcproj @@ -1,296 +1,296 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llwindow/lldxhardware.cpp b/linden/indra/llwindow/lldxhardware.cpp index a401c63..352a5a3 100644 --- a/linden/indra/llwindow/lldxhardware.cpp +++ b/linden/indra/llwindow/lldxhardware.cpp @@ -35,7 +35,9 @@ #include "linden_common.h" +#define INITGUID #include +#undef INITGUID #include diff --git a/linden/indra/llwindow/llgl.cpp b/linden/indra/llwindow/llgl.cpp index 6978fb9..07840c1 100644 --- a/linden/indra/llwindow/llgl.cpp +++ b/linden/indra/llwindow/llgl.cpp @@ -41,6 +41,7 @@ #include "llsys.h" #include "llgl.h" +#include "llglimmediate.h" #include "llerror.h" #include "llquaternion.h" @@ -50,33 +51,15 @@ #include "llglheaders.h" -#if LL_LINUX && !LL_MESA_HEADLESS -// The __APPLE__ hack is to make glh_extensions.h not symbol-clash horribly -# define __APPLE__ -# include "GL/glh_extensions.h" -# undef __APPLE__ - -/* Although SDL very likely ends up calling glXGetProcAddress() itself, - if we do it ourselves then we avoid getting bogus addresses back on - some systems. Weird. */ -/*# include "SDL/SDL.h" - # define GLH_EXT_GET_PROC_ADDRESS(p) SDL_GL_GetProcAddress(p) */ -#define GLX_GLXEXT_PROTOTYPES 1 -# include "GL/glx.h" -# include "GL/glxext.h" -// Use glXGetProcAddressARB instead of glXGetProcAddress - the ARB symbol -// is considered 'legacy' but works on more machines. -# define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddressARB((const GLubyte*)(p)) -#endif // LL_LINUX && !LL_MESA_HEADLESS - - #ifdef _DEBUG //#define GL_STATE_VERIFY #endif BOOL gClothRipple = FALSE; BOOL gNoRender = FALSE; +LLMatrix4 gGLObliqueProjectionInverse; +LLGLNamePool::pool_list_t LLGLNamePool::sInstances; #if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS // ATI prototypes @@ -312,6 +295,8 @@ LLGLManager::LLGLManager() mVRAM = 0; mGLMaxVertexRange = 0; mGLMaxIndexRange = 0; + + mHasRequirements = TRUE; } //--------------------------------------------------------------------- @@ -426,7 +411,13 @@ bool LLGLManager::initGL() } } - else if (mGLVendor.find("INTEL") != LLString::npos) + else if (mGLVendor.find("INTEL") != LLString::npos +#if LL_LINUX + // The Mesa-based drivers put this in the Renderer string, + // not the Vendor string. + || mGLRenderer.find("INTEL") != LLString::npos +#endif //LL_LINUX + ) { mGLVendorShort = "INTEL"; mIsIntel = TRUE; @@ -451,6 +442,8 @@ bool LLGLManager::initGL() } else { + mHasRequirements = FALSE; + // We don't support cards that don't support the GL_ARB_multitexture extension llwarns << "GL Drivers do not support GL_ARB_multitexture" << llendl; return false; @@ -509,6 +502,7 @@ void LLGLManager::shutdownGL() { if (mInited) { + glFinish(); stop_glerror(); mInited = FALSE; } @@ -959,7 +953,17 @@ void assert_glerror() if (error) { #ifndef LL_LINUX // *FIX: ! This should be an error for linux as well. - llerrs << "GL Error:" << gluErrorString(error) << llendl; + GLubyte const * gl_error_msg = gluErrorString(error); + if (NULL != gl_error_msg) + { + llerrs << "GL Error:" << gl_error_msg << llendl; + } + else + { + // gluErrorString returns NULL for some extensions' error codes. + // you'll probably have to grep for the number in glext.h. + llerrs << "GL Error: UNKNOWN 0x" << std::hex << error << llendl; + } #endif } } @@ -988,6 +992,7 @@ GLboolean LLGLDepthTest::sWriteEnabled = GL_TRUE; // OpenGL default void LLGLState::initClass() { sStateMap[GL_DITHER] = GL_TRUE; + sStateMap[GL_TEXTURE_2D] = GL_TRUE; } //static @@ -1001,7 +1006,9 @@ void LLGLState::restoreGL() // Really shouldn't be needed, but seems we sometimes do. void LLGLState::resetTextureStates() { + gGL.flush(); GLint maxTextureUnits; + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits); for (S32 j = maxTextureUnits-1; j >=0; j--) { @@ -1074,7 +1081,23 @@ void LLGLState::checkTextureChannels() error = TRUE; llwarns << "Active texture channel corrupted. " << llendl; } - + else if (!glIsEnabled(GL_TEXTURE_2D)) + { + error = TRUE; + llwarns << "GL_TEXTURE_2D not enabled on texture channel 0." << llendl; + } + else + { + GLint tex_env_mode = 0; + + glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_env_mode); + if (tex_env_mode != GL_MODULATE) + { + error = TRUE; + llwarns << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << llendl; + } + } + GLint maxTextureUnits; glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits); @@ -1270,11 +1293,13 @@ void LLGLState::setEnabled(S32 enabled) } else if (enabled == TRUE && sStateMap[mState] != GL_TRUE) { + gGL.flush(); glEnable(mState); sStateMap[mState] = GL_TRUE; } else if (enabled == FALSE && sStateMap[mState] != GL_FALSE) { + gGL.flush(); glDisable(mState); sStateMap[mState] = GL_FALSE; } @@ -1291,6 +1316,7 @@ LLGLState::~LLGLState() #endif if (mIsEnabled != mWasEnabled) { + gGL.flush(); if (mWasEnabled) { glEnable(mState); @@ -1478,3 +1504,200 @@ void parse_gl_version( S32* major, S32* minor, S32* release, LLString* vendor_sp vendor_specific->assign( version + i ); } } + +LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection) +{ + mModelview = modelview; + mProjection = projection; + + setPlane(p.mV[0], p.mV[1], p.mV[2], p.mV[3]); +} + +void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d) +{ + glh::matrix4f& P = mProjection; + glh::matrix4f& M = mModelview; + + glh::matrix4f invtrans_MVP = (P * M).inverse().transpose(); + glh::vec4f oplane(a,b,c,d); + glh::vec4f cplane; + invtrans_MVP.mult_matrix_vec(oplane, cplane); + + cplane /= fabs(cplane[2]); // normalize such that depth is not scaled + cplane[3] -= 1; + + if(cplane[2] < 0) + cplane *= -1; + + glh::matrix4f suffix; + suffix.set_row(2, cplane); + glh::matrix4f newP = suffix * P; + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixf(newP.m); + gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m); + glMatrixMode(GL_MODELVIEW); +} + +LLGLUserClipPlane::~LLGLUserClipPlane() +{ + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); +} + +LLGLNamePool::LLGLNamePool() +{ +} + +void LLGLNamePool::registerPool(LLGLNamePool* pool) +{ + pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), pool); + if (iter == sInstances.end()) + { + sInstances.push_back(pool); + } +} + +LLGLNamePool::~LLGLNamePool() +{ + pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), this); + if (iter != sInstances.end()) + { + sInstances.erase(iter); + } +} + +void LLGLNamePool::upkeep() +{ + std::sort(mNameList.begin(), mNameList.end(), CompareUsed()); +} + +void LLGLNamePool::cleanup() +{ + for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter) + { + releaseName(iter->name); + } + + mNameList.clear(); +} + +GLuint LLGLNamePool::allocate() +{ + for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter) + { + if (!iter->used) + { + iter->used = TRUE; + return iter->name; + } + } + + NameEntry entry; + entry.name = allocateName(); + entry.used = TRUE; + mNameList.push_back(entry); + + return entry.name; +} + +void LLGLNamePool::release(GLuint name) +{ + for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter) + { + if (iter->name == name) + { + iter->used = FALSE; + return; + } + } +} + +//static +void LLGLNamePool::upkeepPools() +{ + for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) + { + LLGLNamePool* pool = *iter; + pool->upkeep(); + } +} + +//static +void LLGLNamePool::cleanupPools() +{ + for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) + { + LLGLNamePool* pool = *iter; + pool->cleanup(); + } +} + +LLGLDepthTest::LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled, GLenum depth_func) +: mPrevDepthEnabled(sDepthEnabled), mPrevDepthFunc(sDepthFunc), mPrevWriteEnabled(sWriteEnabled) +{ + if (depth_enabled != sDepthEnabled) + { + gGL.flush(); + if (depth_enabled) glEnable(GL_DEPTH_TEST); + else glDisable(GL_DEPTH_TEST); + sDepthEnabled = depth_enabled; + } + if (depth_func != sDepthFunc) + { + gGL.flush(); + glDepthFunc(depth_func); + sDepthFunc = depth_func; + } + if (write_enabled != sWriteEnabled) + { + gGL.flush(); + glDepthMask(write_enabled); + sWriteEnabled = write_enabled; + } +} + +LLGLDepthTest::~LLGLDepthTest() +{ + if (sDepthEnabled != mPrevDepthEnabled ) + { + gGL.flush(); + if (mPrevDepthEnabled) glEnable(GL_DEPTH_TEST); + else glDisable(GL_DEPTH_TEST); + sDepthEnabled = mPrevDepthEnabled; + } + if (sDepthFunc != mPrevDepthFunc) + { + gGL.flush(); + glDepthFunc(mPrevDepthFunc); + sDepthFunc = mPrevDepthFunc; + } + if (sWriteEnabled != mPrevWriteEnabled ) + { + gGL.flush(); + glDepthMask(mPrevWriteEnabled); + sWriteEnabled = mPrevWriteEnabled; + } +} + +LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P) +{ + for (U32 i = 0; i < 4; i++) + { + P.element(2, i) = P.element(3, i) * 0.99999f; + } + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixf(P.m); + glMatrixMode(GL_MODELVIEW); +} + +LLGLClampToFarClip::~LLGLClampToFarClip() +{ + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); +} + diff --git a/linden/indra/llwindow/llgl.h b/linden/indra/llwindow/llgl.h index 57bd616..25ad0d6 100644 --- a/linden/indra/llwindow/llgl.h +++ b/linden/indra/llwindow/llgl.h @@ -42,8 +42,12 @@ #include "llstring.h" #include "stdtypes.h" #include "v4math.h" +#include "llplane.h" #include "llgltypes.h" +#include "llglheaders.h" +#include "glh/glh_linear.h" + #define LL_DEBUG_GL 1 #define LL_GL_ERRS llerrs @@ -97,6 +101,9 @@ public: BOOL mIsGFFX; BOOL mATIOffsetVerticalLines; + // Whether this version of GL is good enough for SL to use + BOOL mHasRequirements; + #if LL_WINDOWS BOOL mHasWGLARBPixelFormat; #endif // LL_WINDOWS @@ -257,6 +264,94 @@ public: LLGLDisable(LLGLenum state) : LLGLState(state, FALSE) {} }; +/* + Store and modify projection matrix to create an oblique + projection that clips to the specified plane. Oblique + projections alter values in the depth buffer, so this + class should not be used mid-renderpass. + + Restores projection matrix on destruction. + GL_MODELVIEW_MATRIX is active whenever program execution + leaves this class. + Does not stack. + Caches inverse of projection matrix used in gGLObliqueProjectionInverse +*/ +class LLGLUserClipPlane +{ +public: + + LLGLUserClipPlane(const LLPlane& plane, const glh::matrix4f& modelview, const glh::matrix4f& projection); + ~LLGLUserClipPlane(); + + void setPlane(F32 a, F32 b, F32 c, F32 d); + +private: + glh::matrix4f mProjection; + glh::matrix4f mModelview; +}; + +/* + Modify and load projection matrix to push depth values to far clip plane. + + Restores projection matrix on destruction. + GL_MODELVIEW_MATRIX is active whenever program execution + leaves this class. + Does not stack. +*/ +class LLGLClampToFarClip +{ +public: + LLGLClampToFarClip(glh::matrix4f projection); + ~LLGLClampToFarClip(); +}; + +/* + Generic pooling scheme for things which use GL names (used for occlusion queries and vertex buffer objects). + Prevents thrashing of GL name caches by avoiding calls to glGenFoo and glDeleteFoo. +*/ +class LLGLNamePool +{ +public: + typedef struct + { + GLuint name; + BOOL used; + } NameEntry; + + struct CompareUsed + { + bool operator()(const NameEntry& lhs, const NameEntry& rhs) + { + return lhs.used < rhs.used; //FALSE entries first + } + }; + + typedef std::vector name_list_t; + name_list_t mNameList; + + LLGLNamePool(); + virtual ~LLGLNamePool(); + + void upkeep(); + void cleanup(); + + GLuint allocate(); + void release(GLuint name); + + static void registerPool(LLGLNamePool* pool); + static void upkeepPools(); + static void cleanupPools(); + +protected: + typedef std::vector pool_list_t; + static pool_list_t sInstances; + + virtual GLuint allocateName() = 0; + virtual void releaseName(GLuint name) = 0; +}; + +extern LLMatrix4 gGLObliqueProjectionInverse; + #include "llglstates.h" void init_glstates(); diff --git a/linden/indra/llwindow/llglheaders.h b/linden/indra/llwindow/llglheaders.h index 45310ef..d66fbe4 100644 --- a/linden/indra/llwindow/llglheaders.h +++ b/linden/indra/llwindow/llglheaders.h @@ -50,6 +50,11 @@ #include "GL/glext.h" #include "GL/glu.h" +// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly +# define __APPLE__ +# include "GL/glh_extensions.h" +# undef __APPLE__ + #elif LL_LINUX //---------------------------------------------------------------------------- // Linux, MESA headers, but not necessarily assuming MESA runtime. @@ -58,6 +63,29 @@ #include "GL/glext.h" #include "GL/glu.h" + +#if LL_LINUX && !LL_MESA_HEADLESS +// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly +# define __APPLE__ +# include "GL/glh_extensions.h" +# undef __APPLE__ + +/* Although SDL very likely ends up calling glXGetProcAddress() itself, + if we use SDL_GL_GetProcAddress() then we get bogus addresses back on + some systems. Weird. */ +/*# include "SDL/SDL.h" + # define GLH_EXT_GET_PROC_ADDRESS(p) SDL_GL_GetProcAddress(p) */ +#define GLX_GLXEXT_PROTOTYPES 1 +# include "GL/glx.h" +# include "GL/glxext.h" +// Use glXGetProcAddressARB instead of glXGetProcAddress - the ARB symbol +// is considered 'legacy' but works on more machines. +# define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddressARB((const GLubyte*)(p)) +// Whee, the X headers define 'Status'. Undefine to avoid confusion. +#undef Status +#endif // LL_LINUX && !LL_MESA_HEADLESS + + // GL_ARB_vertex_buffer_object extern PFNGLBINDBUFFERARBPROC glBindBufferARB; extern PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB; @@ -234,6 +262,12 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT; #elif LL_WINDOWS + +// windows gl headers depend on things like APIENTRY, so include windows. +#define WIN32_LEAN_AND_MEAN +#include +#include + //---------------------------------------------------------------------------- #include #include @@ -555,6 +589,8 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); } #endif +#include + #endif // LL_MESA / LL_WINDOWS / LL_DARWIN diff --git a/linden/indra/llwindow/llglstates.h b/linden/indra/llwindow/llglstates.h index 5052c8d..7d65952 100644 --- a/linden/indra/llwindow/llglstates.h +++ b/linden/indra/llwindow/llglstates.h @@ -33,17 +33,7 @@ #ifndef LL_LLGLSTATES_H #define LL_LLGLSTATES_H -#ifdef WIN32 -# define WIN32_LEAN_AND_MEAN -# include -# include -#endif - -#if LL_DARWIN -#include -#else -#include "llglheaders.h" -#endif +#include "llimagegl.h" //---------------------------------------------------------------------------- @@ -51,45 +41,10 @@ class LLGLDepthTest { // Enabled by default public: - LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled = GL_TRUE, GLenum depth_func = GL_LEQUAL) - : mPrevDepthEnabled(sDepthEnabled), mPrevDepthFunc(sDepthFunc), mPrevWriteEnabled(sWriteEnabled) - { - if (depth_enabled != sDepthEnabled) - { - if (depth_enabled) glEnable(GL_DEPTH_TEST); - else glDisable(GL_DEPTH_TEST); - sDepthEnabled = depth_enabled; - } - if (depth_func != sDepthFunc) - { - glDepthFunc(depth_func); - sDepthFunc = depth_func; - } - if (write_enabled != sWriteEnabled) - { - glDepthMask(write_enabled); - sWriteEnabled = write_enabled; - } - } - ~LLGLDepthTest() - { - if (sDepthEnabled != mPrevDepthEnabled ) - { - if (mPrevDepthEnabled) glEnable(GL_DEPTH_TEST); - else glDisable(GL_DEPTH_TEST); - sDepthEnabled = mPrevDepthEnabled; - } - if (sDepthFunc != mPrevDepthFunc) - { - glDepthFunc(mPrevDepthFunc); - sDepthFunc = mPrevDepthFunc; - } - if (sWriteEnabled != mPrevWriteEnabled ) - { - glDepthMask(mPrevWriteEnabled); - sWriteEnabled = mPrevWriteEnabled; - } - } + LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled = GL_TRUE, GLenum depth_func = GL_LEQUAL); + + ~LLGLDepthTest(); + GLboolean mPrevDepthEnabled; GLenum mPrevDepthFunc; GLboolean mPrevWriteEnabled; @@ -104,7 +59,7 @@ private: class LLGLSDefault { protected: - LLGLEnable mTexture2D, mColorMaterial; + LLGLEnable mColorMaterial; LLGLDisable mAlphaTest, mBlend, mCullFace, mDither, mFog, mLineSmooth, mLineStipple, mNormalize, mPolygonSmooth, mTextureGenQ, mTextureGenR, mTextureGenS, mTextureGenT; @@ -112,7 +67,6 @@ public: LLGLSDefault() : // Enable - mTexture2D(GL_TEXTURE_2D), mColorMaterial(GL_COLOR_MATERIAL), // Disable mAlphaTest(GL_ALPHA_TEST), @@ -131,47 +85,33 @@ public: { } }; -class LLGLSTexture -{ -protected: - LLGLEnable mTexture2D; -public: - LLGLSTexture() - : mTexture2D(GL_TEXTURE_2D) - {} -}; - - class LLGLSNoTexture { -protected: - LLGLDisable mTexture2D; public: LLGLSNoTexture() - : mTexture2D(GL_TEXTURE_2D) - {} + { LLImageGL::unbindTexture(0); } }; -class LLGLSObjectSelect // : public LLGLSDefault +class LLGLSObjectSelect { protected: - LLGLDisable mBlend, mFog, mTexture2D, mAlphaTest; + LLGLDisable mBlend, mFog, mAlphaTest; LLGLEnable mCullFace; public: LLGLSObjectSelect() - : mBlend(GL_BLEND), mFog(GL_FOG), mTexture2D(GL_TEXTURE_2D), + : mBlend(GL_BLEND), mFog(GL_FOG), mAlphaTest(GL_ALPHA_TEST), mCullFace(GL_CULL_FACE) - {} + { LLImageGL::unbindTexture(0); } }; -class LLGLSObjectSelectAlpha // : public LLGLSObjectSelect +class LLGLSObjectSelectAlpha { protected: - LLGLEnable mTexture2D, mAlphaTest; + LLGLEnable mAlphaTest; public: LLGLSObjectSelectAlpha() - : mTexture2D(GL_TEXTURE_2D), mAlphaTest(GL_ALPHA_TEST) + : mAlphaTest(GL_ALPHA_TEST) {} }; @@ -180,13 +120,12 @@ public: class LLGLSUIDefault // : public LLGLSDefault { protected: - LLGLEnable mBlend, mAlphaTest, mTexture2D; + LLGLEnable mBlend, mAlphaTest; LLGLDisable mCullFace; LLGLDepthTest mDepthTest; public: LLGLSUIDefault() : mBlend(GL_BLEND), mAlphaTest(GL_ALPHA_TEST), - mTexture2D(GL_TEXTURE_2D), mCullFace(GL_CULL_FACE), mDepthTest(GL_FALSE, GL_TRUE, GL_LEQUAL) {} @@ -206,12 +145,11 @@ class LLGLSNoTextureNoAlphaTest // : public LLGLSUIDefault { protected: LLGLDisable mAlphaTest; - LLGLDisable mTexture2D; public: LLGLSNoTextureNoAlphaTest() - : mAlphaTest(GL_ALPHA_TEST), - mTexture2D(GL_TEXTURE_2D) - {} + : mAlphaTest(GL_ALPHA_TEST) + + { LLImageGL::unbindTexture(0); } }; //---------------------------------------------------------------------------- @@ -305,14 +243,13 @@ class LLGLSTracker // : public LLGLSDefault { protected: LLGLEnable mCullFace, mBlend, mAlphaTest; - LLGLDisable mTexture2D; public: LLGLSTracker() : mCullFace(GL_CULL_FACE), mBlend(GL_BLEND), - mAlphaTest(GL_ALPHA_TEST), - mTexture2D(GL_TEXTURE_2D) - {} + mAlphaTest(GL_ALPHA_TEST) + + { LLImageGL::unbindTexture(0); } }; //---------------------------------------------------------------------------- @@ -340,4 +277,24 @@ public: //---------------------------------------------------------------------------- +class LLGLSBlendFunc : public LLGLSPipeline { +protected: + GLint mSavedSrc, mSavedDst; + LLGLEnable mBlend; + +public: + LLGLSBlendFunc(GLenum srcFunc, GLenum dstFunc) : + mBlend(GL_BLEND) + { + glGetIntegerv(GL_BLEND_SRC, &mSavedSrc); + glGetIntegerv(GL_BLEND_DST, &mSavedDst); + glBlendFunc(srcFunc, dstFunc); + } + + ~LLGLSBlendFunc(void) { + glBlendFunc(mSavedSrc, mSavedDst); + } +}; + + #endif diff --git a/linden/indra/llwindow/llglstubs.h b/linden/indra/llwindow/llglstubs.h deleted file mode 100644 index 9745caa..0000000 --- a/linden/indra/llwindow/llglstubs.h +++ /dev/null @@ -1,236 +0,0 @@ -/** - * @file llglstubs.h - * @brief LLGL stubs header file - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - - -// bunch of macros that get #included multiple times with GL_FUNC defined -// various ways to make stubs for OpenGL entry points. These are statically -// linked to the app, and call into the real GL, which is dynamically -// loaded at runtime. See llwindowsdl.cpp for current implementation. - -#if 1 -GL_FUNC(void,glAlphaFunc,(GLenum f,GLclampf x),(f,x),) -GL_FUNC(void,glBegin,(GLenum e),(e),) -GL_FUNC(void,glBindTexture,(GLenum target,GLuint name),(target,name),) -GL_FUNC(void,glBlendFunc,(GLenum f,GLenum x),(f,x),) -GL_FUNC(void,glCallLists,(GLsizei a,GLenum b,const GLvoid* c),(a,b,c),) -GL_FUNC(void,glClear,(GLbitfield a),(a),) -GL_FUNC(void,glClearColor,(GLclampf r,GLclampf g,GLclampf b,GLclampf a),(r,g,b,a),) -GL_FUNC(void,glClearDepth,(GLclampd x),(x),) -GL_FUNC(void,glColor3f,(GLfloat r,GLfloat g,GLfloat b),(r,g,b),) -GL_FUNC(void,glColor4f,(GLfloat r,GLfloat g,GLfloat b,GLfloat a),(r,g,b,a),) -GL_FUNC(void,glColorMask,(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha),(red,green,blue,alpha),) -GL_FUNC(void,glColorPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer),(size, type, stride, pointer),) -GL_FUNC(void,glCopyTexImage2D,(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border),(target, level, internalFormat, x, y, width, height, border),) -GL_FUNC(void,glCopyTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height),(target, level, xoffset, yoffset, x, y, width, height),) -GL_FUNC(void,glCullFace,(GLenum mode),(mode),) -GL_FUNC(void,glDeleteLists,(GLuint list, GLsizei range),(list,range),) -GL_FUNC(void,glDeleteTextures,(GLsizei n, const GLuint *textures),(n,textures),) -GL_FUNC(void,glDepthFunc,(GLenum func),(func),) -GL_FUNC(void,glDepthMask,(GLboolean flag),(flag),) -GL_FUNC(void,glDisable,(GLenum cap),(cap),) -GL_FUNC(void,glDisableClientState,(GLenum array),(array),) -GL_FUNC(void,glDrawArrays,(GLenum mode, GLint first, GLsizei count),(mode,first,count),) -GL_FUNC(void,glDrawBuffer,(GLenum mode),(mode),) -GL_FUNC(void,glEnable,(GLenum cap),(cap),) -GL_FUNC(void,glEnableClientState,(GLenum array),(array),) -GL_FUNC(void,glEnd,(void),(),) -GL_FUNC(void,glEndList,(void),(),) -GL_FUNC(GLuint,glGenLists,(GLsizei range),(range),return) -GL_FUNC(void,glGenTextures,(GLsizei n, GLuint *textures),(n,textures),) -GL_FUNC(GLenum,glGetError,(void),(),return) -GL_FUNC(void,glGetFloatv,(GLenum pname, GLfloat *params),(pname,params),) -GL_FUNC(void,glHint,(GLenum target, GLenum mode),(target,mode),) -GL_FUNC(void,glInterleavedArrays,(GLenum format, GLsizei stride, const GLvoid *pointer),(format,stride,pointer),) -GL_FUNC(GLboolean,glIsTexture,(GLuint texture),(texture),return) -GL_FUNC(void,glLightfv,(GLenum light, GLenum pname, const GLfloat *params),(light,pname,params),) -GL_FUNC(void,glListBase,(GLuint base),(base),) -GL_FUNC(void,glLoadIdentity,(void),(),) -GL_FUNC(void,glLoadMatrixf,(const GLfloat *m),(m),) -GL_FUNC(void,glMatrixMode,(GLenum mode),(mode),) -GL_FUNC(void,glNewList,(GLuint list, GLenum mode),(list,mode),) -GL_FUNC(void,glNormal3f,(GLfloat nx, GLfloat ny, GLfloat nz),(nx,ny,nz),) -GL_FUNC(void,glOrtho,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar),(left,right,bottom,top,zNear,zFar),) -GL_FUNC(void,glPixelStorei,(GLenum pname, GLint param),(pname,param),) -GL_FUNC(void,glPixelTransferi,(GLenum pname, GLint param),(pname,param),) -GL_FUNC(void,glPointSize,(GLfloat size),(size),) -GL_FUNC(void,glPopMatrix,(void),(),) -GL_FUNC(void,glPushMatrix,(void),(),) -GL_FUNC(void,glReadBuffer,(GLenum mode),(mode),) -GL_FUNC(void,glReadPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels),(x,y,width,height,format,type,pixels),) -GL_FUNC(void,glRotatef,(GLfloat angle, GLfloat x, GLfloat y, GLfloat z),(angle,x,y,z),) -GL_FUNC(void,glScalef,(GLfloat x, GLfloat y, GLfloat z),(x,y,z),) -GL_FUNC(void,glShadeModel,(GLenum mode),(mode),) -GL_FUNC(void,glTexCoord2f,(GLfloat s, GLfloat t),(s,t),) -GL_FUNC(void,glTexCoordPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer),(size,type,stride,pointer),) -GL_FUNC(void,glTexEnvf,(GLenum target, GLenum pname, GLfloat param),(target,pname,param),) -GL_FUNC(void,glTexEnvfv,(GLenum target, GLenum pname, const GLfloat *params),(target,pname,params),) -GL_FUNC(void,glTexEnvi,(GLenum target, GLenum pname, GLint param),(target,pname,param),) -GL_FUNC(void,glTexParameterf,(GLenum target, GLenum pname, GLfloat param),(target,pname,param),) -GL_FUNC(void,glTexParameteri,(GLenum target, GLenum pname, GLint param),(target,pname,param),) -GL_FUNC(void,glTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels),(target,level,xoffset,yoffset,width,height,format,type,pixels),) -GL_FUNC(void,glTranslated,(GLdouble x, GLdouble y, GLdouble z),(x,y,z),) -GL_FUNC(void,glTranslatef,(GLfloat x, GLfloat y, GLfloat z),(x,y,z),) -GL_FUNC(void,glVertex2i,(GLint x, GLint y),(x,y),) -GL_FUNC(void,glVertex2f,(GLfloat x, GLfloat y),(x,y),) -GL_FUNC(void,glVertex3f,(GLfloat x, GLfloat y, GLfloat z),(x,y,z),) -GL_FUNC(void,glVertexPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer),(size,type,stride,pointer),) -GL_FUNC(void,glViewport,(GLint x, GLint y, GLsizei width, GLsizei height),(x,y,width,height),) -GL_FUNC(void,glLockArraysEXT,(GLint first, GLsizei count),(first,count),) -GL_FUNC(void,glUnlockArraysEXT,(void),(),) -GL_FUNC(void,glGetIntegerv,(GLenum pname, GLint *params),(pname,params),) -GL_FUNC(const GLubyte *,glGetString,(GLenum name),(name),return) -GL_FUNC(void,glGetTexLevelParameteriv,(GLenum target, GLint level, GLenum pname, GLint *params),(target,level,pname,params),) -GL_FUNC(void,glMultMatrixd,(const GLdouble *m),(m),) -GL_FUNC(void,glMultMatrixf,(const GLfloat *m),(m),) -GL_FUNC(void,glGetTexImage,(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels),(target,level,format,type,pixels),) -GL_FUNC(void,glTexImage1D,(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels),(target,level,internalFormat,width,border,format,type,pixels),) -GL_FUNC(void,glTexImage2D,(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels),(target,level,internalFormat,width,height,border,format,type,pixels),) -GL_FUNC(void,glTexImage3D,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels),(target,level,internalformat,width,height,depth,border,format,type,pixels),) -GL_FUNC(void,glDepthRange,(GLclampd near_val, GLclampd far_val),(near_val,far_val),) -GL_FUNC(void,glCallList,(GLuint list),(list),) -GL_FUNC(void,glClearStencil,(GLint s),(s),) -GL_FUNC(void,glColor3d,(GLdouble red, GLdouble green, GLdouble blue),(red,green,blue),) -GL_FUNC(void,glColor3dv,(const GLdouble *v),(v),) -GL_FUNC(void,glColor3fv,(const GLfloat *v),(v),) -GL_FUNC(void,glColor4dv,(const GLdouble *v),(v),) -GL_FUNC(void,glColor4fv,(const GLfloat *v),(v),) -GL_FUNC(void,glColor4ub,(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha),(red,green,blue,alpha),) -GL_FUNC(void,glColor4ubv,(const GLubyte *v),(v),) -GL_FUNC(void,glColorMaterial,(GLenum face, GLenum mode),(face,mode),) -GL_FUNC(void,glClientActiveTextureARB,(GLenum x),(x),) -GL_FUNC(void,glActiveTextureARB,(GLenum texture),(texture),) -GL_FUNC(GLboolean,glAreTexturesResident,(GLsizei n, const GLuint *textures, GLboolean *residences),(n,textures,residences),return) -GL_FUNC(void,glClipPlane,(GLenum plane, const GLdouble *equation),(plane,equation),) -GL_FUNC(void,glBindBufferARB,(GLenum x, GLuint y),(x,y),) -GL_FUNC(void,glDeleteBuffersARB,(GLsizei x, const GLuint *y),(x,y),) -GL_FUNC(void,glGenBuffersARB,(GLsizei x, GLuint *y),(x,y),) -GL_FUNC(void,glBufferDataARB,(GLenum a, GLsizeiptrARB b, const GLvoid *c, GLenum d),(a,b,c,d),) -GL_FUNC(void,glBufferSubDataARB,(GLenum a, GLintptr b, GLsizeiptr c, const GLvoid *d),(a,b,c,d),) -GL_FUNC(void,glProgramStringARB,(GLenum a, GLenum b, GLsizei c, const GLvoid *d),(a,b,c,d),) -GL_FUNC(void,glBindProgramARB,(GLenum a, GLuint b),(a,b),) -GL_FUNC(void,glDeleteProgramsARB,(GLsizei a, const GLuint *b),(a,b),) -GL_FUNC(void,glGenProgramsARB,(GLsizei a, GLuint *b),(a,b),) -GL_FUNC(void,glProgramEnvParameter4dARB,(GLenum a, GLuint b, GLdouble c, GLdouble d, GLdouble e, GLdouble f),(a,b,c,d,e,f),) -GL_FUNC(void,glProgramEnvParameter4dvARB,(GLenum a, GLuint b, const GLdouble *c),(a,b,c),) -GL_FUNC(void,glProgramEnvParameter4fARB,(GLenum a, GLuint b, GLfloat c, GLfloat d, GLfloat e, GLfloat f),(a,b,c,d,e,f),) -GL_FUNC(void,glProgramEnvParameter4fvARB,(GLenum a, GLuint b, const GLfloat *c),(a,b,c),) -GL_FUNC(void,glProgramLocalParameter4dARB,(GLenum a, GLuint b, GLdouble c, GLdouble d, GLdouble e, GLdouble f),(a,b,c,d,e,f),) -GL_FUNC(void,glProgramLocalParameter4dvARB,(GLenum a, GLuint b, const GLdouble *c),(a,b,c),) -GL_FUNC(void,glProgramLocalParameter4fARB,(GLenum a, GLuint b, GLfloat c, GLfloat d, GLfloat e, GLfloat f),(a,b,c,d,e,f),) -GL_FUNC(void,glProgramLocalParameter4fvARB,(GLenum a, GLuint b, const GLfloat *c),(a,b,c),) -GL_FUNC(void,glGetProgramEnvParameterdvARB,(GLenum a, GLuint b, GLdouble *c),(a,b,c),) -GL_FUNC(void,glGetProgramEnvParameterfvARB,(GLenum a, GLuint b, GLfloat *c),(a,b,c),) -GL_FUNC(void,glGetProgramLocalParameterdvARB,(GLenum a, GLuint b, GLdouble *c),(a,b,c),) -GL_FUNC(void,glGetProgramLocalParameterfvARB,(GLenum a, GLuint b, GLfloat *c),(a,b,c),) -GL_FUNC(void,glGetProgramivARB,(GLenum a, GLenum b, GLint *c),(a,b,c),) -GL_FUNC(void,glGetProgramStringARB,(GLenum a, GLenum b, GLvoid *c),(a,b,c),) -GL_FUNC(GLboolean,glIsProgramARB,(GLuint a),(a),return) -GL_FUNC(void,glColorTableEXT,(GLenum a, GLenum b, GLsizei c, GLenum d, GLenum e, const GLvoid *f),(a,b,c,d,e,f),) -GL_FUNC(void,glCompressedTexImage2DARB,(GLenum a, GLint b, GLenum c, GLsizei d, GLsizei e, GLint f, GLsizei g, const GLvoid *h),(a,b,c,d,e,f,g,h),) -GL_FUNC(void,glEnableVertexAttribArrayARB,(GLuint a),(a),) -GL_FUNC(void,glDisableVertexAttribArrayARB,(GLuint a),(a),) -GL_FUNC(void,glDrawElements,(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices),(mode,count,type,indices),) -GL_FUNC(void,glDrawPixels,(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels),(width,height,format,type,pixels),) -GL_FUNC(void,glDrawRangeElements,(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices),(mode,start,end,count,type,indices),) -GL_FUNC(void,glFlush,(void),(),) -GL_FUNC(void,glFogf,(GLenum pname, GLfloat param),(pname,param),) -GL_FUNC(void,glFogfv,(GLenum pname, const GLfloat *params),(pname,params),) -GL_FUNC(void,glFogi,(GLenum pname, GLint param),(pname,param),) -GL_FUNC(void,glFrontFace,(GLenum mode),(mode),) -GL_FUNC(void,glGetBooleanv,(GLenum pname, GLboolean *params),(pname,params),) -GL_FUNC(void,glGetDoublev,(GLenum pname, GLdouble *params),(pname,params),) -GL_FUNC(void,glGetMaterialfv,(GLenum face, GLenum pname, GLfloat *params),(face,pname,params),) -GL_FUNC(void,glGetLightfv,(GLenum light, GLenum pname, GLfloat *params),(light,pname,params),) -GL_FUNC(GLboolean,glIsEnabled,(GLenum cap),(cap),return) -GL_FUNC(void,glGetCompressedTexImageARB,(GLenum a, GLint b, GLvoid *c),(a,b,c),) -GL_FUNC(void,glLightf,(GLenum light, GLenum pname, GLfloat param),(light,pname,param),) -GL_FUNC(void,glLightModelfv,(GLenum pname, const GLfloat *params),(pname,params),) -GL_FUNC(void,glLightModeli,(GLenum pname, GLint param),(pname,param),) -GL_FUNC(void,glLightModeliv,(GLenum pname, const GLint *params),(pname,params),) -GL_FUNC(void,glLineStipple,(GLint factor, GLushort pattern),(factor,pattern),) -GL_FUNC(void,glLineWidth,(GLfloat width),(width),) -GL_FUNC(void,glPushAttrib,(GLbitfield mask),(mask),) -GL_FUNC(void,glPopAttrib,(void),(),) -GL_FUNC(void,glLogicOp,(GLenum opcode),(opcode),) -GL_FUNC(void,glMaterialf,(GLenum face, GLenum pname, GLfloat param),(face,pname,param),) -GL_FUNC(void,glMateriali,(GLenum face, GLenum pname, GLint param),(face,pname,param),) -GL_FUNC(void,glMaterialfv,(GLenum face, GLenum pname, const GLfloat *params),(face,pname,params),) -GL_FUNC(void,glNormal3d,(GLdouble nx, GLdouble ny, GLdouble nz),(nx,ny,nz),) -GL_FUNC(void,glNormal3dv,(const GLdouble *v),(v),) -GL_FUNC(void,glNormal3fv,(const GLfloat *v),(v),) -GL_FUNC(void,glNormalPointer,(GLenum type, GLsizei stride, const GLvoid *ptr),(type,stride,ptr),) -GL_FUNC(void,glPolygonMode,(GLenum face, GLenum mode),(face,mode),) -GL_FUNC(void,glPolygonOffset,(GLfloat factor, GLfloat units),(factor,units),) -GL_FUNC(void,glPolygonStipple,(const GLubyte *mask),(mask),) -GL_FUNC(void,glRotated,(GLdouble angle, GLdouble x, GLdouble y, GLdouble z),(angle,x,y,z),) -GL_FUNC(void,glStencilFunc,(GLenum func, GLint ref, GLuint mask),(func,ref,mask),) -GL_FUNC(void,glStencilMask,(GLuint mask),(mask),) -GL_FUNC(void,glScissor,(GLint x, GLint y, GLsizei width, GLsizei height),(x,y,width,height),) -GL_FUNC(void,glStencilOp,(GLenum fail, GLenum zfail, GLenum zpass),(fail,zfail,zpass),) -GL_FUNC(void,glTexCoord2i,(GLint s, GLint t),(s,t),) -GL_FUNC(void,glTexCoord2fv,(const GLfloat *v),(v),) -GL_FUNC(void,glTexGenfv,(GLenum coord, GLenum pname, const GLfloat *params),(coord,pname,params),) -GL_FUNC(void,glTexGeni,(GLenum coord, GLenum pname, GLint param),(coord,pname,param),) -GL_FUNC(void,glTexParameterfv,(GLenum target, GLenum pname, const GLfloat *params),(target,pname,params),) -GL_FUNC(void,glVertex2d,(GLdouble x, GLdouble y),(x,y),) -GL_FUNC(void,glVertex2dv,(const GLdouble *v),(v),) -GL_FUNC(void,glVertex2fv,(const GLfloat *v),(v),) -GL_FUNC(void,glVertex3dv,(const GLdouble *v),(v),) -GL_FUNC(void,glVertex3fv,(const GLfloat *v),(v),) -GL_FUNC(void,glVertex4dv,(const GLdouble *v),(v),) -GL_FUNC(void,glEvalPoint1,(GLint i),(i),) -GL_FUNC(void,glEvalPoint2,(GLint i, GLint j),(i,j),) -GL_FUNC(void,glEvalCoord1f,(GLfloat u),(u),) -GL_FUNC(void,glEvalCoord2f,(GLfloat u, GLfloat v),(u,v),) -GL_FUNC(void,glEvalMesh1,(GLenum mode, GLint i1, GLint i2),(mode,i1,i2),) -GL_FUNC(void,glEvalMesh2,(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2),(mode,i1,i2,j1,j2),) -GL_FUNC(void,glMapGrid1f,(GLint un, GLfloat u1, GLfloat u2),(un,u1,u2),) -GL_FUNC(void,glMapGrid2d,(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2),(un,u1,u2,vn,v1,v2),) -GL_FUNC(void,glMapGrid2f,(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2),(un,u1,u2,vn,v1,v2),) -GL_FUNC(void,glMap1f,(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points),(target,u1,u2,stride,order,points),) -GL_FUNC(void,glMap2f,(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points),(target,u1,u2,ustride,uorder,v1,v2,vstride,vorder,points),) -GL_FUNC(void,glVertexAttribPointerARB,(GLuint a, GLint b, GLenum c, GLboolean d, GLsizei e, const GLvoid *f),(a,b,c,d,e,f),) -GL_FUNC(GLuint,glNewObjectBufferATI,(GLsizei a, const GLvoid *b, GLenum c),(a,b,c),return) -GL_FUNC(void,glUpdateObjectBufferATI,(GLuint a, GLuint b, GLsizei c, const GLvoid *d, GLenum e),(a,b,c,d,e),) -GL_FUNC(void,glFreeObjectBufferATI,(GLuint a),(a),) -GL_FUNC(void,glArrayObjectATI,(GLenum a, GLint b, GLenum c, GLsizei d, GLuint e, GLuint f),(a,b,c,d,e,f),) -GL_FUNC(void,glVertexAttribArrayObjectATI,(GLuint a, GLint b, GLenum c, GLboolean d, GLsizei e, GLuint f, GLuint g),(a,b,c,d,e,f,g),) - -// CgGL needs these on Linux... -#if LL_LINUX || LL_SOLARIS -GL_FUNC(void*,glXGetCurrentDisplay,(void),(),return) -GL_FUNC(const char *,glXQueryExtensionsString,(void *dpy, int screen),(dpy,screen),return) -GL_FUNC(void*,glXGetProcAddressARB,(const GLubyte *fn),(fn),return) -#endif -#endif - -// end of llglstubs.h ... - diff --git a/linden/indra/llwindow/llmousehandler.h b/linden/indra/llwindow/llmousehandler.h index 8bc77bb..b511dcd 100644 --- a/linden/indra/llwindow/llmousehandler.h +++ b/linden/indra/llwindow/llmousehandler.h @@ -57,7 +57,7 @@ public: virtual void onMouseCaptureLost() = 0; // Hack to support LLFocusMgr - virtual BOOL isView() = 0; + virtual BOOL isView() const = 0; virtual void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const = 0; virtual void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const = 0; diff --git a/linden/indra/llwindow/llwindow.cpp b/linden/indra/llwindow/llwindow.cpp index 718ed55..5e05f03 100644 --- a/linden/indra/llwindow/llwindow.cpp +++ b/linden/indra/llwindow/llwindow.cpp @@ -247,7 +247,7 @@ LLWindow::LLWindow(BOOL fullscreen, U32 flags) mFlags(flags), mHighSurrogate(0) { - for (U32 i = 0; i < 6; i++) + for (U32 i = 0; i < 8; i++) { mJoyAxis[i] = 0; } @@ -275,7 +275,7 @@ void LLWindow::decBusyCount() F32 LLWindow::getJoystickAxis(U32 axis) { - if (axis < 6) + if (axis < 8) { return mJoyAxis[axis]; } @@ -415,7 +415,7 @@ void LLSplashScreen::hide() // // TODO: replace with std::set -static LLLinkedList sWindowList; +static std::set sWindowList; LLWindow* LLWindowManager::createWindow( char *title, @@ -481,13 +481,13 @@ LLWindow* LLWindowManager::createWindow( llwarns << "LLWindowManager::create() : Error creating window." << llendl; return NULL; } - sWindowList.addDataAtEnd(new_window); + sWindowList.insert(new_window); return new_window; } BOOL LLWindowManager::destroyWindow(LLWindow* window) { - if (!sWindowList.checkData(window)) + if (sWindowList.find(window) == sWindowList.end()) { llerrs << "LLWindowManager::destroyWindow() : Window pointer not valid, this window doesn't exist!" << llendl; @@ -496,7 +496,7 @@ BOOL LLWindowManager::destroyWindow(LLWindow* window) window->close(); - sWindowList.removeData(window); + sWindowList.erase(window); delete window; @@ -505,5 +505,5 @@ BOOL LLWindowManager::destroyWindow(LLWindow* window) BOOL LLWindowManager::isWindowValid(LLWindow *window) { - return sWindowList.checkData(window); + return sWindowList.find(window) != sWindowList.end(); } diff --git a/linden/indra/llwindow/llwindow.h b/linden/indra/llwindow/llwindow.h index 1d49572..48ee4d6 100644 --- a/linden/indra/llwindow/llwindow.h +++ b/linden/indra/llwindow/llwindow.h @@ -73,6 +73,9 @@ enum ECursorType { UI_CURSOR_TOOLBUY, UI_CURSOR_TOOLPAY, UI_CURSOR_TOOLOPEN, + UI_CURSOR_TOOLPLAY, + UI_CURSOR_TOOLPAUSE, + UI_CURSOR_TOOLMEDIAOPEN, UI_CURSOR_PIPETTE, UI_CURSOR_COUNT // Number of elements in this enum (NOT a cursor) }; @@ -255,7 +258,7 @@ protected: ESwapMethod mSwapMethod; BOOL mHideCursorPermanent; U32 mFlags; - F32 mJoyAxis[6]; + F32 mJoyAxis[8]; U8 mJoyButtonState[16]; U16 mHighSurrogate; diff --git a/linden/indra/llwindow/llwindow.vcproj b/linden/indra/llwindow/llwindow.vcproj index 1291d99..0243c72 100644 --- a/linden/indra/llwindow/llwindow.vcproj +++ b/linden/indra/llwindow/llwindow.vcproj @@ -19,7 +19,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llwindow/llwindow_vc9.vcproj b/linden/indra/llwindow/llwindow_vc9.vcproj index 89998cd..991c296 100644 --- a/linden/indra/llwindow/llwindow_vc9.vcproj +++ b/linden/indra/llwindow/llwindow_vc9.vcproj @@ -1,398 +1,398 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llwindow/llwindowmacosx.cpp b/linden/indra/llwindow/llwindowmacosx.cpp index b458d7f..b616595 100644 --- a/linden/indra/llwindow/llwindowmacosx.cpp +++ b/linden/indra/llwindow/llwindowmacosx.cpp @@ -42,6 +42,7 @@ #include "llgl.h" #include "llstring.h" #include "lldir.h" +#include "llviewercontrol.h" #include "llglheaders.h" @@ -800,22 +801,24 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits } aglSetInteger(mContext, AGL_SWAP_INTERVAL, &frames_per_swap); -#if 0 // SJB: Got a compile error. Plus I don't want to test this along with everything else ; save it for later //enable multi-threaded OpenGL - CGLError cgl_err; - CGLContextObj ctx = CGLGetCurrentContext(); - - cgl_err = CGLEnable( ctx, kCGLCEMPEngine); - - if (cgl_err != kCGLNoError ) - { - llinfos << "Multi-threaded OpenGL not available." << llendl; - } - else + if (gSavedSettings.getBOOL("RenderAppleUseMultGL")) { - llinfos << "Multi-threaded OpenGL enabled." << llendl; + CGLError cgl_err; + CGLContextObj ctx = CGLGetCurrentContext(); + + cgl_err = CGLEnable( ctx, kCGLCEMPEngine); + + if (cgl_err != kCGLNoError ) + { + llinfos << "Multi-threaded OpenGL not available." << llendl; + } + else + { + llinfos << "Multi-threaded OpenGL enabled." << llendl; + } } -#endif + // Don't need to get the current gamma, since there's a call that restores it to the system defaults. return TRUE; } @@ -2740,6 +2743,9 @@ const char* cursorIDToName(int id) case UI_CURSOR_TOOLBUY: return "UI_CURSOR_TOOLBUY"; case UI_CURSOR_TOOLPAY: return "UI_CURSOR_TOOLPAY"; case UI_CURSOR_TOOLOPEN: return "UI_CURSOR_TOOLOPEN"; + case UI_CURSOR_TOOLPLAY: return "UI_CURSOR_TOOLPLAY"; + case UI_CURSOR_TOOLPAUSE: return "UI_CURSOR_TOOLPAUSE"; + case UI_CURSOR_TOOLMEDIAOPEN: return "UI_CURSOR_TOOLMEDIAOPEN"; case UI_CURSOR_PIPETTE: return "UI_CURSOR_PIPETTE"; } @@ -2836,6 +2842,9 @@ void LLWindowMacOSX::setCursor(ECursorType cursor) case UI_CURSOR_TOOLBUY: case UI_CURSOR_TOOLPAY: case UI_CURSOR_TOOLOPEN: + case UI_CURSOR_TOOLPLAY: + case UI_CURSOR_TOOLPAUSE: + case UI_CURSOR_TOOLMEDIAOPEN: result = setImageCursor(gCursors[cursor]); break; @@ -2878,6 +2887,9 @@ void LLWindowMacOSX::initCursors() initPixmapCursor(UI_CURSOR_TOOLBUY, 1, 1); initPixmapCursor(UI_CURSOR_TOOLPAY, 1, 1); initPixmapCursor(UI_CURSOR_TOOLOPEN, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLPLAY, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLPAUSE, 1, 1); + initPixmapCursor(UI_CURSOR_TOOLMEDIAOPEN, 1, 1); initPixmapCursor(UI_CURSOR_SIZENWSE, 10, 10); initPixmapCursor(UI_CURSOR_SIZENESW, 10, 10); diff --git a/linden/indra/llwindow/llwindowsdl.cpp b/linden/indra/llwindow/llwindowsdl.cpp index 7d42bce..f8a87c4 100644 --- a/linden/indra/llwindow/llwindowsdl.cpp +++ b/linden/indra/llwindow/llwindowsdl.cpp @@ -116,7 +116,9 @@ BOOL ll_try_gtk_init(void) if (!tried_gtk_init) { tried_gtk_init = TRUE; +#if LL_GSTREAMER_ENABLED if (!g_thread_supported ()) g_thread_init (NULL); +#endif // LL_GSTREAMER_ENABLED maybe_lock_display(); gtk_is_good = gtk_init_check(NULL, NULL); maybe_unlock_display(); @@ -503,6 +505,9 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); #if !LL_SOLARIS SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bits <= 16) ? 16 : 24); + // We need stencil support for a few (minor) things. + if (!getenv("LL_GL_NO_STENCIL")) + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); #else // NOTE- use smaller Z-buffer to enable more graphics cards // - This should not affect better GPUs and has been proven @@ -585,6 +590,11 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B } mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN); + if (!mWindow && bits > 16) + { + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN); + } if (mWindow) { @@ -627,6 +637,11 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B llinfos << "createContext: creating window " << width << "x" << height << "x" << bits << llendl; mWindow = SDL_SetVideoMode(width, height, bits, sdlflags); + if (!mWindow && bits > 16) + { + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + mWindow = SDL_SetVideoMode(width, height, bits, sdlflags); + } if (!mWindow) { @@ -1985,7 +2000,7 @@ void LLWindowSDL::gatherInput() static Uint32 lastRightDown = 0; SDL_Event event; -#if LL_GTK && LL_LIBXUL_ENABLED +#if LL_GTK && LL_LLMOZLIB_ENABLED // Pump GTK events so embedded Gecko doesn't starve. if (ll_try_gtk_init()) { @@ -2004,7 +2019,7 @@ void LLWindowSDL::gatherInput() setlocale(LC_ALL, saved_locale.c_str() ); } -#endif // LL_GTK && LL_LIBXUL_ENABLED +#endif // LL_GTK && LL_LLMOZLIB_ENABLED // Handle all outstanding SDL events while (SDL_PollEvent(&event)) @@ -2358,6 +2373,9 @@ void LLWindowSDL::initCursors() mSDLCursors[UI_CURSOR_TOOLBUY] = makeSDLCursorFromBMP("toolbuy.BMP",0,0); mSDLCursors[UI_CURSOR_TOOLPAY] = makeSDLCursorFromBMP("toolpay.BMP",0,0); mSDLCursors[UI_CURSOR_TOOLOPEN] = makeSDLCursorFromBMP("toolopen.BMP",0,0); + mSDLCursors[UI_CURSOR_TOOLPLAY] = makeSDLCursorFromBMP("toolplay.BMP",0,0); + mSDLCursors[UI_CURSOR_TOOLPAUSE] = makeSDLCursorFromBMP("toolpause.BMP",0,0); + mSDLCursors[UI_CURSOR_TOOLMEDIAOPEN] = makeSDLCursorFromBMP("toolmediaopen.BMP",0,0); mSDLCursors[UI_CURSOR_PIPETTE] = makeSDLCursorFromBMP("lltoolpipette.BMP",2,28); } @@ -2744,20 +2762,27 @@ void spawn_web_browser(const char* escaped_url) void *LLWindowSDL::getPlatformWindow() { -#if LL_GTK && LL_LIBXUL_ENABLED +#if LL_GTK && LL_LLMOZLIB_ENABLED if (ll_try_gtk_init()) { maybe_lock_display(); - GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL); - // show the hidden-widget while debugging (needs mozlib change) - //gtk_widget_show_all(GTK_WIDGET(win)); - - gtk_widget_realize(GTK_WIDGET(win)); + GtkWidget *owin = gtk_window_new(GTK_WINDOW_POPUP); + // Why a layout widget? A MozContainer would be ideal, but + // it involves exposing Mozilla headers to mozlib-using apps. + // A layout widget with a GtkWindow parent has the desired + // properties of being plain GTK, having a window, and being + // derived from a GtkContainer. + GtkWidget *rtnw = gtk_layout_new(NULL, NULL); + gtk_container_add(GTK_CONTAINER(owin), rtnw); + gtk_widget_realize(rtnw); + GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(rtnw), GTK_NO_WINDOW); + maybe_unlock_display(); - return win; + + return rtnw; } -#endif // LL_GTK && LL_LIBXUL_ENABLED +#endif // LL_GTK && LL_LLMOZLIB_ENABLED // Unixoid mozilla really needs GTK. return NULL; } diff --git a/linden/indra/llwindow/llwindowwin32.cpp b/linden/indra/llwindow/llwindowwin32.cpp index 4ad044b..3f33f1a 100644 --- a/linden/indra/llwindow/llwindowwin32.cpp +++ b/linden/indra/llwindow/llwindowwin32.cpp @@ -44,6 +44,7 @@ // Require DirectInput version 8 #define DIRECTINPUT_VERSION 0x0800 + #include @@ -428,7 +429,7 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width, mhInstance = GetModuleHandle(NULL); mWndProc = NULL; - mSwapMethod = SWAP_METHOD_UNDEFINED; + mSwapMethod = SWAP_METHOD_EXCHANGE; // No WPARAM yet. mLastSizeWParam = 0; @@ -774,7 +775,7 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width, attrib_list[cur_attrib++] = GL_TRUE; attrib_list[cur_attrib++] = WGL_COLOR_BITS_ARB; - attrib_list[cur_attrib++] = 24; + attrib_list[cur_attrib++] = 32; attrib_list[cur_attrib++] = WGL_RED_BITS_ARB; attrib_list[cur_attrib++] = 8; @@ -1018,6 +1019,11 @@ LLWindowWin32::LLWindowWin32(char *title, char *name, S32 x, S32 y, S32 width, // based on the system's (or user's) default settings. allowLanguageTextInput(NULL, FALSE); + initInputDevices(); +} + +void LLWindowWin32::initInputDevices() +{ // Direct Input HRESULT hr; @@ -1753,6 +1759,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, LLCoordScreen size, BOOL disa SetWindowLong(mWindowHandle, GWL_USERDATA, (U32)this); show(); + initInputDevices(); + // ok to post quit messages now mPostQuit = TRUE; return TRUE; @@ -1907,6 +1915,9 @@ void LLWindowWin32::initCursors() mCursor[UI_CURSOR_TOOLBUY] = loadColorCursor(TEXT("TOOLBUY")); mCursor[UI_CURSOR_TOOLPAY] = loadColorCursor(TEXT("TOOLPAY")); mCursor[UI_CURSOR_TOOLOPEN] = loadColorCursor(TEXT("TOOLOPEN")); + mCursor[UI_CURSOR_TOOLPLAY] = loadColorCursor(TEXT("TOOLPLAY")); + mCursor[UI_CURSOR_TOOLPAUSE] = loadColorCursor(TEXT("TOOLPAUSE")); + mCursor[UI_CURSOR_TOOLMEDIAOPEN] = loadColorCursor(TEXT("TOOLMEDIAOPEN")); // Note: custom cursors that are not found make LoadCursor() return NULL. for( S32 i = 0; i < UI_CURSOR_COUNT; i++ ) @@ -3196,6 +3207,8 @@ void LLWindowWin32::updateJoystick( ) mJoyAxis[3] = js.lRx/1000.f; mJoyAxis[4] = js.lRy/1000.f; mJoyAxis[5] = js.lRz/1000.f; + mJoyAxis[6] = js.rglSlider[0]/1000.f; + mJoyAxis[7] = js.rglSlider[1]/1000.f; for (U32 i = 0; i < 16; i++) { diff --git a/linden/indra/llwindow/llwindowwin32.h b/linden/indra/llwindow/llwindowwin32.h index 3f78dca..f159d30 100644 --- a/linden/indra/llwindow/llwindowwin32.h +++ b/linden/indra/llwindow/llwindowwin32.h @@ -122,6 +122,7 @@ protected: ~LLWindowWin32(); void initCursors(); + void initInputDevices(); HCURSOR loadColorCursor(LPCTSTR name); BOOL isValid(); void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size); diff --git a/linden/indra/llxml/llcontrol.cpp b/linden/indra/llxml/llcontrol.cpp index d185987..5504a10 100644 --- a/linden/indra/llxml/llcontrol.cpp +++ b/linden/indra/llxml/llcontrol.cpp @@ -69,8 +69,6 @@ std::set LLControlBase::mChangedControls; const S32 CURRENT_VERSION = 101; -BOOL control_insert_before( LLControlBase* first, LLControlBase* second ); - BOOL LLControl::llsd_compare(const LLSD& a, const LLSD & b) { switch (mType) @@ -1033,6 +1031,13 @@ U32 LLControlGroup::loadFromFile(const LLString& filename, BOOL require_declarat return validitems; } +struct compare_controls +{ + bool operator() (const LLControlBase* const a, const LLControlBase* const b) const + { + return a->getName() < b->getName(); + } +}; U32 LLControlGroup::saveToFile(const LLString& filename, BOOL nondefault_only) { @@ -1042,13 +1047,14 @@ U32 LLControlGroup::saveToFile(const LLString& filename, BOOL nondefault_only) // place the objects in a temporary container that enforces a sort // order to ease manual editing of the file - LLLinkedList< LLControlBase > controls; - controls.setInsertBefore( &control_insert_before ); - LLString name; + + typedef std::set< LLControlBase*, compare_controls > control_list_t; + control_list_t controls; + for (ctrl_name_table_t::iterator iter = mNameTable.begin(); iter != mNameTable.end(); iter++) { - name = iter->first; + LLString name = iter->first; if (name.empty()) { CONTROL_ERRS << "Control with no name found!!!" << llendl; @@ -1065,7 +1071,7 @@ U32 LLControlGroup::saveToFile(const LLString& filename, BOOL nondefault_only) { if (!(nondefault_only && (control->mIsDefault))) { - controls.addDataSorted( control ); + controls.insert( control ); } else { @@ -1088,12 +1094,12 @@ U32 LLControlGroup::saveToFile(const LLString& filename, BOOL nondefault_only) // Write file version file << "\n"; file << "\n"; - for( LLControlBase* control = controls.getFirstData(); - control != NULL; - control = controls.getNextData() ) + for (control_list_t::iterator iter = controls.begin(); + iter != controls.end(); ++iter) { + LLControlBase* control = *iter; file << "\t" << ENDL; - name = control->name(); + LLString name = control->getName(); switch (control->type()) { case TYPE_U32: @@ -1165,7 +1171,7 @@ U32 LLControlGroup::saveToFile(const LLString& filename, BOOL nondefault_only) file << "\n"; file.close(); - return controls.getLength(); + return controls.size(); } void LLControlGroup::applyOverrides(const std::map& overrides) @@ -1435,8 +1441,3 @@ void main() } #endif -BOOL control_insert_before( LLControlBase* first, LLControlBase* second ) -{ - return ( first->getName().compare(second->getName()) < 0 ); -} - diff --git a/linden/indra/llxml/llxml_vc8.vcproj b/linden/indra/llxml/llxml_vc8.vcproj index a049d41..b39ae53 100644 --- a/linden/indra/llxml/llxml_vc8.vcproj +++ b/linden/indra/llxml/llxml_vc8.vcproj @@ -1,279 +1,279 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llxml/llxml_vc9.vcproj b/linden/indra/llxml/llxml_vc9.vcproj index e4553e8..eb719c9 100644 --- a/linden/indra/llxml/llxml_vc9.vcproj +++ b/linden/indra/llxml/llxml_vc9.vcproj @@ -1,280 +1,280 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/llxml/llxmlnode.cpp b/linden/indra/llxml/llxmlnode.cpp index 275b6c2..757e2f7 100644 --- a/linden/indra/llxml/llxmlnode.cpp +++ b/linden/indra/llxml/llxmlnode.cpp @@ -3024,80 +3024,65 @@ LLXMLNodePtr LLXMLNode::getNextSibling() LLString LLXMLNode::getTextContents() const { std::string msg; - LLXMLNodeList p_children; - getChildren("p", p_children); - if (p_children.size() > 0) - { - // Case 1: node has

text

tags - LLXMLNodeList::iterator itor; - for (itor = p_children.begin(); itor != p_children.end(); ++itor) - { - LLXMLNodePtr p = itor->second; - msg += p->getValue() + "\n"; - } - } - else - { - LLString contents = mValue; - std::string::size_type n = contents.find_first_not_of(" \t\n"); - if (n != std::string::npos && contents[n] == '\"') - { - // Case 2: node has quoted text - S32 num_lines = 0; + LLString contents = mValue; + std::string::size_type n = contents.find_first_not_of(" \t\n"); + if (n != std::string::npos && contents[n] == '\"') + { + // Case 1: node has quoted text + S32 num_lines = 0; + while(1) + { + // mContents[n] == '"' + ++n; + std::string::size_type t = n; + std::string::size_type m = 0; + // fix-up escaped characters while(1) { - // mContents[n] == '"' - ++n; - std::string::size_type t = n; - std::string::size_type m = 0; - // fix-up escaped characters - while(1) - { - m = contents.find_first_of("\\\"", t); // find first \ or " - if ((m == std::string::npos) || (contents[m] == '\"')) - { - break; - } - contents.erase(m,1); - t = m+1; - } - if (m == std::string::npos) + m = contents.find_first_of("\\\"", t); // find first \ or " + if ((m == std::string::npos) || (contents[m] == '\"')) { break; } - // mContents[m] == '"' - num_lines++; - msg += contents.substr(n,m-n) + "\n"; - n = contents.find_first_of("\"", m+1); - if (n == std::string::npos) + contents.erase(m,1); + t = m+1; + } + if (m == std::string::npos) + { + break; + } + // mContents[m] == '"' + num_lines++; + msg += contents.substr(n,m-n) + "\n"; + n = contents.find_first_of("\"", m+1); + if (n == std::string::npos) + { + if (num_lines == 1) { - if (num_lines == 1) - { - msg.erase(msg.size()-1); // remove "\n" if only one line - } - break; + msg.erase(msg.size()-1); // remove "\n" if only one line } + break; } } - else + } + else + { + // Case 2: node has embedded text (beginning and trailing whitespace trimmed) + LLString::size_type start = mValue.find_first_not_of(" \t\n"); + if (start != mValue.npos) { - // Case 3: node has embedded text (beginning and trailing whitespace trimmed) - LLString::size_type start = mValue.find_first_not_of(" \t\n"); - if (start != mValue.npos) + LLString::size_type end = mValue.find_last_not_of(" \t\n"); + if (end != mValue.npos) { - LLString::size_type end = mValue.find_last_not_of(" \t\n"); - if (end != mValue.npos) - { - msg = mValue.substr(start, end+1-start); - } - else - { - msg = mValue.substr(start); - } + msg = mValue.substr(start, end+1-start); + } + else + { + msg = mValue.substr(start); } - // Convert any internal CR to LF - msg = utf8str_removeCRLF(msg); } + // Convert any internal CR to LF + msg = utf8str_removeCRLF(msg); } return msg; } diff --git a/linden/indra/lscript/lscript_byteconvert.h b/linden/indra/lscript/lscript_byteconvert.h index 42f71e8..a9b0094 100644 --- a/linden/indra/lscript/lscript_byteconvert.h +++ b/linden/indra/lscript/lscript_byteconvert.h @@ -162,13 +162,19 @@ inline void bytestream_int2float(U8 *stream, S32 &offset) float2bytestream(stream, offset, fpvalue); } -inline void bytestream2char(char *buffer, const U8 *stream, S32 &offset) +// Returns true on success, return false and clip copy on buffer overflow +inline bool bytestream2char(char *buffer, const U8 *stream, S32 &offset, S32 buffsize) { - while ((*buffer++ = *(stream + offset++))) - ; + S32 source_len = strlen( (const char *)stream+offset ); + strncpy( buffer, (const char *)stream+offset, buffsize-1 ); + buffer[buffsize-1] = 0; + + offset += source_len + 1; // advance past source string, include terminating '\0' + + return source_len < buffsize; } -inline void char2bytestream(U8 *stream, S32 &offset, char *buffer) +inline void char2bytestream(U8 *stream, S32 &offset, const char *buffer) { while ((*(stream + offset++) = *buffer++)) ; @@ -1065,11 +1071,30 @@ inline void safe_instruction_float2bytestream(U8 *stream, S32 &offset, F32 value } } -inline void safe_instruction_bytestream2char(char *buffer, U8 *stream, S32 &offset) +inline void safe_instruction_bytestream2char(char *buffer, U8 *stream, S32 &offset, S32 buffsize) { - while ( (safe_instruction_check_address(stream, offset, 1)) + bool safe; + while ( (safe = safe_instruction_check_address(stream, offset, 1)) + && buffsize-- &&(*buffer++ = *(stream + offset++))) ; + + // Return if it ended in a null (success) or if script error handling is taking over + if( !safe || (0 == *(buffer-1)) ) + { + return; // Yep. Success. + } + + // Defensive mode. We copied at least one char and ran out of space before + // null termination. Add the terminator... + *(buffer-1) = 0; + + // ...and advance offset past the end of the data as if we copied the rest. If we + // violate the safety check, script error handling will protect us. No need to + // keep advancing. + while( safe_instruction_check_address(stream, offset, 1) + && *( stream + offset++ ) ) + ; } inline void safe_instruction_bytestream_count_char(U8 *stream, S32 &offset) diff --git a/linden/indra/lscript/lscript_compile/indra.l b/linden/indra/lscript/lscript_compile/indra.l index 57aef07..c8458a3 100644 --- a/linden/indra/lscript/lscript_compile/indra.l +++ b/linden/indra/lscript/lscript_compile/indra.l @@ -36,6 +36,7 @@ FS (f|F) #include "llparcelflags.h" #include "llregionflags.h" #include "lscript_http.h" +#include "llclickaction.h" void count(); void comment(); @@ -522,6 +523,10 @@ extern "C" { int yyerror(const char *fmt, ...); } "PARCEL_MEDIA_COMMAND_AGENT" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_AGENT; return(INTEGER_CONSTANT); } "PARCEL_MEDIA_COMMAND_UNLOAD" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_UNLOAD; return(INTEGER_CONSTANT); } "PARCEL_MEDIA_COMMAND_AUTO_ALIGN" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_AUTO_ALIGN; return(INTEGER_CONSTANT); } +"PARCEL_MEDIA_COMMAND_TYPE" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_TYPE; return(INTEGER_CONSTANT); } +"PARCEL_MEDIA_COMMAND_SIZE" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_SIZE; return(INTEGER_CONSTANT); } +"PARCEL_MEDIA_COMMAND_DESC" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_DESC; return(INTEGER_CONSTANT); } +"PARCEL_MEDIA_COMMAND_LOOP_SET" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_LOOP_SET; return(INTEGER_CONSTANT); } "LIST_STAT_MAX" { count(); yylval.ival = LIST_STAT_MAX; return(INTEGER_CONSTANT); } "LIST_STAT_MIN" { count(); yylval.ival = LIST_STAT_MIN; return(INTEGER_CONSTANT); } @@ -587,6 +592,15 @@ extern "C" { int yyerror(const char *fmt, ...); } "STRING_TRIM_TAIL" { count(); yylval.ival = STRING_TRIM_TAIL; return(INTEGER_CONSTANT); } "STRING_TRIM" { count(); yylval.ival = STRING_TRIM; return(INTEGER_CONSTANT); } +"CLICK_ACTION_NONE" { count(); yylval.ival = CLICK_ACTION_NONE; return(INTEGER_CONSTANT); } +"CLICK_ACTION_TOUCH" { count(); yylval.ival = CLICK_ACTION_TOUCH; return(INTEGER_CONSTANT); } +"CLICK_ACTION_SIT" { count(); yylval.ival = CLICK_ACTION_SIT; return(INTEGER_CONSTANT); } +"CLICK_ACTION_BUY" { count(); yylval.ival = CLICK_ACTION_BUY; return(INTEGER_CONSTANT); } +"CLICK_ACTION_PAY" { count(); yylval.ival = CLICK_ACTION_PAY; return(INTEGER_CONSTANT); } +"CLICK_ACTION_OPEN" { count(); yylval.ival = CLICK_ACTION_OPEN; return(INTEGER_CONSTANT); } +"CLICK_ACTION_PLAY" { count(); yylval.ival = CLICK_ACTION_PLAY; return(INTEGER_CONSTANT); } +"CLICK_ACTION_OPEN_MEDIA" { count(); yylval.ival = CLICK_ACTION_OPEN_MEDIA; return(INTEGER_CONSTANT); } + {L}({L}|{N})* { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(IDENTIFIER); } {N}+{E} { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); } diff --git a/linden/indra/lscript/lscript_compile/lscript_compile_fb_vc8.vcproj b/linden/indra/lscript/lscript_compile/lscript_compile_fb_vc8.vcproj index 901a191..91561b9 100644 --- a/linden/indra/lscript/lscript_compile/lscript_compile_fb_vc8.vcproj +++ b/linden/indra/lscript/lscript_compile/lscript_compile_fb_vc8.vcproj @@ -1,133 +1,131 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/lscript/lscript_compile/lscript_compile_fb_vc9.vcproj b/linden/indra/lscript/lscript_compile/lscript_compile_fb_vc9.vcproj index adfd694..62f3ada 100644 --- a/linden/indra/lscript/lscript_compile/lscript_compile_fb_vc9.vcproj +++ b/linden/indra/lscript/lscript_compile/lscript_compile_fb_vc9.vcproj @@ -1,132 +1,132 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/lscript/lscript_compile/lscript_compile_ly_vc8.vcproj b/linden/indra/lscript/lscript_compile/lscript_compile_ly_vc8.vcproj index baa202a..f55385e 100644 --- a/linden/indra/lscript/lscript_compile/lscript_compile_ly_vc8.vcproj +++ b/linden/indra/lscript/lscript_compile/lscript_compile_ly_vc8.vcproj @@ -1,131 +1,131 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/lscript/lscript_compile/lscript_compile_vc8.vcproj b/linden/indra/lscript/lscript_compile/lscript_compile_vc8.vcproj index 919d290..0622c32 100644 --- a/linden/indra/lscript/lscript_compile/lscript_compile_vc8.vcproj +++ b/linden/indra/lscript/lscript_compile/lscript_compile_vc8.vcproj @@ -1,331 +1,331 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/lscript/lscript_compile/lscript_compile_vc9.vcproj b/linden/indra/lscript/lscript_compile/lscript_compile_vc9.vcproj index 4831422..581c99e 100644 --- a/linden/indra/lscript/lscript_compile/lscript_compile_vc9.vcproj +++ b/linden/indra/lscript/lscript_compile/lscript_compile_vc9.vcproj @@ -1,332 +1,332 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/lscript/lscript_execute/lscript_execute.cpp b/linden/indra/lscript/lscript_execute/lscript_execute.cpp index 1d2438c..d1200f0 100644 --- a/linden/indra/lscript/lscript_execute/lscript_execute.cpp +++ b/linden/indra/lscript/lscript_execute/lscript_execute.cpp @@ -1333,7 +1333,7 @@ BOOL run_pushargs(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) S32 size = toffset - offset; char *arg = new char[size]; offset++; - safe_instruction_bytestream2char(arg, buffer, offset); + safe_instruction_bytestream2char(arg, buffer, offset, size); if (b_print) printf("%s\n", arg); S32 address = lsa_heap_add_data(buffer, new LLScriptLibData(arg), get_max_heap_size(buffer), TRUE); @@ -2753,7 +2753,7 @@ BOOL run_jumpif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; char *sdata = new char[size]; - bytestream2char(sdata, buffer, string); + bytestream2char(sdata, buffer, string, size); if (strlen(sdata)) /*Flawfinder: ignore*/ { offset += arg; @@ -2781,7 +2781,7 @@ BOOL run_jumpif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; char *sdata = new char[size]; - bytestream2char(sdata, buffer, string); + bytestream2char(sdata, buffer, string, size); if (strlen(sdata)) /*Flawfinder: ignore*/ { LLUUID id; @@ -2880,7 +2880,7 @@ BOOL run_jumpnif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; char *sdata = new char[size]; - bytestream2char(sdata, buffer, string); + bytestream2char(sdata, buffer, string, size); if (!strlen(sdata)) /*Flawfinder: ignore*/ { offset += arg; @@ -2908,7 +2908,7 @@ BOOL run_jumpnif(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; char *sdata = new char[size]; - bytestream2char(sdata, buffer, string); + bytestream2char(sdata, buffer, string, size); if (strlen(sdata)) /*Flawfinder: ignore*/ { LLUUID id; @@ -3182,7 +3182,7 @@ BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; char *arg = new char[size]; - bytestream2char(arg, buffer, string); + bytestream2char(arg, buffer, string, size); // S32 length = strlen(arg); S32 dest; S32 base; @@ -3225,7 +3225,7 @@ BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; char *arg = new char[size]; - bytestream2char(arg, buffer, string); + bytestream2char(arg, buffer, string, size); F32 dest = (F32)atof(arg); @@ -3265,7 +3265,7 @@ BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; char *arg = new char[size]; - bytestream2char(arg, buffer, string); + bytestream2char(arg, buffer, string, size); LLVector3 vec; S32 num = sscanf(arg, "<%f, %f, %f>", &vec.mV[VX], &vec.mV[VY], &vec.mV[VZ]); if (num != 3) @@ -3295,7 +3295,7 @@ BOOL run_cast(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; char *arg = new char[size]; - bytestream2char(arg, buffer, string); + bytestream2char(arg, buffer, string, size); LLQuaternion quat; S32 num = sscanf(arg, "<%f, %f, %f, %f>", &quat.mQ[VX], &quat.mQ[VY], &quat.mQ[VZ], &quat.mQ[VW]); if (num != 4) @@ -3496,7 +3496,7 @@ void lscript_stacktol_pop_variable(LLScriptLibData *data, U8 *buffer, char type) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; data->mKey = new char[size]; - bytestream2char(data->mKey, buffer, string); + bytestream2char(data->mKey, buffer, string, size); } lsa_decrease_ref_count(buffer, base_address); } @@ -3523,7 +3523,7 @@ void lscript_stacktol_pop_variable(LLScriptLibData *data, U8 *buffer, char type) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; data->mString = new char[size]; - bytestream2char(data->mString, buffer, string); + bytestream2char(data->mString, buffer, string, size); } lsa_decrease_ref_count(buffer, base_address); } @@ -3623,7 +3623,7 @@ BOOL run_print(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; char *arg = new char[size]; - bytestream2char(arg, buffer, string); + bytestream2char(arg, buffer, string, size); printf("%s\n", arg); delete [] arg; } @@ -3787,7 +3787,7 @@ void lscript_pop_variable(LLScriptLibData *data, U8 *buffer, char type) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; data->mKey = new char[size]; - bytestream2char(data->mKey, buffer, string); + bytestream2char(data->mKey, buffer, string, size); } lsa_decrease_ref_count(buffer, base_address); } @@ -3814,7 +3814,7 @@ void lscript_pop_variable(LLScriptLibData *data, U8 *buffer, char type) safe_heap_bytestream_count_char(buffer, toffset); S32 size = toffset - string; data->mString = new char[size]; - bytestream2char(data->mString, buffer, string); + bytestream2char(data->mString, buffer, string, size); } lsa_decrease_ref_count(buffer, base_address); } diff --git a/linden/indra/lscript/lscript_execute/lscript_execute_vc8.vcproj b/linden/indra/lscript/lscript_execute/lscript_execute_vc8.vcproj index 2314e6a..8a1e4c6 100644 --- a/linden/indra/lscript/lscript_execute/lscript_execute_vc8.vcproj +++ b/linden/indra/lscript/lscript_execute/lscript_execute_vc8.vcproj @@ -1,279 +1,279 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/lscript/lscript_execute/lscript_execute_vc9.vcproj b/linden/indra/lscript/lscript_execute/lscript_execute_vc9.vcproj index 9c6f7e3..eb41122 100644 --- a/linden/indra/lscript/lscript_execute/lscript_execute_vc9.vcproj +++ b/linden/indra/lscript/lscript_execute/lscript_execute_vc9.vcproj @@ -1,280 +1,280 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/lscript/lscript_execute/lscript_readlso.cpp b/linden/indra/lscript/lscript_execute/lscript_readlso.cpp index b6d5092..218e14a 100644 --- a/linden/indra/lscript/lscript_execute/lscript_readlso.cpp +++ b/linden/indra/lscript/lscript_execute/lscript_readlso.cpp @@ -155,7 +155,7 @@ void LLScriptLSOParse::printGlobals(FILE *fp) type = *(mRawData + global_v_offset++); // set name - bytestream2char(name, mRawData, global_v_offset); + bytestream2char(name, mRawData, global_v_offset, sizeof(name)); switch(type) { @@ -261,7 +261,7 @@ void LLScriptLSOParse::printGlobalFunctions(FILE *fp) // where do the opcodes start opcode_start = bytestream2integer(mRawData, function_offset); opcode_start += orig_function_offset; - bytestream2char(name, mRawData, function_offset); + bytestream2char(name, mRawData, function_offset, sizeof(name)); // get return type type = *(mRawData + function_offset++); fprintf(fp, "[Function #%d] [0x%X] %s\n", function_number, orig_function_offset, name); @@ -272,7 +272,7 @@ void LLScriptLSOParse::printGlobalFunctions(FILE *fp) S32 pcount = 0; while (type) { - bytestream2char(name, mRawData, function_offset); + bytestream2char(name, mRawData, function_offset, sizeof(name)); fprintf(fp, "\tParameter #%d: %s %s\n", pcount++, LSCRIPTTypeNames[type], name); type = *(mRawData + function_offset++); } @@ -336,7 +336,7 @@ void LLScriptLSOParse::printStates(FILE *fp) state_info_offset += state_offset; fprintf(fp, "[0x%X] ", state_info_offset); state_info_offset += LSCRIPTDataSize[LST_INTEGER]; - bytestream2char(name, mRawData, state_info_offset); + bytestream2char(name, mRawData, state_info_offset, sizeof(name)); fprintf(fp, "%s\n", name); event_jump_table = state_info_offset; @@ -385,243 +385,243 @@ void LLScriptLSOParse::printStates(FILE *fp) switch(j) { case LSTT_STATE_ENTRY: // LSTT_STATE_ENTRY - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); break; case LSTT_STATE_EXIT: // LSTT_STATE_EXIT - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); break; case LSTT_TOUCH_START: // LSTT_TOUCH_START - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); break; case LSTT_TOUCH: // LSTT_TOUCH - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); break; case LSTT_TOUCH_END: // LSTT_TOUCH_END - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); break; case LSTT_COLLISION_START: // LSTT_COLLISION_START - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); break; case LSTT_COLLISION: // LSTT_COLLISION - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); break; case LSTT_COLLISION_END: // LSTT_COLLISION_END - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); break; case LSTT_LAND_COLLISION_START: // LSTT_LAND_COLLISION_START - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); break; case LSTT_LAND_COLLISION: // LSTT_LAND_COLLISION - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); break; case LSTT_LAND_COLLISION_END: // LSTT_LAND_COLLISION_END - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); break; case LSTT_INVENTORY: // LSTT_INVENTORY - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); break; case LSTT_ATTACH: // LSTT_ATTACH - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); break; case LSTT_DATASERVER: // LSTT_DATASERVER - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tstring %s\n", name); break; case LSTT_TIMER: // LSTT_TIMER - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); break; case LSTT_MOVING_START: // LSTT_MOVING_START - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); break; case LSTT_MOVING_END: // LSTT_MOVING_END - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); break; case LSTT_CHAT: // LSTT_CHAT - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tstring %s\n", name); break; case LSTT_OBJECT_REZ: // LSTT_OBJECT_REZ - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); break; case LSTT_REMOTE_DATA: // LSTT_REMOTE_DATA - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tstring %s\n", name); break; case LSTT_REZ: // LSTT_REZ - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); break; case LSTT_SENSOR: // LSTT_SENSOR - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); break; case LSTT_NO_SENSOR: // LSTT_NO_SENSOR - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); break; case LSTT_CONTROL: // LSTT_CONTROL - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); break; case LSTT_LINK_MESSAGE: // LSTT_LINK_MESSAGE - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tstring %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); break; case LSTT_MONEY: // LSTT_MONEY - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); break; case LSTT_EMAIL: // LSTT_EMAIL - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tstring %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tstring %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tstring %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); break; case LSTT_AT_TARGET: // LSTT_AT_TARGET - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tvector %s\n", name); break; case LSTT_NOT_AT_TARGET: // LSTT_NOT_AT_TARGET - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); break; case LSTT_AT_ROT_TARGET: // LSTT_AT_ROT_TARGET - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tquaternion %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tquaternion %s\n", name); break; case LSTT_NOT_AT_ROT_TARGET: // LSTT_NOT_AT_TARGET - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); break; case LSTT_RTPERMISSIONS: // LSTT_RTPERMISSIONS - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); fprintf(fp, "\t\tinteger %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); break; case LSTT_HTTP_RESPONSE: // LSTT_REMOTE_DATA ?!?!?! - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "%s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tkey %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tinteger %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tlist %s\n", name); - bytestream2char(name, mRawData, event_offset); + bytestream2char(name, mRawData, event_offset, sizeof(name)); fprintf(fp, "\t\tstring %s\n", name); break; default: @@ -1210,7 +1210,7 @@ void print_pushargs(FILE *fp, U8 *buffer, S32 &offset, S32 tabs) char arg[1024]; /*Flawfinder: ignore*/ lso_print_tabs(fp, tabs); fprintf(fp, "[0x%X]\tPUSHARGS ", offset++); - bytestream2char(arg, buffer, offset); + bytestream2char(arg, buffer, offset, sizeof(arg)); fprintf(fp, "%s\n", arg); } diff --git a/linden/indra/lscript/lscript_library.h b/linden/indra/lscript/lscript_library.h index 10ba7fa..458ab25 100644 --- a/linden/indra/lscript/lscript_library.h +++ b/linden/indra/lscript/lscript_library.h @@ -278,7 +278,7 @@ public: break; case LST_KEY: { - bytestream2char(temp, src, offset); + bytestream2char(temp, src, offset, sizeof(temp)); mKey = new char[strlen(temp) + 1]; /* Flawfinder: ignore */ if (mKey == NULL) { @@ -290,7 +290,7 @@ public: break; case LST_STRING: { - bytestream2char(temp, src, offset); + bytestream2char(temp, src, offset, sizeof(temp)); mString = new char[strlen(temp) + 1]; /* Flawfinder: ignore */ if (mString == NULL) { @@ -327,7 +327,7 @@ public: break; case LST_KEY: { - bytestream2char(temp, src, offset); + bytestream2char(temp, src, offset, sizeof(temp)); mKey = new char[strlen(temp) + 1]; /* Flawfinder: ignore */ if (mKey == NULL) { @@ -339,7 +339,7 @@ public: break; case LST_STRING: { - bytestream2char(temp, src, offset); + bytestream2char(temp, src, offset, sizeof(temp)); mString = new char[strlen(temp) + 1]; /* Flawfinder: ignore */ if (mString == NULL) { diff --git a/linden/indra/lscript/lscript_library/lscript_alloc.cpp b/linden/indra/lscript/lscript_library/lscript_alloc.cpp index a39edda..2c37d22 100644 --- a/linden/indra/lscript/lscript_library/lscript_alloc.cpp +++ b/linden/indra/lscript/lscript_library/lscript_alloc.cpp @@ -131,10 +131,12 @@ S32 lsa_heap_add_data(U8 *buffer, LLScriptLibData *data, S32 heapsize, BOOL b_de size = 4; break; case LST_KEY: - size = (S32)strlen(data->mKey) + 1; /*Flawfinder: ignore*/ + // NOTE: babbage: defensive as some library calls set data to NULL + size = data->mKey ? (S32)strlen(data->mKey) + 1 : 1; /*Flawfinder: ignore*/ break; case LST_STRING: - size = (S32)strlen(data->mString) + 1; /*Flawfinder: ignore*/ + // NOTE: babbage: defensive as some library calls set data to NULL + size = data->mString ? (S32)strlen(data->mString) + 1 : 1; /*Flawfinder: ignore*/ break; case LST_LIST: // list data 4 bytes of number of entries followed by number of pointer @@ -294,10 +296,10 @@ void lsa_insert_data(U8 *buffer, S32 &offset, LLScriptLibData *data, LLScriptAll float2bytestream(buffer, offset, data->mFP); break; case LST_KEY: - char2bytestream(buffer, offset, data->mKey); + char2bytestream(buffer, offset, data->mKey ? data->mKey : ""); break; case LST_STRING: - char2bytestream(buffer, offset, data->mString); + char2bytestream(buffer, offset, data->mString ? data->mString : ""); break; case LST_VECTOR: vector2bytestream(buffer, offset, data->mVec); @@ -524,7 +526,7 @@ void lsa_decrease_ref_count(U8 *buffer, S32 offset) alloc_entry2bytestream(buffer, orig_offset, entry); } -char gLSAStringRead[16384]; /*Flawfinder: ignore*/ +char gLSAStringRead[TOP_OF_MEMORY]; /*Flawfinder: ignore*/ LLScriptLibData *lsa_get_data(U8 *buffer, S32 &offset, BOOL b_dec_ref) @@ -564,12 +566,12 @@ LLScriptLibData *lsa_get_data(U8 *buffer, S32 &offset, BOOL b_dec_ref) retval->mFP = bytestream2float(buffer, offset); break; case LST_KEY: - bytestream2char(gLSAStringRead, buffer, offset); + bytestream2char(gLSAStringRead, buffer, offset, sizeof(gLSAStringRead)); // global sring buffer? for real? :( retval->mKey = new char[strlen(gLSAStringRead) + 1]; /*Flawfinder: ignore*/ strcpy(retval->mKey, gLSAStringRead); /*Flawfinder: ignore*/ break; case LST_STRING: - bytestream2char(gLSAStringRead, buffer, offset); + bytestream2char(gLSAStringRead, buffer, offset, sizeof(gLSAStringRead)); retval->mString = new char[strlen(gLSAStringRead) + 1]; /*Flawfinder: ignore*/ strcpy(retval->mString, gLSAStringRead); /*Flawfinder: ignore*/ break; @@ -816,11 +818,11 @@ void lsa_print_heap(U8 *buffer) printf("%f\n", fpvalue); break; case LST_STRING: - bytestream2char(string, buffer, readoffset); + bytestream2char(string, buffer, readoffset, sizeof(string)); printf("%s\n", string); break; case LST_KEY: - bytestream2char(string, buffer, readoffset); + bytestream2char(string, buffer, readoffset, sizeof(string)); printf("%s\n", string); break; case LST_VECTOR: @@ -883,11 +885,11 @@ void lsa_fprint_heap(U8 *buffer, FILE *fp) fprintf(fp, "%f\n", fpvalue); break; case LST_STRING: - bytestream2char(string, buffer, readoffset); + bytestream2char(string, buffer, readoffset, sizeof(string)); fprintf(fp, "%s\n", string); break; case LST_KEY: - bytestream2char(string, buffer, readoffset); + bytestream2char(string, buffer, readoffset, sizeof(string)); fprintf(fp, "%s\n", string); break; case LST_VECTOR: diff --git a/linden/indra/lscript/lscript_library/lscript_library.cpp b/linden/indra/lscript/lscript_library/lscript_library.cpp index 594a001..14019d0 100644 --- a/linden/indra/lscript/lscript_library/lscript_library.cpp +++ b/linden/indra/lscript/lscript_library/lscript_library.cpp @@ -29,7 +29,15 @@ * $/LicenseInfo$ */ -// *WARNING* + +// ## ## ### ######## ## ## #### ## ## ###### #### #### +// ## ## ## ## ## ## ## ### ## ## ### ## ## ## #### #### +// ## ## ## ## ## ## ## #### ## ## #### ## ## #### #### +// ## ## ## ## ## ######## ## ## ## ## ## ## ## ## #### ## ## +// ## ## ## ######### ## ## ## #### ## ## #### ## ## +// ## ## ## ## ## ## ## ## ### ## ## ### ## ## #### #### +// ### ### ## ## ## ## ## ## #### ## ## ###### #### #### +// // When adding functions, they MUST be appended to the end of // the init() method. The init() associates the name with a number, // which is then serialized into the bytecode. Inserting a new @@ -431,6 +439,8 @@ void LLScriptLibrary::init() addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetObjectDetails", "l", "kl", "list llGetObjectDetails(key id, list params)\nGets the object details specified in params for the object with key id.\nDetails are OBJECT_NAME, _DESC, _POS, _ROT, _VELOCITY, _OWNER, _GROUP, _CREATOR.")); + addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetClickAction", NULL, "i", "llSetClickAction(integer action)\nSets the action performed when a prim is clicked upon.")); + // energy, sleep, dummy_func, name, return type, parameters, help text, gods-only // IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST. diff --git a/linden/indra/lscript/lscript_library/lscript_library_vc8.vcproj b/linden/indra/lscript/lscript_library/lscript_library_vc8.vcproj index 371f880..38a951b 100644 --- a/linden/indra/lscript/lscript_library/lscript_library_vc8.vcproj +++ b/linden/indra/lscript/lscript_library/lscript_library_vc8.vcproj @@ -1,271 +1,271 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/lscript/lscript_library/lscript_library_vc9.vcproj b/linden/indra/lscript/lscript_library/lscript_library_vc9.vcproj index 031b67d..63ffbac 100644 --- a/linden/indra/lscript/lscript_library/lscript_library_vc9.vcproj +++ b/linden/indra/lscript/lscript_library/lscript_library_vc9.vcproj @@ -1,272 +1,272 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/newview/English.lproj/InfoPlist.strings b/linden/indra/newview/English.lproj/InfoPlist.strings index 608a6ad..5bca4ea 100644 --- a/linden/indra/newview/English.lproj/InfoPlist.strings +++ b/linden/indra/newview/English.lproj/InfoPlist.strings @@ -1,5 +1,5 @@ /* Localized versions of Info.plist keys */ CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 1.19.0.5"; -CFBundleGetInfoString = "Second Life version 1.19.0.5, Copyright 2004-2007 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 1.19.1.0"; +CFBundleGetInfoString = "Second Life version 1.19.1.0, Copyright 2004-2008 Linden Research, Inc."; diff --git a/linden/indra/newview/Info-SecondLife.plist b/linden/indra/newview/Info-SecondLife.plist index e257d6f..6f8c464 100644 --- a/linden/indra/newview/Info-SecondLife.plist +++ b/linden/indra/newview/Info-SecondLife.plist @@ -32,7 +32,7 @@ CFBundleVersion - 1.19.0.5 + 1.19.1.0 CSResourcesFileMapped diff --git a/linden/indra/newview/app_settings/colors_base.xml b/linden/indra/newview/app_settings/colors_base.xml index c68487b..ded1eb2 100644 --- a/linden/indra/newview/app_settings/colors_base.xml +++ b/linden/indra/newview/app_settings/colors_base.xml @@ -64,6 +64,9 @@ + + + @@ -153,6 +156,14 @@ + + + + + + + + @@ -162,7 +173,7 @@ - + diff --git a/linden/indra/newview/app_settings/high_graphics.xml b/linden/indra/newview/app_settings/high_graphics.xml new file mode 100644 index 0000000..6368f70 --- /dev/null +++ b/linden/indra/newview/app_settings/high_graphics.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/newview/app_settings/keywords.ini b/linden/indra/newview/app_settings/keywords.ini index 5a68c5b..0800647 100644 --- a/linden/indra/newview/app_settings/keywords.ini +++ b/linden/indra/newview/app_settings/keywords.ini @@ -422,7 +422,10 @@ PARCEL_MEDIA_COMMAND_PLAY Play media stream PARCEL_MEDIA_COMMAND_LOOP Loop media stream PARCEL_MEDIA_COMMAND_TEXTURE Get or set the parcel's media texture PARCEL_MEDIA_COMMAND_URL Get or set the parcel's media url +PARCEL_MEDIA_COMMAND_TYPE Get or set the parcel's media mimetype +PARCEL_MEDIA_COMMAND_DESC Get or set the parcel's media description PARCEL_MEDIA_COMMAND_TIME Set media stream to specific time +PARCEL_MEDIA_COMMAND_SIZE Get or set the parcel's media pixel resolution PARCEL_MEDIA_COMMAND_AGENT Allows media stream commands to apply to only one agent PARCEL_MEDIA_COMMAND_UNLOAD Unloads the media stream PARCEL_MEDIA_COMMAND_AUTO_ALIGN Auto aligns the media stream to the texture size. May cause a performance hit and loss of some visual quality. @@ -492,6 +495,15 @@ STRING_TRIM_HEAD Used with llStringTrim to trim leading spaces from a string. STRING_TRIM_TAIL Used with llStringTrim to trim trailing spaces from a string. STRING_TRIM Used with llStringTrim to trim both leading and trailing spaces from a string. +CLICK_ACTION_NONE Used with llSetClickAction to disable the click action +CLICK_ACTION_TOUCH Used with llSetClickAction to set touch as the default action when object is clicked +CLICK_ACTION_SIT Used with llSetClickAction to set sit as the default action when object is clicked +CLICK_ACTION_BUY Used with llSetClickAction to set buy as the default action when object is clicked +CLICK_ACTION_PAY Used with llSetClickAction to set pay as the default action when object is clicked +CLICK_ACTION_OPEN Used with llSetClickAction to set open as the default action when object is clicked +CLICK_ACTION_PLAY Used with llSetClickAction to set play as the default action when object is clicked +CLICK_ACTION_OPEN_MEDIA Used with llSetClickAction to set open-media as the default action when object is clicked + # string constants [word .1, .3, .5] NULL_KEY Indicates an empty key diff --git a/linden/indra/newview/app_settings/low_graphics.xml b/linden/indra/newview/app_settings/low_graphics.xml new file mode 100644 index 0000000..3f67a70 --- /dev/null +++ b/linden/indra/newview/app_settings/low_graphics.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/newview/app_settings/mid_graphics.xml b/linden/indra/newview/app_settings/mid_graphics.xml new file mode 100644 index 0000000..12da77d --- /dev/null +++ b/linden/indra/newview/app_settings/mid_graphics.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl b/linden/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl index 5731add..b6cc7f7 100644 --- a/linden/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl @@ -1,3 +1,10 @@ +/** + * @file avatarF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + void default_lighting(); void main() diff --git a/linden/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/linden/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl index 1fcc001..292dbfd 100644 --- a/linden/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl @@ -1,4 +1,9 @@ -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color); +/** + * @file avatarSkinV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ attribute vec4 weight; //1 diff --git a/linden/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl b/linden/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl index 50f9b01..ee3410d 100644 --- a/linden/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl @@ -1,9 +1,13 @@ -void default_scatter(vec3 viewVec, vec3 lightDir); +/** + * @file avatarV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); mat4 getSkinnedTransform(); -vec2 getScatterCoord(vec3 viewVec, vec3 lightDir); - -attribute vec4 materialColor; +void calcAtmospherics(vec3 inPositionEye); void main() { @@ -24,12 +28,16 @@ void main() norm = normalize(norm); gl_Position = gl_ProjectionMatrix * pos; - + //gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - default_scatter(pos.xyz, gl_LightSource[0].position.xyz); + gl_FogFragCoord = length(pos.xyz); - vec4 color = calcLighting(pos.xyz, norm, materialColor, gl_Color); + calcAtmospherics(pos.xyz); + + vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0,0,0,0)); gl_FrontColor = color; } + + diff --git a/linden/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl b/linden/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl index 5731add..4d93c19 100644 --- a/linden/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl @@ -1,3 +1,10 @@ +/** + * @file eyeballF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + void default_lighting(); void main() diff --git a/linden/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl b/linden/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl index d436b4e..b3c988a 100644 --- a/linden/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl @@ -1,7 +1,12 @@ -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec3 baseCol); -void default_scatter(vec3 viewVec, vec3 lightDir); +/** + * @file eyeballV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ -attribute vec4 materialColor; +vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); void main() { @@ -12,9 +17,11 @@ void main() vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz; vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - vec4 color = calcLighting(pos, norm, materialColor, gl_Color.rgb); - default_scatter(pos, gl_LightSource[0].position.xyz); - + calcAtmospherics(pos.xyz); + + vec4 specular = vec4(1.0); + vec4 color = calcLightingSpecular(pos, norm, gl_Color, specular, vec4(0.0)); gl_FrontColor = color; + } diff --git a/linden/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl b/linden/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl index b311afb..2019300 100644 --- a/linden/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl @@ -1,3 +1,10 @@ +/** + * @file pickAvatarF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + uniform sampler2D diffuseMap; void main() diff --git a/linden/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl b/linden/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl index b6dcbe1..12d8f9d 100644 --- a/linden/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl @@ -1,4 +1,10 @@ -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color); +/** + * @file pickAvatarV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + mat4 getSkinnedTransform(); void main() @@ -14,4 +20,4 @@ void main() gl_FrontColor = gl_Color; gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = gl_ProjectionMatrix * pos; -} \ No newline at end of file +} diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl new file mode 100644 index 0000000..dbdfe11 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl @@ -0,0 +1,28 @@ +/** + * @file glowExtractF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseMap; +uniform float minLuminance; +uniform float maxExtractAlpha; +uniform vec3 lumWeights; +uniform vec3 warmthWeights; +uniform float warmthAmount; + +void main() +{ + vec4 col = texture2DRect(diffuseMap, gl_TexCoord[0].xy); + + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + float lum = smoothstep(minLuminance, 1.0, dot(col.rgb, lumWeights ) ); + float warmth = smoothstep(minLuminance, 1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) ); + + gl_FragColor.rgb = col.rgb; + gl_FragColor.a = max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl new file mode 100644 index 0000000..61dfd2f --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl @@ -0,0 +1,14 @@ +/** + * @file glowExtractV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + +void main() +{ + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + + gl_TexCoord[0].xy = gl_MultiTexCoord0.xy; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/glowF.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/glowF.glsl new file mode 100644 index 0000000..21c7ad7 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/effects/glowF.glsl @@ -0,0 +1,31 @@ +/** + * @file glowF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; +uniform float glowStrength; + +void main() +{ + + vec4 col = vec4(0.0, 0.0, 0.0, 0.0); + + // ATI compiler falls down on array initialization. + float kern[8]; + kern[0] = 0.25; kern[1] = 0.5; kern[2] = 0.8; kern[3] = 1.0; + kern[4] = 1.0; kern[5] = 0.8; kern[6] = 0.5; kern[7] = 0.25; + + col += kern[0] * texture2D(diffuseMap, gl_TexCoord[0].xy); + col += kern[1] * texture2D(diffuseMap, gl_TexCoord[1].xy); + col += kern[2] * texture2D(diffuseMap, gl_TexCoord[2].xy); + col += kern[3] * texture2D(diffuseMap, gl_TexCoord[3].xy); + col += kern[4] * texture2D(diffuseMap, gl_TexCoord[0].zw); + col += kern[5] * texture2D(diffuseMap, gl_TexCoord[1].zw); + col += kern[6] * texture2D(diffuseMap, gl_TexCoord[2].zw); + col += kern[7] * texture2D(diffuseMap, gl_TexCoord[3].zw); + + gl_FragColor = vec4(col.rgb * glowStrength, col.a); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/glowV.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/glowV.glsl new file mode 100644 index 0000000..13ce7c7 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/effects/glowV.glsl @@ -0,0 +1,22 @@ +/** + * @file glowV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform vec2 glowDelta; + +void main() +{ + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + + gl_TexCoord[0].xy = gl_MultiTexCoord0.xy + glowDelta*(-3.5); + gl_TexCoord[1].xy = gl_MultiTexCoord0.xy + glowDelta*(-2.5); + gl_TexCoord[2].xy = gl_MultiTexCoord0.xy + glowDelta*(-1.5); + gl_TexCoord[3].xy = gl_MultiTexCoord0.xy + glowDelta*(-0.5); + gl_TexCoord[0].zw = gl_MultiTexCoord0.xy + glowDelta*(0.5); + gl_TexCoord[1].zw = gl_MultiTexCoord0.xy + glowDelta*(1.5); + gl_TexCoord[2].zw = gl_MultiTexCoord0.xy + glowDelta*(2.5); + gl_TexCoord[3].zw = gl_MultiTexCoord0.xy + glowDelta*(3.5); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/glowF.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/glowF.glsl deleted file mode 100644 index 670b976..0000000 --- a/linden/indra/newview/app_settings/shaders/class1/environment/glowF.glsl +++ /dev/null @@ -1,14 +0,0 @@ -uniform sampler2D diffuseMap; - -void main() -{ - vec4 color1 = texture2D(diffuseMap, gl_TexCoord[0].xy); - vec4 color2 = texture2D(diffuseMap, gl_TexCoord[1].xy); - vec4 color3 = texture2D(diffuseMap, gl_TexCoord[2].xy); - vec4 color4 = texture2D(diffuseMap, gl_TexCoord[3].xy); - vec4 color5 = texture2D(diffuseMap, gl_TexCoord[4].xy); - - vec4 col = (color1+color2+color3+color4+color5)*0.21; - col = max(col, col*0.25 + color5*0.75); - gl_FragColor = col; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/glowV.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/glowV.glsl deleted file mode 100644 index 3b1a72e..0000000 --- a/linden/indra/newview/app_settings/shaders/class1/environment/glowV.glsl +++ /dev/null @@ -1,10 +0,0 @@ -uniform float delta; -void main() -{ - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - gl_TexCoord[0].xy = gl_MultiTexCoord0.xy + vec2(delta, delta); - gl_TexCoord[1].xy = gl_MultiTexCoord0.xy + vec2(-delta, delta); - gl_TexCoord[2].xy = gl_MultiTexCoord0.xy + vec2(-delta, -delta); - gl_TexCoord[3].xy = gl_MultiTexCoord0.xy + vec2(delta, -delta); - gl_TexCoord[4].xy = gl_MultiTexCoord0.xy; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/groundF.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/groundF.glsl deleted file mode 100644 index ef81b07..0000000 --- a/linden/indra/newview/app_settings/shaders/class1/environment/groundF.glsl +++ /dev/null @@ -1,5 +0,0 @@ - -void main() -{ - gl_FragColor = gl_Color; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/groundV.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/groundV.glsl deleted file mode 100644 index e227c58..0000000 --- a/linden/indra/newview/app_settings/shaders/class1/environment/groundV.glsl +++ /dev/null @@ -1,6 +0,0 @@ - -void main() -{ - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - gl_FrontColor = gl_Fog.color; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/scatterF.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/scatterF.glsl deleted file mode 100644 index 3aa44de..0000000 --- a/linden/indra/newview/app_settings/shaders/class1/environment/scatterF.glsl +++ /dev/null @@ -1,17 +0,0 @@ -uniform sampler2D scatterMap; - -//for per-pixel scatter -vec4 getScatter(vec3 viewVec, vec3 lightDir) -{ - return gl_TexCoord[5]; -} - -void applyScatter(inout vec3 color) -{ - color = gl_TexCoord[5].a*color + (1.0-gl_TexCoord[5].a) * gl_TexCoord[5].rgb; -} - -void applyScatter(inout vec3 color, vec4 haze) -{ - color.rgb = haze.rgb + haze.a * color.rgb; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/scatterV.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/scatterV.glsl deleted file mode 100644 index 19dc2b8..0000000 --- a/linden/indra/newview/app_settings/shaders/class1/environment/scatterV.glsl +++ /dev/null @@ -1,15 +0,0 @@ - - -vec2 getScatterCoord(vec3 viewVec, vec3 lightDir) -{ - vec2 scatterCoord = vec2(0,0); - return scatterCoord; -} - -void default_scatter(vec3 viewVec, vec3 lightDir) -{ - float f = gl_Fog.density * (gl_ModelViewProjectionMatrix * gl_Vertex).z; - f = clamp(exp2(-f),0.0,1.0); - gl_TexCoord[5].a = f; - gl_TexCoord[5].rgb = gl_Fog.color.rgb; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl index fde3701..2278c69 100644 --- a/linden/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl @@ -1,9 +1,13 @@ -void terrain_lighting(inout vec3 color); - -uniform sampler2D detail0; //0 -uniform sampler2D detail1; //2 -uniform sampler2D alphaRamp; //1 +/** + * @file terrainF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +uniform sampler2D detail0; +uniform sampler2D detail1; +uniform sampler2D alphaRamp; void main() { @@ -12,8 +16,6 @@ void main() texture2D(detail0, gl_TexCoord[0].xy).rgb, a); - terrain_lighting(color); - gl_FragColor.rgb = color; gl_FragColor.a = texture2D(alphaRamp, gl_TexCoord[3].xy).a; } diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl index 3153a80..112d669 100644 --- a/linden/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl @@ -1,7 +1,11 @@ -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); -void default_scatter(vec3 viewVec, vec3 lightDir); +/** + * @file terrainV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ -attribute vec4 materialColor; +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) { @@ -25,7 +29,7 @@ void main() vec4 pos = gl_ModelViewMatrix * gl_Vertex; vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - vec4 color = calcLighting(pos.xyz, norm, materialColor, gl_Color); + vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), gl_Color); gl_FrontColor = color; @@ -33,5 +37,4 @@ void main() gl_TexCoord[1] = gl_TextureMatrix[1]*gl_MultiTexCoord1; gl_TexCoord[2] = texgen_object(gl_Vertex,gl_MultiTexCoord2,gl_TextureMatrix[2],gl_ObjectPlaneS[2],gl_ObjectPlaneT[2]); gl_TexCoord[3] = gl_TextureMatrix[3]*gl_MultiTexCoord3; - default_scatter(pos.xyz, gl_LightSource[0].position.xyz); } diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl new file mode 100644 index 0000000..e2f68e8 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl @@ -0,0 +1,23 @@ +/** + * @file terrainWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +// this class1 shader is just a copy of terrainF + +uniform sampler2D detail0; +uniform sampler2D detail1; +uniform sampler2D alphaRamp; + +void main() +{ + float a = texture2D(alphaRamp, gl_TexCoord[1].xy).a; + vec3 color = mix(texture2D(detail1, gl_TexCoord[2].xy).rgb, + texture2D(detail0, gl_TexCoord[0].xy).rgb, + a); + + gl_FragColor.rgb = color; + gl_FragColor.a = texture2D(alphaRamp, gl_TexCoord[3].xy).a; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl new file mode 100644 index 0000000..f1740a4 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl @@ -0,0 +1,45 @@ +/** + * @file underWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; +uniform sampler2D bumpMap; +uniform sampler2D screenTex; + +uniform float refScale; +uniform vec4 waterFogColor; + +//bigWave is (refCoord.w, view.w); +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; + +void main() +{ + vec4 color; + + //get bigwave normal + vec3 wavef = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0; + + //get detail normals + vec3 dcol = texture2D(bumpMap, littleWave.xy).rgb*0.75; + dcol += texture2D(bumpMap, littleWave.zw).rgb*1.25; + + //interpolate between big waves and little waves (big waves in deep water) + wavef = (wavef+dcol)*0.5; + + //crunch normal to range [-1,1] + wavef -= vec3(1,1,1); + + //figure out distortion vector (ripply) + vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; + distort = distort+wavef.xy*refScale; + + vec4 fb = texture2D(screenTex, distort); + + gl_FragColor.rgb = mix(waterFogColor.rgb, fb.rgb, waterFogColor.a * 0.001 + 0.999); + gl_FragColor.a = fb.a; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/waterF.glsl index f8b8031..1c14381 100644 --- a/linden/indra/newview/app_settings/shaders/class1/environment/waterF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/environment/waterF.glsl @@ -1,22 +1,94 @@ -void water_lighting(inout vec3 diff); +/** + * @file waterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec3 scaleSoftClip(vec3 inColor); +vec3 atmosTransport(vec3 inColor); -uniform samplerCube environmentMap; uniform sampler2D diffuseMap; -uniform sampler2D bumpMap; +uniform sampler2D bumpMap; +uniform sampler2D screenTex; +uniform sampler2D refTex; + +uniform float sunAngle; +uniform float sunAngle2; +uniform float scaledAngle; +uniform vec3 lightDir; +uniform vec3 specular; +uniform float lightExp; +uniform float refScale; +uniform float kd; +uniform vec2 screenRes; +uniform vec3 normScale; +uniform float fresnelScale; +uniform float fresnelOffset; +uniform float blurMultiplier; +uniform vec4 fogCol; -varying vec4 specular; +//bigWave is (refCoord.w, view.w); +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; void main() { - vec4 depth = texture2D(diffuseMap, gl_TexCoord[0].xy); - vec4 diff = texture2D(bumpMap, gl_TexCoord[1].xy); - vec3 ref = textureCube(environmentMap, gl_TexCoord[2].xyz).rgb; + vec3 viewVec = view.xyz; + vec4 color; + + float dist = length(viewVec.xy); + + //normalize view vector + viewVec = normalize(viewVec); + + //get wave normals + vec3 wavef = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0; + + //get detail normals + vec3 dcol = texture2D(bumpMap, littleWave.xy).rgb*0.75; + dcol += texture2D(bumpMap, littleWave.zw).rgb*1.25; + + //interpolate between big waves and little waves (big waves in deep water) + wavef = (wavef + dcol) * 0.5; + + //crunch normal to range [-1,1] + wavef -= vec3(1,1,1); + wavef = normalize(wavef); + + //get base fresnel components - diff.rgb *= depth.rgb; + float df = dot(viewVec,wavef) * fresnelScale + fresnelOffset; + + vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; + + float dist2 = dist; + dist = max(dist, 5.0); + + //get reflected color + vec2 refdistort = wavef.xy*dot(normScale, vec3(0.333)); + vec2 refvec = distort+refdistort/dist; + vec4 refcol = texture2D(refTex, refvec); + + //get specular component + float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); + + //harden specular + spec = pow(spec, lightExp); + + //figure out distortion vector (ripply) + vec2 distort2 = distort+wavef.xy*refScale/max(dist*df, 1.0); - vec3 col = mix(diff.rgb, ref, specular.a)+specular.rgb*diff.rgb; + vec4 fb = texture2D(screenTex, distort2); + + //mix with reflection + color.rgb = mix(mix(fogCol.rgb, fb.rgb, fogCol.a), refcol.rgb, df); + color.rgb += spec * specular; - water_lighting(col.rgb); - gl_FragColor.rgb = col.rgb; - gl_FragColor.a = (gl_Color.a+depth.a)*0.5; + color.rgb = atmosTransport(color.rgb); + color.rgb = scaleSoftClip(color.rgb); + color.a = spec * sunAngle2; + + gl_FragColor = color; } diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl new file mode 100644 index 0000000..59e44fa --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl @@ -0,0 +1,20 @@ +/** + * @file waterFogF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec4 applyWaterFog(vec4 color) +{ + // GL_EXP2 Fog + float fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord); + // GL_EXP Fog + // float fog = exp(-gl_Fog.density * gl_FogFragCoord); + // GL_LINEAR Fog + // float fog = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale; + fog = clamp(fog, 0.0, 1.0); + color.rgb = mix(gl_Fog.color.rgb, color.rgb, fog); + return color; +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/linden/indra/newview/app_settings/shaders/class1/environment/waterV.glsl index 873a6fc..d332798 100644 --- a/linden/indra/newview/app_settings/shaders/class1/environment/waterV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/environment/waterV.glsl @@ -1,41 +1,73 @@ -void default_scatter(vec3 viewVec, vec3 lightDir); -vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec3 baseCol); -vec2 getScatterCoord(vec3 viewVec, vec3 lightDir); +/** + * @file waterV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ -varying vec4 specular; +void calcAtmospherics(vec3 inPositionEye); -vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) +uniform vec2 d1; +uniform vec2 d2; +uniform float time; +uniform vec3 eyeVec; +uniform float waterHeight; + +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; + +float wave(vec2 v, float t, float f, vec2 d, float s) { - vec4 tcoord; - - tcoord.x = dot(vpos, tp0); - tcoord.y = dot(vpos, tp1); - tcoord.z = tc.z; - tcoord.w = tc.w; - - tcoord = mat * tcoord; - - return tcoord; + return (dot(d, v)*f + t*s)*f; } void main() { //transform vertex - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_TexCoord[1] = texgen_object(gl_Vertex, gl_MultiTexCoord1, gl_TextureMatrix[1], gl_ObjectPlaneS[1],gl_ObjectPlaneT[1]); + vec4 position = gl_Vertex; + mat4 modelViewProj = gl_ModelViewProjectionMatrix; - vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz; - vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - vec4 spec = gl_Color; - gl_FrontColor.rgb = calcLightingSpecular(pos, norm, gl_Color, spec, vec3(0.0, 0.0, 0.0)).rgb; - gl_FrontColor.a = gl_Color.a; - specular = spec; - specular.a = gl_Color.a*0.5; - vec3 ref = reflect(pos,norm); + vec4 oPosition; + + //get view vector + vec3 oEyeVec; + oEyeVec.xyz = position.xyz-eyeVec; + + float d = length(oEyeVec.xy); + float ld = min(d, 2560.0); - gl_TexCoord[2] = gl_TextureMatrix[2]*vec4(ref,1); + position.xy = eyeVec.xy + oEyeVec.xy/d*ld; + view.xyz = oEyeVec; + + d = clamp(ld/1536.0-0.5, 0.0, 1.0); + d *= d; - default_scatter(pos.xyz, gl_LightSource[0].position.xyz); + oPosition = position; + oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d); + oPosition = modelViewProj * oPosition; + refCoord.xyz = oPosition.xyz + vec3(0,0,0.2); + + //get wave position parameter (create sweeping horizontal waves) + vec3 v = position.xyz; + v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0; + + //push position for further horizon effect. + position.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z); + position.w = 1.0; + position = position*gl_ModelViewMatrix; + + calcAtmospherics((gl_ModelViewMatrix * gl_Vertex).xyz); + + + //pass wave parameters to pixel shader + vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055; + //get two normal map (detail map) texture coordinates + littleWave.xy = (v.xy) * vec2(0.6, 1.2) + d2 * time * 0.05; + // littleWave.zw = (v.xy) * vec2(0.07, 0.15) - d1 * time * 0.043; + littleWave.zw = (v.xy) * vec2(0.3, 0.6) + d1 * time * 0.1; + view.w = bigWave.y; + refCoord.w = bigWave.x; + + gl_Position = oPosition; } - diff --git a/linden/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl b/linden/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl index 1e342fb..328c416 100644 --- a/linden/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl @@ -1,3 +1,10 @@ +/** + * @file highlightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + uniform sampler2D diffuseMap; void main() diff --git a/linden/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl b/linden/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl index bb6707b..a9ea6e8 100644 --- a/linden/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl @@ -1,9 +1,14 @@ -attribute vec4 materialColor; +/** + * @file highlightV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ void main() { //transform vertex - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = ftransform(); vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz; pos = normalize(pos); float d = dot(pos, normalize(gl_NormalMatrix * gl_Normal)); @@ -11,10 +16,10 @@ void main() d = 1.0 - d; d *= d; - d = min(d, materialColor.a*2.0); + d = min(d, gl_Color.a*2.0); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - gl_FrontColor.rgb = materialColor.rgb; - gl_FrontColor.a = max(d, materialColor.a); + gl_FrontColor.rgb = gl_Color.rgb; + gl_FrontColor.a = max(d, gl_Color.a); } diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl index c169fce..9ab986b 100644 --- a/linden/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl @@ -1,31 +1,15 @@ -void applyScatter(inout vec3 color); +/** + * @file lightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ uniform sampler2D diffuseMap; void default_lighting() { - vec4 color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); - //applyScatter(color.rgb); + color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); gl_FragColor = color; } -void alpha_lighting() -{ - default_lighting(); -} - -void water_lighting(inout vec3 diff) -{ - applyScatter(diff); -} - -void terrain_lighting(inout vec3 color) -{ - color.rgb *= gl_Color.rgb; - applyScatter(color); -} - -vec4 getLightColor() -{ - return gl_Color; -} \ No newline at end of file diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl new file mode 100644 index 0000000..b12cca9 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl @@ -0,0 +1,15 @@ +/** + * @file lightFullbrightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + +uniform sampler2D diffuseMap; + +void fullbright_lighting() +{ + gl_FragColor = texture2D(diffuseMap, gl_TexCoord[0].xy); +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl new file mode 100644 index 0000000..bc795a7 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl @@ -0,0 +1,15 @@ +/** + * @file lightFullbrightShinyF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +void fullbright_shiny_lighting() +{ + gl_FragColor = texture2D(diffuseMap, gl_TexCoord[0].xy); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl new file mode 100644 index 0000000..b13088f --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl @@ -0,0 +1,15 @@ +/** + * @file lightFullbrightWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + +uniform sampler2D diffuseMap; + +void fullbright_lighting_water() +{ + gl_FragColor = texture2D(diffuseMap, gl_TexCoord[0].xy); +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl new file mode 100644 index 0000000..bbbd9f3 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl @@ -0,0 +1,46 @@ +/** + * @file lightFuncSpecularV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +float calcDirectionalLight(vec3 n, vec3 l) +{ + float a = max(dot(n,l),0.0); + return a; +} + +float calcDirectionalSpecular(vec3 view, vec3 n, vec3 l) +{ + return pow(max(dot(reflect(view, n),l), 0.0),8.0); +} + +float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da) +{ + + specular.rgb += calcDirectionalSpecular(view,n,l)*lightCol*da; + return max(dot(n,l),0.0); +} + +vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol) +{ + //get light vector + vec3 lv = l-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float da = clamp(1.0/(r * d), 0.0, 1.0); + + //angular attenuation + + da *= calcDirectionalLightSpecular(specular, view, n, lv, lightCol, da); + + return da*lightCol; +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl new file mode 100644 index 0000000..3e8fdfb --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl @@ -0,0 +1,34 @@ +/** + * @file lightFuncV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + +float calcDirectionalLight(vec3 n, vec3 l) +{ + float a = max(dot(n,l),0.0); + return a; +} + +float calcPointLight(vec3 v, vec3 n, vec4 lp, float la) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float da = clamp(1.0/(la * d), 0.0, 1.0); + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl new file mode 100644 index 0000000..c6f7f8b --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl @@ -0,0 +1,17 @@ +/** + * @file lightShinyF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +void shiny_lighting() +{ + color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + gl_FragColor = color; +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl new file mode 100644 index 0000000..75f61cc --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl @@ -0,0 +1,17 @@ +/** + * @file lightShinyWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +void shiny_lighting_water() +{ + color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + gl_FragColor = color; +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl new file mode 100644 index 0000000..8532129 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl @@ -0,0 +1,26 @@ +/** + * @file lightV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +float calcDirectionalLight(vec3 n, vec3 l); + +// Same as non-specular lighting in lightV.glsl +vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol) +{ + specularColor.rgb = vec3(0.0, 0.0, 0.0); + vec4 col; + col.a = color.a; + + col.rgb = gl_LightModel.ambient.rgb + baseCol.rgb; + + col.rgb += gl_LightSource[0].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[0].position.xyz); + col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); + + col.rgb = min(col.rgb*color.rgb, 1.0); + + return col; +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl index e381631..8c2813a 100644 --- a/linden/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl @@ -1,66 +1,11 @@ +/** + * @file lightV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ -float calcDirectionalLight(vec3 n, vec3 l) -{ - float a = max(dot(n,l),0.0); - return a; -} - -float calcPointLight(vec3 v, vec3 n, vec3 l, float r, float pw) -{ - //get light vector - vec3 lv = l-v; - - //get distance - float d = length(lv); - - //normalize light vector - lv *= 1.0/d; - - //distance attenuation - float da = max((r-d)/r, 0.0); - - //da = pow(da, pw); - - //angular attenuation - da *= calcDirectionalLight(n, lv); - - return da; -} - -float calcDirectionalSpecular(vec3 view, vec3 n, vec3 l) -{ - float a = max(dot(n,l),0.0); - return a; -} - -float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da) -{ - - specular.rgb += calcDirectionalSpecular(view,n,l)*lightCol*da; - return calcDirectionalLight(n,l); -} - -vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol) -{ - //get light vector - vec3 lv = l-v; - - //get distance - float d = length(lv); - - //normalize light vector - lv *= 1.0/d; - - //distance attenuation - float da = clamp((r-d)/r, 0.0, 1.0); - - //da = pow(da, pw); - - //angular attenuation - da *= calcDirectionalLightSpecular(specular, view, n, lv, lightCol, da); - - return da*lightCol; -} +float calcDirectionalLight(vec3 n, vec3 l); vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseLight) { @@ -77,23 +22,3 @@ vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseLight) return col; } -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec3 baseLight) -{ - return calcLighting(pos, norm, color, vec4(baseLight, 1.0)); -} - -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color) -{ - return calcLighting(pos, norm, color, vec3(0.0,0.0,0.0)); -} - -vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol) -{ - specularColor.rgb = vec3(0.0, 0.0, 0.0); - return calcLighting(pos, norm, color, baseCol); -} - -vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec3 baseCol) -{ - return calcLightingSpecular(pos, norm, color, specularColor, vec4(baseCol, 1.0)); -} diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl new file mode 100644 index 0000000..81dff1e --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl @@ -0,0 +1,15 @@ +/** + * @file lightWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +void default_lighting_water() +{ + vec4 color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + gl_FragColor = color; +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl new file mode 100644 index 0000000..218585f --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl @@ -0,0 +1,35 @@ +/** + * @file sumLightsSpecularV.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da); +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 atmosGetDiffuseSunlightColor(); +vec3 scaleDownLight(vec3 light); + +vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol) +{ + vec4 col; + col.a = color.a; + + + vec3 view = normalize(pos); + + /// collect all the specular values from each calcXXXLightSpecular() function + vec4 specularSum = vec4(0.0); + + col.rgb = gl_LightSource[1].diffuse.rgb * calcDirectionalLightSpecular(specularColor, view, norm, gl_LightSource[1].position.xyz, gl_LightSource[1].diffuse.rgb, 1.0); + col.rgb = scaleDownLight(col.rgb); + col.rgb += atmosAmbient(baseCol.rgb); + col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, gl_LightSource[0].position.xyz,atmosGetDiffuseSunlightColor() * baseCol.a, 1.0)); + + col.rgb = min(col.rgb * color.rgb, 1.0); + specularColor.rgb = min(specularColor.rgb * specularSum.rgb, 1.0); + + col.rgb += specularColor.rgb; + + return col; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl b/linden/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl new file mode 100644 index 0000000..e536103 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl @@ -0,0 +1,29 @@ +/** + * @file sumLightsV.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +float calcDirectionalLight(vec3 n, vec3 l); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); + +vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight) +{ + vec4 col; + col.a = color.a; + + col.rgb = gl_LightSource[1].diffuse.rgb * calcDirectionalLight(norm, gl_LightSource[1].position.xyz); + col.rgb = scaleDownLight(col.rgb); + col.rgb += atmosAmbient(baseLight.rgb); + col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz)); + + col.rgb = min(col.rgb*color.rgb, 1.0); + + return col; +} + + diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/alphaF.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/alphaF.glsl deleted file mode 100644 index 0d98f36..0000000 --- a/linden/indra/newview/app_settings/shaders/class1/objects/alphaF.glsl +++ /dev/null @@ -1,6 +0,0 @@ -void alpha_lighting(); - -void main() -{ - alpha_lighting(); -} diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/alphaV.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/alphaV.glsl deleted file mode 100644 index 91821f7..0000000 --- a/linden/indra/newview/app_settings/shaders/class1/objects/alphaV.glsl +++ /dev/null @@ -1,21 +0,0 @@ -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); -void default_scatter(vec3 viewVec, vec3 lightDir); - -attribute vec4 materialColor; - -void main() -{ - //transform vertex - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - gl_TexCoord[0] = gl_MultiTexCoord0; - - vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz; - vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - - default_scatter(pos, gl_LightSource[0].position.xyz); - - vec4 color = calcLighting(pos, norm, materialColor, gl_Color); - color.a = materialColor.a; - - gl_FrontColor = color; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/bumpshinyF.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/bumpshinyF.glsl deleted file mode 100644 index 8509c62..0000000 --- a/linden/indra/newview/app_settings/shaders/class1/objects/bumpshinyF.glsl +++ /dev/null @@ -1,18 +0,0 @@ -vec4 getLightColor(); -void applyScatter(inout vec3 col); - -uniform samplerCube environmentMap; -uniform sampler2D diffuseMap; - -void main() -{ - vec4 diff = texture2D(diffuseMap, gl_TexCoord[0].xy); - vec3 ref = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb; - vec4 specular = gl_TexCoord[2]; - vec3 col = mix(getLightColor().rgb * diff.rgb, ref, specular.a)+specular.rgb*diff.rgb; - - applyScatter(col); - - gl_FragColor.rgb = col; - gl_FragColor.a = diff.a*gl_Color.a; -} diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/bumpshinyV.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/bumpshinyV.glsl deleted file mode 100644 index 9a189a2..0000000 --- a/linden/indra/newview/app_settings/shaders/class1/objects/bumpshinyV.glsl +++ /dev/null @@ -1,25 +0,0 @@ -vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol); -void default_scatter(vec3 viewVec, vec3 lightDir); - -attribute vec4 materialColor; -attribute vec4 specularColor; - -void main() -{ - //transform vertex - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - gl_TexCoord[0] = gl_MultiTexCoord0; - - vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz; - vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - - vec4 spec = specularColor; - gl_FrontColor.rgb = calcLightingSpecular(pos, norm, materialColor, spec, gl_Color).rgb; - gl_FrontColor.a = materialColor.a; - gl_TexCoord[2] = spec; - vec3 ref = reflect(pos,norm); - gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1.0); - - default_scatter(pos.xyz, gl_LightSource[0].position.xyz); -} - diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl new file mode 100755 index 0000000..1b0ffb9 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl @@ -0,0 +1,13 @@ +/** + * @file fullbrightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void fullbright_lighting(); + +void main() +{ + fullbright_lighting(); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl new file mode 100644 index 0000000..936c228 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl @@ -0,0 +1,13 @@ +/** + * @file fullbrightShinyF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void fullbright_shiny_lighting(); + +void main() +{ + fullbright_shiny_lighting(); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl new file mode 100755 index 0000000..ba2aa02 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl @@ -0,0 +1,29 @@ +/** + * @file fullbrightShinyV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void calcAtmospherics(vec3 inPositionEye); + +uniform vec4 origin; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + + vec4 pos = (gl_ModelViewMatrix * gl_Vertex); + vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + vec3 ref = reflect(pos.xyz, -norm); + + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1.0); + + calcAtmospherics(pos.xyz); + + gl_FrontColor = gl_Color; + + gl_FogFragCoord = pos.z; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl new file mode 100755 index 0000000..e64ccb8 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl @@ -0,0 +1,23 @@ +/** + * @file fullbrightV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void calcAtmospherics(vec3 inPositionEye); + +void main() +{ + //transform vertex + gl_Position = ftransform(); + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + vec4 pos = (gl_ModelViewMatrix * gl_Vertex); + + calcAtmospherics(pos.xyz); + + gl_FrontColor = gl_Color; + + gl_FogFragCoord = pos.z; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl new file mode 100755 index 0000000..fd855aa --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl @@ -0,0 +1,13 @@ +/** + * @file fullbrightWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void fullbright_lighting_water(); + +void main() +{ + fullbright_lighting_water(); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl index 6942132..bdb0b05 100644 --- a/linden/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl @@ -1,13 +1,13 @@ -void applyScatter(inout vec3 col); +/** + * @file shinyF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ -uniform samplerCube environmentMap; +void shiny_lighting(); void main() { - vec3 ref = textureCube(environmentMap, gl_TexCoord[0].xyz).rgb; - - applyScatter(ref); - - gl_FragColor.rgb = ref; - gl_FragColor.a = gl_Color.a; + shiny_lighting(); } diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl index 16fba01..c2e1ddf 100644 --- a/linden/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl @@ -1,27 +1,30 @@ -void default_scatter(vec3 viewVec, vec3 lightDir); +/** + * @file shinyV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void calcAtmospherics(vec3 inPositionEye); uniform vec4 origin; void main() { //transform vertex - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = ftransform(); //gl_ModelViewProjectionMatrix * gl_Vertex; - vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz; + vec4 pos = (gl_ModelViewMatrix * gl_Vertex); vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + + calcAtmospherics(pos.xyz); gl_FrontColor = gl_Color; - vec3 ref = reflect(pos, norm); - - vec3 d = pos - origin.xyz; - float dist = dot(normalize(d), ref); - vec3 e = d + (ref * max(origin.w-dist, 0.0)); - - ref = e - origin.xyz; + vec3 ref = reflect(pos.xyz, -norm); gl_TexCoord[0] = gl_TextureMatrix[0]*vec4(ref,1.0); - default_scatter(pos.xyz, gl_LightSource[0].position.xyz); + gl_FogFragCoord = pos.z; } diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl new file mode 100755 index 0000000..0a2a5f6 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl @@ -0,0 +1,13 @@ +/** + * @file shinyWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void shiny_lighting_water(); + +void main() +{ + shiny_lighting_water(); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl index ce5ab12..7dacca4 100644 --- a/linden/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl @@ -1,3 +1,10 @@ +/** + * @file simpleF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + void default_lighting(); void main() diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl index 2aa3521..0df89c8 100644 --- a/linden/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl @@ -1,20 +1,26 @@ -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); -void default_scatter(vec3 viewVec, vec3 lightDir); +/** + * @file simpleV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ -attribute vec4 materialColor; +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); void main() { //transform vertex - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = ftransform(); //gl_ModelViewProjectionMatrix * gl_Vertex; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz; - vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + vec4 pos = (gl_ModelViewMatrix * gl_Vertex); - default_scatter(pos, gl_LightSource[0].position.xyz); + vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + + calcAtmospherics(pos.xyz); - vec4 color = calcLighting(pos, norm, materialColor, gl_Color); + vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); gl_FrontColor = color; gl_FogFragCoord = pos.z; diff --git a/linden/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl b/linden/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl new file mode 100755 index 0000000..e066b3d --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl @@ -0,0 +1,13 @@ +/** + * @file simpleWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void default_lighting_water(); + +void main() +{ + default_lighting_water(); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl new file mode 100644 index 0000000..248c322 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl @@ -0,0 +1,13 @@ +/** + * @file atmosphericsF.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec3 atmosLighting(vec3 light) +{ + /* stub function for fallback compatibility on class1 hardware */ + return light; +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl new file mode 100644 index 0000000..c2c39e2 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl @@ -0,0 +1,34 @@ +/** + * @file atmosphericsHelpersV.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec3 atmosAmbient(vec3 light) +{ + return gl_LightModel.ambient.rgb + light; +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ + return gl_LightSource[0].diffuse.rgb * lightIntensity; +} + +vec3 atmosGetDiffuseSunlightColor() +{ + return gl_LightSource[0].diffuse.rgb; +} + +vec3 scaleDownLight(vec3 light) +{ + /* stub function for fallback compatibility on class1 hardware */ + return light; +} + +vec3 scaleUpLight(vec3 light) +{ + /* stub function for fallback compatibility on class1 hardware */ + return light; +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl b/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl new file mode 100644 index 0000000..551b643 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl @@ -0,0 +1,15 @@ +/** + * @file atmosphericsV.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void setPositionEye(vec3 v); + +void calcAtmospherics(vec3 inPositionEye) +{ + /* stub function for fallback compatibility on class1 hardware */ + setPositionEye(inPositionEye); +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl new file mode 100644 index 0000000..c001a40 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl @@ -0,0 +1,13 @@ +/** + * @file atmosphericVarsF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec3 vary_PositionEye; + +vec3 getPositionEye() +{ + return vary_PositionEye; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl new file mode 100644 index 0000000..1b263b0 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl @@ -0,0 +1,19 @@ +/** + * @file atmosphericVarsV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec3 vary_PositionEye; + + +vec3 getPositionEye() +{ + return vary_PositionEye; +} + +void setPositionEye(vec3 v) +{ + vary_PositionEye = v; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl b/linden/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl new file mode 100644 index 0000000..c1ffda1 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl @@ -0,0 +1,19 @@ +/** + * @file gammaF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform vec4 gamma; + +/// Soft clips the light with a gamma correction +vec3 scaleSoftClip(vec3 light) { + // For compatibility with lower cards. Do nothing. + return light; +} + +vec3 fullbrightScaleSoftClip(vec3 light) { + return scaleSoftClip(light); +} + diff --git a/linden/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl b/linden/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl new file mode 100644 index 0000000..7097906 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl @@ -0,0 +1,26 @@ +/** + * @file transportF.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec3 atmosTransport(vec3 light) +{ + /* stub function for fallback compatibility on class1 hardware */ + return light; +} + +vec3 fullbrightAtmosTransport(vec3 light) +{ + /* stub function for fallback compatibility on class1 hardware */ + return light; +} + + +vec3 fullbrightShinyAtmosTransport(vec3 light) +{ + /* stub function for fallback compatibility on class1 hardware */ + return light; +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/avatar/avatarV.glsl b/linden/indra/newview/app_settings/shaders/class2/avatar/avatarV.glsl deleted file mode 100644 index b040143..0000000 --- a/linden/indra/newview/app_settings/shaders/class2/avatar/avatarV.glsl +++ /dev/null @@ -1,48 +0,0 @@ -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec3 baseCol); -mat4 getSkinnedTransform(); -void default_scatter(vec3 viewVec, vec3 lightDir); - -attribute vec4 materialColor; -attribute vec4 binormal; - -void main() -{ - gl_TexCoord[0] = gl_MultiTexCoord0; - - vec4 pos; - mat4 trans = getSkinnedTransform(); - pos.x = dot(trans[0], gl_Vertex); - pos.y = dot(trans[1], gl_Vertex); - pos.z = dot(trans[2], gl_Vertex); - pos.w = 1.0; - - vec3 norm; - norm.x = dot(trans[0].xyz, gl_Normal); - norm.y = dot(trans[1].xyz, gl_Normal); - norm.z = dot(trans[2].xyz, gl_Normal); - norm = normalize(norm); - - vec3 binorm; - binorm.x = dot(trans[0].xyz, binormal.xyz); - binorm.y = dot(trans[1].xyz, binormal.xyz); - binorm.z = dot(trans[2].xyz, binormal.xyz); - - float spec = 1.0-max(dot(reflect(normalize(pos.xyz), norm),gl_LightSource[0].position.xyz), 0.0); - spec *= spec; - spec = 1.0-spec; - - vec4 color = calcLighting(pos.xyz, norm, materialColor, gl_Color.rgb); - gl_FrontColor = color; - - gl_Position = gl_ProjectionMatrix * pos; - - vec3 N = norm; - vec3 B = normalize(binorm); - vec3 T = cross(N,B); - - //gl_TexCoord[1].xy = gl_MultiTexCoord0.xy + 1.0/512.0 * vec2(dot(T,gl_LightSource[0].position.xyz), - // dot(B,gl_LightSource[0].position.xyz)); - - - default_scatter(pos.xyz, gl_LightSource[0].position.xyz); -} \ No newline at end of file diff --git a/linden/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl b/linden/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl index 7957edd..3dd62d2 100644 --- a/linden/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl +++ b/linden/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl @@ -1,8 +1,12 @@ -vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec3 baseCol); -void default_scatter(vec3 viewVec, vec3 lightDir); +/** + * @file eyeballV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ -attribute vec4 materialColor; -attribute vec4 specularColor; +vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); void main() { @@ -12,12 +16,15 @@ void main() vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz; vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + + calcAtmospherics(pos.xyz); - default_scatter(pos.xyz, gl_LightSource[0].position.xyz); - vec4 specular = specularColor; - vec4 color = calcLightingSpecular(pos, norm, materialColor, specular, gl_Color.rgb); + // vec4 specular = specularColor; + vec4 specular = vec4(1.0); + vec4 color = calcLightingSpecular(pos, norm, gl_Color, specular, vec4(0.0)); gl_FrontColor = color; gl_FogFragCoord = pos.z; + } diff --git a/linden/indra/newview/app_settings/shaders/class2/effects/blurF.glsl b/linden/indra/newview/app_settings/shaders/class2/effects/blurF.glsl new file mode 100644 index 0000000..9443320 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/effects/blurF.glsl @@ -0,0 +1,31 @@ +/** + * @file blurf.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform float bloomStrength; + +varying vec4 gl_TexCoord[gl_MaxTextureCoords]; +void main(void) +{ + float blurWeights[7]; + blurWeights[0] = 0.05; + blurWeights[1] = 0.1; + blurWeights[2] = 0.2; + blurWeights[3] = 0.3; + blurWeights[4] = 0.2; + blurWeights[5] = 0.1; + blurWeights[6] = 0.05; + + vec3 color = vec3(0,0,0); + for (int i = 0; i < 7; i++){ + color += vec3(texture2DRect(RenderTexture, gl_TexCoord[i].st)) * blurWeights[i]; + } + + color *= bloomStrength; + + gl_FragColor = vec4(color, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class2/effects/blurV.glsl b/linden/indra/newview/app_settings/shaders/class2/effects/blurV.glsl new file mode 100644 index 0000000..ba65b16 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/effects/blurV.glsl @@ -0,0 +1,35 @@ +/** + * @file blurV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform vec2 texelSize; +uniform vec2 blurDirection; +uniform float blurWidth; + +void main(void) +{ + // Transform vertex + gl_Position = ftransform(); + + vec2 blurDelta = texelSize * blurDirection * vec2(blurWidth, blurWidth); + vec2 s = gl_MultiTexCoord0.st - (blurDelta * 3.0); + + // for (int i = 0; i < 7; i++) { + // gl_TexCoord[i].st = s + (i * blurDelta); + // } + + // MANUALLY UNROLL + gl_TexCoord[0].st = s; + gl_TexCoord[1].st = s + blurDelta; + gl_TexCoord[2].st = s + (2. * blurDelta); + gl_TexCoord[3].st = s + (3. * blurDelta); + gl_TexCoord[4].st = s + (4. * blurDelta); + gl_TexCoord[5].st = s + (5. * blurDelta); + gl_TexCoord[6].st = s + (6. * blurDelta); + + // gl_TexCoord[0].st = s; + // gl_TexCoord[1].st = blurDelta; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl b/linden/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl new file mode 100644 index 0000000..623ef7a --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl @@ -0,0 +1,31 @@ +/** + * @file colorFilterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform float brightness; +uniform float contrast; +uniform vec3 contrastBase; +uniform float saturation; +uniform vec3 lumWeights; + +const float gamma = 2.0; + +void main(void) +{ + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Modulate brightness + color *= brightness; + + /// Modulate contrast + color = mix(contrastBase, color, contrast); + + /// Modulate saturation + color = mix(vec3(dot(color, lumWeights)), color, saturation); + + gl_FragColor = vec4(color, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl b/linden/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl new file mode 100644 index 0000000..29c2a09 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl @@ -0,0 +1,14 @@ +/** + * @file drawQuadV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void main(void) +{ + //transform vertex + gl_Position = ftransform(); + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_TexCoord[1] = gl_MultiTexCoord1; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/effects/extractF.glsl b/linden/indra/newview/app_settings/shaders/class2/effects/extractF.glsl new file mode 100644 index 0000000..a1583b1 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/effects/extractF.glsl @@ -0,0 +1,22 @@ +/** + * @file extractF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform float extractLow; +uniform float extractHigh; +uniform vec3 lumWeights; + +void main(void) +{ + /// Get scene color + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Extract luminance and scale up by night vision brightness + float lum = smoothstep(extractLow, extractHigh, dot(color, lumWeights)); + + gl_FragColor = vec4(vec3(lum), 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl b/linden/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl new file mode 100644 index 0000000..271d5cf --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl @@ -0,0 +1,42 @@ +/** + * @file nightVisionF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform sampler2D NoiseTexture; +uniform float brightMult; +uniform float noiseStrength; + +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + +void main(void) +{ + /// Get scene color + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Extract luminance and scale up by night vision brightness + float lum = luminance(color) * brightMult; + + /// Convert into night vision color space + /// Newer NVG colors (crisper and more saturated) + vec3 outColor = (lum * vec3(0.91, 1.21, 0.9)) + vec3(-0.07, 0.1, -0.12); + + /// Add noise + float noiseValue = texture2D(NoiseTexture, gl_TexCoord[1].st).r; + noiseValue = (noiseValue - 0.5) * noiseStrength; + + /// Older NVG colors (more muted) + // vec3 outColor = (lum * vec3(0.82, 0.75, 0.83)) + vec3(0.05, 0.32, -0.11); + + outColor += noiseValue; + + gl_FragColor = vec4(outColor, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl b/linden/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl new file mode 100644 index 0000000..e55d278 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl @@ -0,0 +1,14 @@ +/** + * @file simpleF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; + +void main(void) +{ + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + gl_FragColor = vec4(1.0 - color, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl b/linden/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl new file mode 100644 index 0000000..4253bc2 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl @@ -0,0 +1,38 @@ +/** + * @file terrainF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D detail_0; +uniform sampler2D detail_1; +uniform sampler2D detail_2; +uniform sampler2D detail_3; +uniform sampler2D alpha_ramp; + +vec3 atmosLighting(vec3 light); + +vec3 scaleSoftClip(vec3 color); + +void main() +{ + /// Note: This should duplicate the blending functionality currently used for the terrain rendering. + + /// TODO Confirm tex coords and bind them appropriately in vert shader. + vec4 color0 = texture2D(detail_0, gl_TexCoord[0].xy); + vec4 color1 = texture2D(detail_1, gl_TexCoord[0].xy); + vec4 color2 = texture2D(detail_2, gl_TexCoord[0].xy); + vec4 color3 = texture2D(detail_3, gl_TexCoord[0].xy); + + float alpha1 = texture2D(alpha_ramp, gl_TexCoord[0].zw).a; + float alpha2 = texture2D(alpha_ramp,gl_TexCoord[1].xy).a; + float alphaFinal = texture2D(alpha_ramp, gl_TexCoord[1].zw).a; + vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); + + /// Add WL Components + outColor.rgb = atmosLighting(outColor.rgb * gl_Color.rgb); + + gl_FragColor = vec4(scaleSoftClip(outColor.rgb), 1.0); +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl b/linden/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl new file mode 100644 index 0000000..119d55a --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl @@ -0,0 +1,52 @@ +/** + * @file terrainV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void calcAtmospherics(vec3 inPositionEye); + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); + +vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) +{ + vec4 tcoord; + + tcoord.x = dot(vpos, tp0); + tcoord.y = dot(vpos, tp1); + tcoord.z = tc.z; + tcoord.w = tc.w; + + tcoord = mat * tcoord; + + return tcoord; +} + +void main() +{ + //transform vertex + gl_Position = ftransform(); + + vec4 pos = gl_ModelViewMatrix * gl_Vertex; + vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + + /// Potentially better without it for water. + pos /= pos.w; + + calcAtmospherics((gl_ModelViewMatrix * gl_Vertex).xyz); + + vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0)); + + gl_FrontColor = color; + + // Transform and pass tex coords + gl_TexCoord[0].xy = texgen_object(gl_Vertex, gl_MultiTexCoord0, gl_TextureMatrix[0], gl_ObjectPlaneS[0], gl_ObjectPlaneT[0]).xy; + + vec4 t = gl_MultiTexCoord1; + + gl_TexCoord[0].zw = t.xy; + gl_TexCoord[1].xy = t.xy-vec2(2.0, 0.0); + gl_TexCoord[1].zw = t.xy-vec2(1.0, 0.0); +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl b/linden/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl new file mode 100755 index 0000000..3a98970 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl @@ -0,0 +1,39 @@ +/** + * @file terrainWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D detail_0; +uniform sampler2D detail_1; +uniform sampler2D detail_2; +uniform sampler2D detail_3; +uniform sampler2D alpha_ramp; + +vec3 atmosLighting(vec3 light); + +vec4 applyWaterFog(vec4 color); + +void main() +{ + /// Note: This should duplicate the blending functionality currently used for the terrain rendering. + + /// TODO Confirm tex coords and bind them appropriately in vert shader. + vec4 color0 = texture2D(detail_0, gl_TexCoord[0].xy); + vec4 color1 = texture2D(detail_1, gl_TexCoord[0].xy); + vec4 color2 = texture2D(detail_2, gl_TexCoord[0].xy); + vec4 color3 = texture2D(detail_3, gl_TexCoord[0].xy); + + float alpha1 = texture2D(alpha_ramp, gl_TexCoord[0].zw).a; + float alpha2 = texture2D(alpha_ramp,gl_TexCoord[1].xy).a; + float alphaFinal = texture2D(alpha_ramp, gl_TexCoord[1].zw).a; + vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); + + /// Add WL Components + outColor.rgb = atmosLighting(outColor.rgb * gl_Color.rgb); + + outColor = applyWaterFog(outColor); + gl_FragColor = outColor; +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl b/linden/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl new file mode 100644 index 0000000..1998fea --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl @@ -0,0 +1,88 @@ +/** + * @file underWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; +uniform sampler2D bumpMap; +uniform sampler2D screenTex; +uniform sampler2D refTex; +uniform sampler2D screenDepth; + +uniform vec4 fogCol; +uniform vec3 lightDir; +uniform vec3 specular; +uniform float lightExp; +uniform vec2 fbScale; +uniform float refScale; +uniform float znear; +uniform float zfar; +uniform float kd; +uniform vec4 waterPlane; +uniform vec3 eyeVec; +uniform vec4 waterFogColor; +uniform float waterFogDensity; +uniform float waterFogKS; +uniform vec2 screenRes; + +//bigWave is (refCoord.w, view.w); +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; + +vec4 applyWaterFog(vec4 color, vec3 viewVec) +{ + //normalize view vector + vec3 view = normalize(viewVec); + float es = -view.z; + + //find intersection point with water plane and eye vector + + //get eye depth + float e0 = max(-waterPlane.w, 0.0); + + //get object depth + float depth = length(viewVec); + + //get "thickness" of water + float l = max(depth, 0.1); + + float kd = waterFogDensity; + float ks = waterFogKS; + vec4 kc = waterFogColor; + + float F = 0.98; + + float t1 = -kd * pow(F, ks * e0); + float t2 = kd + ks * es; + float t3 = pow(F, t2*l) - 1.0; + + float L = min(t1/t2*t3, 1.0); + + float D = pow(0.98, l*kd); + //return vec4(1.0, 0.0, 1.0, 1.0); + return color * D + kc * L; + //depth /= 10.0; + //return vec4(depth,depth,depth,0.0); +} + +void main() +{ + vec4 color; + + //get detail normals + vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; + vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0; + vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0; + vec3 wavef = normalize(wave1+wave2+wave3); + + //figure out distortion vector (ripply) + vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; + distort = distort+wavef.xy*refScale; + + vec4 fb = texture2D(screenTex, distort); + + gl_FragColor = applyWaterFog(fb,view.xyz); +} diff --git a/linden/indra/newview/app_settings/shaders/class2/environment/waterF.glsl b/linden/indra/newview/app_settings/shaders/class2/environment/waterF.glsl index 11a057b..6ec3dc4 100644 --- a/linden/indra/newview/app_settings/shaders/class2/environment/waterF.glsl +++ b/linden/indra/newview/app_settings/shaders/class2/environment/waterF.glsl @@ -1,138 +1,117 @@ -void applyScatter(inout vec3 color); +/** + * @file waterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec3 scaleSoftClip(vec3 inColor); +vec3 atmosTransport(vec3 inColor); -uniform sampler2D diffuseMap; uniform sampler2D bumpMap; -uniform samplerCube environmentMap; //: TEXUNIT4, // Environment map texture -uniform sampler2D screenTex; // : TEXUNIT5 +uniform sampler2D screenTex; +uniform sampler2D refTex; +uniform float sunAngle; +uniform float sunAngle2; uniform vec3 lightDir; uniform vec3 specular; uniform float lightExp; -uniform vec2 fbScale; uniform float refScale; +uniform float kd; +uniform vec2 screenRes; +uniform vec3 normScale; +uniform float fresnelScale; +uniform float fresnelOffset; +uniform float blurMultiplier; -float msin(float x) { - float k = sin(x)+1.0; - k *= 0.5; - k *= k; - return 2.0 * k; -} -float mcos(float x) { - float k = cos(x)+1.0; - k *= 0.5; - k *= k; - return 2.0 * k; -} +//bigWave is (refCoord.w, view.w); +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; -float waveS(vec2 v, float t, float a, float f, vec2 d, float s, sampler1D sinMap) +void main() { - return texture1D(sinMap, (dot(d, v)*f + t*s)*f).r*a; -} + vec4 color; + + float dist = length(view.xy); + + //normalize view vector + vec3 viewVec = normalize(view.xyz); + + //get wave normals + vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; + vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0; + vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0; + //get base fresnel components + + vec3 df = vec3( + dot(viewVec, wave1), + dot(viewVec, (wave2 + wave3) * 0.5), + dot(viewVec, wave3) + ) * fresnelScale + fresnelOffset; + df *= df; + + vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; + + float dist2 = dist; + dist = max(dist, 5.0); + + float dmod = sqrt(dist); + + vec2 dmod_scale = vec2(dmod*dmod, dmod); + + //get reflected color + vec2 refdistort1 = wave1.xy*normScale.x; + vec2 refvec1 = distort+refdistort1/dmod_scale; + vec4 refcol1 = texture2D(refTex, refvec1); + + vec2 refdistort2 = wave2.xy*normScale.y; + vec2 refvec2 = distort+refdistort2/dmod_scale; + vec4 refcol2 = texture2D(refTex, refvec2); + + vec2 refdistort3 = wave3.xy*normScale.z; + vec2 refvec3 = distort+refdistort3/dmod_scale; + vec4 refcol3 = texture2D(refTex, refvec3); -float waveC(vec2 v, float t, float a, float f, vec2 d, float s, sampler1D sinMap) -{ - return texture1D(sinMap, (dot(d, v)*f + t*s)*f).g*a*2.0-1.0; -} + vec4 refcol = refcol1 + refcol2 + refcol3; + float df1 = df.x + df.y + df.z; + refcol *= df1 * 0.333; + + vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; + + wavef.z *= max(-viewVec.z, 0.1); + wavef = normalize(wavef); + + float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; + + vec2 refdistort4 = wavef.xy*0.125; + refdistort4.y -= abs(refdistort4.y); + vec2 refvec4 = distort+refdistort4/dmod; + float dweight = min(dist2*blurMultiplier, 1.0); + vec4 baseCol = texture2D(refTex, refvec4); + refcol = mix(baseCol*df2, refcol, dweight); -float magnitude(vec3 vec) { - return sqrt(dot(vec,vec)); -} - -vec3 mreflect(vec3 i, vec3 n) { - return i + n * 2.0 * abs(dot(n,i))+vec3(0.0,0.0,0.5); -} - -void main() -{ - vec2 texCoord = gl_TexCoord[0].xy; // Texture coordinates - vec2 littleWave1 = gl_TexCoord[0].zw; - vec2 littleWave2 = gl_TexCoord[1].xy; - vec2 bigWave = gl_TexCoord[1].zw; - vec3 viewVec = gl_TexCoord[2].xyz; - vec4 refCoord = gl_TexCoord[3]; - vec4 col = gl_Color; - vec4 color; - - //get color from alpha map (alpha denotes water depth), rgb denotes water color - vec4 wcol = texture2D(diffuseMap, texCoord.xy); - - //store texture alpha - float da = wcol.a; - - //modulate by incoming water color - //wcol.a *= refCoord.w; - - //scale wcol.a (water depth) for steep transition - wcol.a *= wcol.a; - - //normalize view vector - viewVec = normalize(viewVec); - - //get bigwave normal - vec3 wavef = texture2D(bumpMap, bigWave).xyz*2.0; - - vec3 view = vec3(viewVec.x, viewVec.y, viewVec.z); - - float dx = 1.0-(dot(wavef*2.0-vec3(1.0), view))*da; - dx *= 0.274; - - //get detail normals - vec3 dcol = texture2D(bumpMap, littleWave1+dx*view.xy).rgb*0.75; - dcol += texture2D(bumpMap, littleWave2+view.xy*dx*0.1).rgb*1.25; - - //interpolate between big waves and little waves (big waves in deep water) - wavef = wavef*wcol.a + dcol*(1.0-wcol.a); - - //crunch normal to range [-1,1] - wavef -= vec3(1,1,1); - - //get base fresnel component - float df = dot(viewVec,wavef); - //reposition fresnel to latter half of [0,1] - df = 1.0-clamp(df,0.0,1.0); + //get specular component + float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); + + //harden specular + spec = pow(spec, 128.0); - //set output alpha based on fresnel - color.a = clamp((df+da)*0.5,0.0,1.0); - - //calculate reflection vector - vec3 ref = reflect(viewVec.xyz, wavef); - - //get specular component - float spec = clamp(dot(lightDir, normalize(ref)),0.0,1.0); - - //fudge reflection to be more noisy at good angles - ref.z = ref.z*ref.z+df*df*0.5; - - //get diffuse component - float diff = clamp((abs(dot(ref, wavef))),0.0,1.0)*0.9; - - //fudge diffuse for extra contrast and ambience - diff *= diff; - diff += 0.4; - - //set diffuse color contribution - color.rgb = textureCube(environmentMap, ref).rgb*diff; - - //harden specular - spec = pow(spec, lightExp); - - //add specular color contribution - color.rgb += spec * specular; + //figure out distortion vector (ripply) + vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); + + vec4 fb = texture2D(screenTex, distort2); + + //mix with reflection + // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug + color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999); + color.rgb += spec * specular; + + color.rgb = atmosTransport(color.rgb); + color.rgb = scaleSoftClip(color.rgb); + color.a = spec * sunAngle2; - //figure out distortion vector (ripply) - vec2 distort = clamp(((refCoord.xy/refCoord.z) * 0.5 + 0.5 + wavef.xy*refScale),0.0,0.99); - - //read from framebuffer (offset) - vec4 fb = texture2D(screenTex, distort*fbScale); - - //tint by framebuffer - color.rgb = color.a*color.rgb + (1.0-color.a)*fb.rgb; - - //apply fog - applyScatter(color.rgb); - - color.a = spec*0.5+fb.a; - - gl_FragColor = color; + gl_FragColor = color; } diff --git a/linden/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl b/linden/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl new file mode 100644 index 0000000..522c990 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl @@ -0,0 +1,54 @@ +/** + * @file waterFogF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform vec4 lightnorm; +uniform vec4 waterPlane; +uniform vec4 waterFogColor; +uniform float waterFogDensity; +uniform float waterFogKS; + +vec3 getPositionEye(); + +vec4 applyWaterFog(vec4 color) +{ + //normalize view vector + vec3 view = normalize(getPositionEye()); + float es = -(dot(view, waterPlane.xyz)); + + //find intersection point with water plane and eye vector + + //get eye depth + float e0 = max(-waterPlane.w, 0.0); + + vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0); + + //get object depth + float depth = length(getPositionEye() - int_v); + + //get "thickness" of water + float l = max(depth, 0.1); + + float kd = waterFogDensity; + float ks = waterFogKS; + vec4 kc = waterFogColor; + + float F = 0.98; + + float t1 = -kd * pow(F, ks * e0); + float t2 = kd + ks * es; + float t3 = pow(F, t2*l) - 1.0; + + float L = min(t1/t2*t3, 1.0); + + float D = pow(0.98, l*kd); + + color.rgb = color.rgb * D + kc.rgb * L; + color.a = kc.a + color.a; + + return color; +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/environment/waterV.glsl b/linden/indra/newview/app_settings/shaders/class2/environment/waterV.glsl deleted file mode 100644 index 25309fa..0000000 --- a/linden/indra/newview/app_settings/shaders/class2/environment/waterV.glsl +++ /dev/null @@ -1,53 +0,0 @@ -void default_scatter(vec3 viewVec, vec3 lightDir); - -uniform vec2 d1; -uniform vec2 d2; -uniform float time; -uniform vec3 eyeVec; - -float wave(vec2 v, float t, float f, vec2 d, float s) -{ - return (dot(d, v)*f + t*s)*f; -} - -void main() -{ - //transform vertex - vec4 position = gl_Vertex; - mat4 modelViewProj = gl_ModelViewProjectionMatrix; - vec4 oPosition = modelViewProj * position; - vec3 oRefCoord = oPosition.xyz + vec3(0, 0, 0.2); - - //get view vector - vec4 oEyeVec; - oEyeVec.xyz = position.xyz-eyeVec; - - //get wave position parameter (create sweeping horizontal waves) - vec3 v = position.xyz; - v.x += (cos(v.x*0.08+time*0.01)+sin(v.y*0.02))*6.0; - - //get two normal map (detail map) texture coordinates - vec2 oTexCoord = gl_MultiTexCoord0.xy; - vec2 littleWave1 = (v.xy)*vec2(0.7, 1.5)+d2*time*0.065; - vec2 littleWave2 = (v.xy)*vec2(0.07, 0.15)-d1*time*0.087; - - //pass wave parameters to pixel shader - float t = time * 0.075; - vec2 bigWave = (v.xy)*vec2(0.04,0.04)+d1*t; - - //pass color and fog color to pixel shader - vec4 col = gl_Color; - col.a = clamp(abs(dot(normalize(oEyeVec.xyz), vec3(0,0,1))),0.0,1.0); - col.a = 1.0-col.a; - col.a += 0.75; - default_scatter((gl_ModelViewMatrix * gl_Vertex).xyz, gl_LightSource[0].position.xyz); - - gl_Position = oPosition; - gl_TexCoord[0].xy = oTexCoord; - gl_TexCoord[0].zw = littleWave1; - gl_TexCoord[1].xy = littleWave2; - gl_TexCoord[1].zw = bigWave; - gl_TexCoord[2].xyz = oEyeVec.xyz; - gl_TexCoord[3].xyz = oRefCoord; - gl_FrontColor = col; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl b/linden/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl index 6f732ed..b372d66 100644 --- a/linden/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl @@ -1,36 +1,23 @@ -void applyScatter(inout vec3 color); +/** + * @file lightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ uniform sampler2D diffuseMap; +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + void default_lighting() { - vec4 color = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); - //applyScatter(color.rgb); - gl_FragColor = color; -} + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; + + color.rgb = atmosLighting(color.rgb); -void alpha_lighting() -{ - vec4 diff = texture2D(diffuseMap, gl_TexCoord[0].xy); - vec3 color = gl_Color.rgb * diff.rgb; - applyScatter(color); - gl_FragColor.rgb = color; - gl_FragColor.a = diff.a * gl_Color.a; -} + color.rgb = scaleSoftClip(color.rgb); -void water_lighting(inout vec3 diff) -{ - diff = (diff*0.9 + gl_Color.rgb*0.1); - applyScatter(diff); -} - -void terrain_lighting(inout vec3 color) -{ - color.rgb *= gl_Color.rgb; - applyScatter(color); + gl_FragColor = color; } -vec4 getLightColor() -{ - return gl_Color; -} \ No newline at end of file diff --git a/linden/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl b/linden/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl new file mode 100644 index 0000000..e6b6d85 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl @@ -0,0 +1,23 @@ +/** + * @file lightFullbrightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +vec3 fullbrightAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); + +void fullbright_lighting() +{ + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; + + color.rgb = fullbrightAtmosTransport(color.rgb); + + color.rgb = fullbrightScaleSoftClip(color.rgb); + + gl_FragColor = color; +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl b/linden/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl new file mode 100644 index 0000000..8f408c0 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl @@ -0,0 +1,30 @@ +/** + * @file lightFullbrightShinyF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +vec3 fullbrightShinyAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); + +void fullbright_shiny_lighting() +{ + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); + color.rgb *= gl_Color.rgb; + + vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb; + color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a); + + color.rgb = fullbrightShinyAtmosTransport(color.rgb); + + color.rgb = fullbrightScaleSoftClip(color.rgb); + + color.a = max(color.a, gl_Color.a); + + gl_FragColor = color; +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl b/linden/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl new file mode 100644 index 0000000..060ad9c --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl @@ -0,0 +1,21 @@ +/** + * @file lightFullbrightWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +vec3 fullbrightAtmosTransport(vec3 light); +vec4 applyWaterFog(vec4 color); + +void fullbright_lighting_water() +{ + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; + + color.rgb = fullbrightAtmosTransport(color.rgb); + + gl_FragColor = applyWaterFog(color); +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl b/linden/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl new file mode 100644 index 0000000..b3927c7 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl @@ -0,0 +1,29 @@ +/** + * @file lightShinyF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +vec3 scaleSoftClip(vec3 light); +vec3 atmosLighting(vec3 light); +vec4 applyWaterFog(vec4 color); + +void shiny_lighting() +{ + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); + color.rgb *= gl_Color.rgb; + + vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb; + color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a); + + color.rgb = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + color.a = max(color.a, gl_Color.a); + gl_FragColor = color; +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl b/linden/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl new file mode 100644 index 0000000..f090306 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl @@ -0,0 +1,27 @@ +/** + * @file lightShinyWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +vec3 atmosLighting(vec3 light); +vec4 applyWaterFog(vec4 color); + +void shiny_lighting_water() +{ + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); + color.rgb *= gl_Color.rgb; + + vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb; + color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a); + + color.rgb = atmosLighting(color.rgb); + color.a = max(color.a, gl_Color.a); + gl_FragColor = applyWaterFog(color); +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl b/linden/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl new file mode 100644 index 0000000..c3384ff --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl @@ -0,0 +1,16 @@ +/** + * @file lightSpecularV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +// All lights, no specular highlights + +vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol); + +vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol) +{ + return sumLightsSpecular(pos, norm, color, specularColor, baseCol); +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl b/linden/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl index b15960d..ff3bcb5 100644 --- a/linden/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl +++ b/linden/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl @@ -1,126 +1,16 @@ -// All lights, no specular highlights - -float calcDirectionalLight(vec3 n, vec3 l) -{ - float a = max(dot(n,l),0.0); - return a; -} - -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la) -{ - //get light vector - vec3 lv = lp.xyz-v; - - //get distance - float d = length(lv); - - //normalize light vector - lv *= 1.0/d; - - //distance attenuation - float da = clamp(1.0/(la * d), 0.0, 1.0); - - //angular attenuation - da *= calcDirectionalLight(n, lv); - - return da; -} +/** + * @file lightV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ -float calcDirectionalSpecular(vec3 view, vec3 n, vec3 l) -{ - return pow(max(dot(reflect(view, n),l), 0.0),8.0); -} +// All lights, no specular highlights -float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da) -{ - - specular.rgb += calcDirectionalSpecular(view,n,l)*lightCol*da; - return calcDirectionalLight(n,l); -} - -vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol) -{ - //get light vector - vec3 lv = l-v; - - //get distance - float d = length(lv); - - //normalize light vector - lv *= 1.0/d; - - //distance attenuation - float da = clamp(1.0/(r * d), 0.0, 1.0); - - //angular attenuation - - da *= calcDirectionalLightSpecular(specular, view, n, lv, lightCol, da); - - return da*lightCol; -} +vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight); vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseLight) { - vec4 col; - col.a = color.a; - - col.rgb = gl_LightModel.ambient.rgb + baseLight.rgb; - - col.rgb += gl_LightSource[0].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[0].position.xyz); - col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); - col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); - col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); - col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); - col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); - col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); - col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); - - col.rgb = min(col.rgb*color.rgb, 1.0); - - gl_FrontColor = vec4(col.rgb, col.a); - return col; -} - -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec3 baseLight) -{ - return calcLighting(pos, norm, color, vec4(baseLight, 1.0)); -} - -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color) -{ - return calcLighting(pos, norm, color, vec3(0.0,0.0,0.0)); + return sumLights(pos, norm, color, baseLight); } -vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol) -{ - vec4 col; - col.a = color.a; - - col.rgb = gl_LightModel.ambient.rgb; - - vec3 view = normalize(pos); - - vec4 specular = specularColor; - specularColor.rgb = vec3(0.0, 0.0, 0.0); - - col.rgb += baseCol.a*gl_LightSource[0].diffuse.rgb*calcDirectionalLightSpecular(specularColor, view, norm, gl_LightSource[0].position.xyz,gl_LightSource[0].diffuse.rgb*baseCol.a, 1.0); - col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLightSpecular(specularColor, view, norm, gl_LightSource[1].position.xyz,gl_LightSource[1].diffuse.rgb, 1.0); - col.rgb += calcPointLightSpecular(specularColor, view, pos, norm, gl_LightSource[2].position.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation,gl_LightSource[2].diffuse.rgb); - col.rgb += calcPointLightSpecular(specularColor, view, pos, norm, gl_LightSource[3].position.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation,gl_LightSource[3].diffuse.rgb); - col.rgb += calcPointLightSpecular(specularColor, view, pos, norm, gl_LightSource[4].position.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation,gl_LightSource[4].diffuse.rgb); - col.rgb += calcPointLightSpecular(specularColor, view, pos, norm, gl_LightSource[5].position.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation,gl_LightSource[5].diffuse.rgb); - //col.rgb += calcPointLightSpecular(specularColor, view, pos, norm, gl_LightSource[6].position.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation,gl_LightSource[6].diffuse.rgb); - //col.rgb += calcPointLightSpecular(specularColor, view, pos, norm, gl_LightSource[7].position.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation,gl_LightSource[7].diffuse.rgb); - col.rgb += baseCol.rgb; - - col.rgb = min(col.rgb*color.rgb, 1.0); - specularColor.rgb = min(specularColor.rgb*specular.rgb, 1.0); - - gl_FrontColor = vec4(col.rgb+specularColor.rgb,col.a); - return col; -} - -vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec3 baseCol) -{ - return calcLightingSpecular(pos, norm, color, specularColor, vec4(baseCol, 1.0)); -} diff --git a/linden/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl b/linden/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl new file mode 100644 index 0000000..086954c --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl @@ -0,0 +1,21 @@ +/** + * @file lightWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +vec3 atmosLighting(vec3 light); +vec4 applyWaterFog(vec4 color); + +void default_lighting_water() +{ + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * gl_Color; + + color.rgb = atmosLighting(color.rgb); + + gl_FragColor = applyWaterFog(color); +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl b/linden/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl new file mode 100644 index 0000000..edd1a8a --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl @@ -0,0 +1,41 @@ +/** + * @file sumLightsV.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da); +vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 atmosGetDiffuseSunlightColor(); +vec3 scaleDownLight(vec3 light); + +vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol) +{ + vec4 col = vec4(0.0, 0.0, 0.0, color.a); + + vec3 view = normalize(pos); + + /// collect all the specular values from each calcXXXLightSpecular() function + vec4 specularSum = vec4(0.0); + + // Collect normal lights (need to be divided by two, as we later multiply by 2) + col.rgb += gl_LightSource[1].diffuse.rgb * calcDirectionalLightSpecular(specularColor, view, norm, gl_LightSource[1].position.xyz, gl_LightSource[1].diffuse.rgb, 1.0); + col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[2].position.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].diffuse.rgb); + col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[3].position.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation, gl_LightSource[3].diffuse.rgb); + //col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[4].position.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].diffuse.rgb); + col.rgb = scaleDownLight(col.rgb); + + // Add windlight lights + col.rgb += atmosAmbient(baseCol.rgb); + col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, gl_LightSource[0].position.xyz, atmosGetDiffuseSunlightColor()*baseCol.a, 1.0)); + + col.rgb = min(col.rgb*color.rgb, 1.0); + specularColor.rgb = min(specularColor.rgb*specularSum.rgb, 1.0); + col.rgb += specularColor.rgb; + + return col; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/linden/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl new file mode 100644 index 0000000..f4c5973 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl @@ -0,0 +1,34 @@ +/** + * @file sumLightsV.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +float calcDirectionalLight(vec3 n, vec3 l); +float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); + +vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight) +{ + vec4 col = vec4(0.0, 0.0, 0.0, color.a); + + // Collect normal lights (need to be divided by two, as we later multiply by 2) + col.rgb += gl_LightSource[1].diffuse.rgb * calcDirectionalLight(norm, gl_LightSource[1].position.xyz); + col.rgb += gl_LightSource[2].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); + col.rgb += gl_LightSource[3].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); + //col.rgb += gl_LightSource[4].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); + col.rgb = scaleDownLight(col.rgb); + + // Add windlight lights + col.rgb += atmosAmbient(baseLight.rgb); + col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz)); + + col.rgb = min(col.rgb*color.rgb, 1.0); + + return col; +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/objects/alphaF.glsl b/linden/indra/newview/app_settings/shaders/class2/objects/alphaF.glsl deleted file mode 100644 index 97feb55..0000000 --- a/linden/indra/newview/app_settings/shaders/class2/objects/alphaF.glsl +++ /dev/null @@ -1,18 +0,0 @@ -vec4 getLightColor(); -void applyScatter(inout vec3 col); - -uniform samplerCube environmentMap; -uniform sampler2D diffuseMap; - -void main() -{ - vec4 diff = texture2D(diffuseMap, gl_TexCoord[0].xy); - vec3 ref = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb; - vec4 specular = gl_TexCoord[2]; - vec3 col = mix(getLightColor().rgb * diff.rgb, ref, specular.a)+specular.rgb*diff.rgb; - - applyScatter(col); - - gl_FragColor.rgb = col.rgb; - gl_FragColor.a = diff.a*gl_Color.a; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/objects/alphaV.glsl b/linden/indra/newview/app_settings/shaders/class2/objects/alphaV.glsl deleted file mode 100644 index baf5323..0000000 --- a/linden/indra/newview/app_settings/shaders/class2/objects/alphaV.glsl +++ /dev/null @@ -1,24 +0,0 @@ -vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol); -void default_scatter(vec3 viewVec, vec3 lightDir); - -attribute vec4 materialColor; -attribute vec4 specularColor; - -void main() -{ - //transform vertex - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - gl_TexCoord[0] = gl_MultiTexCoord0; - - vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz; - vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - vec4 spec = specularColor; - gl_FrontColor.rgb = calcLightingSpecular(pos, norm, materialColor, spec, gl_Color).rgb; - gl_FrontColor.a = materialColor.a; - gl_TexCoord[2] = spec; - vec3 ref = reflect(pos,norm); - gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1); - - default_scatter(pos.xyz, gl_LightSource[0].position.xyz); -} - diff --git a/linden/indra/newview/app_settings/shaders/class2/objects/bumpshinyF.glsl b/linden/indra/newview/app_settings/shaders/class2/objects/bumpshinyF.glsl deleted file mode 100644 index 7462bb1..0000000 --- a/linden/indra/newview/app_settings/shaders/class2/objects/bumpshinyF.glsl +++ /dev/null @@ -1,29 +0,0 @@ -vec4 getLightColor(); -void applyScatter(inout vec3 col); - -uniform samplerCube environmentMap; -uniform sampler2D diffuseMap; -uniform sampler2D bumpMap; - - -void main() -{ - vec4 diff = texture2D(diffuseMap, gl_TexCoord[0].xy); - vec3 ref = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb; - - vec4 specular = gl_TexCoord[3]; - - float b = texture2D(bumpMap, gl_TexCoord[0].xy).a; - b -= texture2D(bumpMap, gl_TexCoord[2].xy).a; - - vec3 col = mix(getLightColor().rgb * diff.rgb, ref, specular.a)+specular.rgb*diff.rgb; - col += col * b; - float m = (col.r + col.g + col.b); - m *= 1.0/3.0; - col = mix(col, vec3(m), -specular.a*specular.a); - - applyScatter(col); - - gl_FragColor.rgb = col; - gl_FragColor.a = diff.a; -} diff --git a/linden/indra/newview/app_settings/shaders/class2/objects/bumpshinyV.glsl b/linden/indra/newview/app_settings/shaders/class2/objects/bumpshinyV.glsl deleted file mode 100644 index 037b282..0000000 --- a/linden/indra/newview/app_settings/shaders/class2/objects/bumpshinyV.glsl +++ /dev/null @@ -1,31 +0,0 @@ -vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol); -void default_scatter(vec3 viewVec, vec3 lightDir); - -attribute vec4 materialColor; -attribute vec4 specularColor; -attribute vec4 binormal; - -void main() -{ - //transform vertex - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - gl_TexCoord[0] = gl_MultiTexCoord0; - - vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz; - vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - vec3 binorm = normalize(gl_NormalMatrix * binormal.xyz); - vec3 tangent = cross(binorm, norm); - binorm.xy = vec2(dot(tangent, gl_LightSource[0].position.xyz), - dot(binorm, gl_LightSource[0].position.xyz))*1.0/128.0; - - vec4 spec = specularColor; - gl_FrontColor.rgb = calcLightingSpecular(pos, norm, materialColor, spec, gl_Color).rgb; - gl_TexCoord[3] = spec; - gl_FrontColor.a = materialColor.a; - vec3 ref = reflect(pos,norm); - gl_TexCoord[1].xyz = (gl_TextureMatrix[1]*vec4(ref,1.0)).xyz; - gl_TexCoord[2].xy = binorm.xy + gl_MultiTexCoord0.xy; - - default_scatter(pos.xyz, gl_LightSource[0].position.xyz); -} - diff --git a/linden/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl b/linden/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl new file mode 100755 index 0000000..0d52f32 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl @@ -0,0 +1,31 @@ +/** + * @file shinyV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); + +void calcAtmospherics(vec3 inPositionEye); + +uniform vec4 origin; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + + vec4 pos = (gl_ModelViewMatrix * gl_Vertex); + vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + vec3 ref = reflect(pos.xyz, -norm); + + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1.0); + + calcAtmospherics(pos.xyz); + + gl_FrontColor = calcLighting(pos.xyz, norm, gl_Color, vec4(0.0)); + + gl_FogFragCoord = pos.z; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl new file mode 100644 index 0000000..92c0664 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl @@ -0,0 +1,24 @@ +/** + * @file atmosphericsF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +////////////////////////////////////////////////////////// +// The fragment shader for the terrain atmospherics +////////////////////////////////////////////////////////// + +vec3 getAdditiveColor(); +vec3 getAtmosAttenuation(); + +uniform sampler2D cloudMap; +uniform vec4 cloud_pos_density1; + +vec3 atmosLighting(vec3 light) +{ + light *= getAtmosAttenuation().r; + light += getAdditiveColor(); + return (2.0 * light); +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl b/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl new file mode 100644 index 0000000..32d5ed5 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl @@ -0,0 +1,41 @@ +/** + * @file atmosphericsHelpersV.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +// Output variables +vec3 getSunlitColor(); +vec3 getAmblitColor(); +vec3 getAdditiveColor(); +vec3 getAtmosAttenuation(); +vec3 getPositionEye(); + +uniform float scene_light_strength; + +vec3 atmosAmbient(vec3 light) +{ + return getAmblitColor() + light / 2.0; +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ + return getSunlitColor() * lightIntensity; +} + +vec3 atmosGetDiffuseSunlightColor() +{ + return getSunlitColor(); +} + +vec3 scaleDownLight(vec3 light) +{ + return (light / scene_light_strength ); +} + +vec3 scaleUpLight(vec3 light) +{ + return (light * scene_light_strength); +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl new file mode 100644 index 0000000..e40372e --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl @@ -0,0 +1,137 @@ +/** + * @file atmosphericsV.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +// varying param funcs +void setSunlitColor(vec3 v); +void setAmblitColor(vec3 v); +void setAdditiveColor(vec3 v); +void setAtmosAttenuation(vec3 v); +void setPositionEye(vec3 v); + +vec3 getAdditiveColor(); + +//varying vec4 vary_CloudUVs; +//varying float vary_CloudDensity; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +//uniform vec4 camPosWorld; + +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 distance_multiplier; +uniform vec4 max_y; +uniform vec4 glow; + +void calcAtmospherics(vec3 inPositionEye) { + + vec3 P = inPositionEye; + setPositionEye(P); + + //(TERRAIN) limit altitude + if (P.y > max_y.x) P *= (max_y.x / P.y); + if (P.y < -max_y.x) P *= (-max_y.x / P.y); + + vec3 tmpLightnorm = lightnorm.xyz; + + vec3 Pn = normalize(P); + float Plen = length(P); + + vec4 temp1 = vec4(0); + vec3 temp2 = vec3(0); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + //sunlight attenuation effect (hue and brightness) due to atmosphere + //this is used later for sunlight modulation at various altitudes + light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); + //I had thought blue_density and haze_density should have equal weighting, + //but attenuation due to haze_density tends to seem too strong + + temp1 = blue_density + vec4(haze_density.r); + blue_weight = blue_density / temp1; + haze_weight = vec4(haze_density.r) / temp1; + + //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) + temp2.y = max(0.0, tmpLightnorm.y); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // main atmospheric scattering line integral + temp2.z = Plen * density_multiplier.x; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + + //final atmosphere attenuation factor + setAtmosAttenuation(temp1.rgb); + //vary_AtmosAttenuation = distance_multiplier / 10000.; + //vary_AtmosAttenuation = density_multiplier * 100.; + //vary_AtmosAttenuation = vec4(Plen / 100000., 0., 0., 1.); + + //compute haze glow + //(can use temp2.x as temp because we haven't used it yet) + temp2.x = dot(Pn, tmpLightnorm.xyz); + temp2.x = 1. - temp2.x; + //temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .03); //was glow.y + //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + //higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + //glow.z should be negative, so we're doing a sort of (1 / "angle") function + + //add "minimum anti-solar illumination" + temp2.x += .25; + + + //increase ambient when there are more clouds + vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; + + //haze color + setAdditiveColor( + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) + + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x + + tmpAmbient))); + + //brightness of surface both sunlight and ambient + setSunlitColor(vec3(sunlight * .5)); + setAmblitColor(vec3(tmpAmbient * .25)); + setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); + + // vary_SunlitColor = vec3(0); + // vary_AmblitColor = vec3(0); + // vary_AdditiveColor = vec4(Pn, 1.0); + + /* + const float cloudShadowScale = 100.; + // Get cloud uvs for shadowing + vec3 cloudPos = inPositionEye + camPosWorld - cloudShadowScale / 2.; + vary_CloudUVs.xy = cloudPos.xz / cloudShadowScale; + + // We can take uv1 and multiply it by (TerrainSpan / CloudSpan) +// cloudUVs *= (((worldMaxZ - worldMinZ) * 20) /40000.); + vary_CloudUVs *= (10000./40000.); + + // Offset by sun vector * (CloudAltitude / CloudSpan) + vary_CloudUVs.x += tmpLightnorm.x / tmpLightnorm.y * (3000./40000.); + vary_CloudUVs.y += tmpLightnorm.z / tmpLightnorm.y * (3000./40000.); + */ +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl b/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl new file mode 100644 index 0000000..0dbf2d3 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl @@ -0,0 +1,34 @@ +/** + * @file atmosphericVars.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec3 vary_PositionEye; + +varying vec3 vary_SunlitColor; +varying vec3 vary_AmblitColor; +varying vec3 vary_AdditiveColor; +varying vec3 vary_AtmosAttenuation; + +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; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl b/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl new file mode 100644 index 0000000..b528837 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl @@ -0,0 +1,60 @@ +/** + * @file atmosphericVars.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec3 vary_PositionEye; + +varying vec3 vary_SunlitColor; +varying vec3 vary_AmblitColor; +varying vec3 vary_AdditiveColor; +varying vec3 vary_AtmosAttenuation; + +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; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/linden/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl new file mode 100644 index 0000000..b7d7e5a --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl @@ -0,0 +1,76 @@ +/** + * @file WLCloudsF.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +///////////////////////////////////////////////////////////////////////// +// The fragment shader for the sky +///////////////////////////////////////////////////////////////////////// + +varying vec4 vary_CloudColorSun; +varying vec4 vary_CloudColorAmbient; +varying float vary_CloudDensity; + +uniform sampler2D cloud_noise_texture; +uniform vec4 cloud_pos_density1; +uniform vec4 cloud_pos_density2; +uniform vec4 gamma; + +/// Soft clips the light with a gamma correction +vec3 scaleSoftClip(vec3 light) { + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + + return light; +} + +void main() +{ + // Set variables + vec2 uv1 = gl_TexCoord[0].xy; + vec2 uv2 = gl_TexCoord[1].xy; + + vec4 cloudColorSun = vary_CloudColorSun; + vec4 cloudColorAmbient = vary_CloudColorAmbient; + float cloudDensity = vary_CloudDensity; + vec2 uv3 = gl_TexCoord[2].xy; + vec2 uv4 = gl_TexCoord[3].xy; + + // Offset texture coords + uv1 += cloud_pos_density1.xy; //large texture, visible density + uv2 += cloud_pos_density1.xy; //large texture, self shadow + uv3 += cloud_pos_density2.xy; //small texture, visible density + uv4 += cloud_pos_density2.xy; //small texture, self shadow + + + // Compute alpha1, the main cloud opacity + float alpha1 = (texture2D(cloud_noise_texture, uv1).x - 0.5) + (texture2D(cloud_noise_texture, uv3).x - 0.5) * cloud_pos_density2.z; + alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10. * cloud_pos_density1.z, 1.); + + // And smooth + alpha1 = 1. - alpha1 * alpha1; + alpha1 = 1. - alpha1 * alpha1; + + + // Compute alpha2, for self shadowing effect + // (1 - alpha2) will later be used as percentage of incoming sunlight + float alpha2 = (texture2D(cloud_noise_texture, uv2).x - 0.5); + alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.); + + // And smooth + alpha2 = 1. - alpha2; + alpha2 = 1. - alpha2 * alpha2; + + // Combine + vec4 color; + color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient); + color *= 2.; + + /// Gamma correct for WL (soft clip effect). + gl_FragColor.rgb = scaleSoftClip(color.rgb); + gl_FragColor.a = alpha1; +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/linden/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl new file mode 100644 index 0000000..e149d58 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl @@ -0,0 +1,163 @@ +/** + * @file WLCloudsV.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +////////////////////////////////////////////////////////////////////////// +// The vertex shader for creating the atmospheric sky +/////////////////////////////////////////////////////////////////////////////// + +// Output parameters +varying vec4 vary_CloudColorSun; +varying vec4 vary_CloudColorAmbient; +varying float vary_CloudDensity; + +// Inputs +uniform vec3 camPosLocal; + +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; + +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 max_y; + +uniform vec4 glow; + +uniform vec4 cloud_color; + +uniform vec4 cloud_scale; + +void main() +{ + + // World / view / projection + gl_Position = ftransform(); + + gl_TexCoord[0] = gl_MultiTexCoord0; + + // Get relative position + vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0); + + // Set altitude + if (P.y > 0.) + { + P *= (max_y.x / P.y); + } + else + { + P *= (-32000. / P.y); + } + + // Can normalize then + vec3 Pn = normalize(P); + float Plen = length(P); + + // Initialize temp variables + vec4 temp1 = vec4(0.); + vec4 temp2 = vec4(0.); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + + // Sunlight attenuation effect (hue and brightness) due to atmosphere + // this is used later for sunlight modulation at various altitudes + light_atten = (blue_density * 1.0 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x); + + // Calculate relative weights + temp1 = blue_density + haze_density.x; + blue_weight = blue_density / temp1; + haze_weight = haze_density.x / temp1; + + // Compute sunlight from P & lightnorm (for long rays like sky) + temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // Distance + temp2.z = Plen * density_multiplier.x; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z); + + + // Compute haze glow + temp2.x = dot(Pn, lightnorm.xyz); + temp2.x = 1. - temp2.x; + // temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .001); + // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + // Higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + // glow.z should be negative, so we're doing a sort of (1 / "angle") function + + // Add "minimum anti-solar illumination" + temp2.x += .25; + + // Increase ambient when there are more clouds + vec4 tmpAmbient = ambient; + tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5; + + // Dim sunlight by cloud shadow percentage + sunlight *= (1. - cloud_shadow.x); + + // Haze color below cloud + vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient) + + (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient) + ); + + // CLOUDS + + sunlight = sunlight_color; + temp2.y = max(0., lightnorm.y * 2.); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // Cloud color out + vary_CloudColorSun = (sunlight * temp2.x) * cloud_color; + vary_CloudColorAmbient = tmpAmbient * cloud_color; + + // Attenuate cloud color by atmosphere + temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds + vary_CloudColorSun *= temp1; + vary_CloudColorAmbient *= temp1; + vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - temp1); + + // Make a nice cloud density based on the cloud_shadow value that was passed in. + vary_CloudDensity = 2. * (cloud_shadow.x - 0.25); + + + // Texture coords + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_TexCoord[0].xy -= 0.5; + gl_TexCoord[0].xy /= cloud_scale.x; + gl_TexCoord[0].xy += 0.5; + + gl_TexCoord[1] = gl_TexCoord[0]; + gl_TexCoord[1].x += lightnorm.x * 0.0125; + gl_TexCoord[1].y += lightnorm.z * 0.0125; + + gl_TexCoord[2] = gl_TexCoord[0] * 16.; + gl_TexCoord[3] = gl_TexCoord[1] * 16.; + + // Combine these to minimize register use + vary_CloudColorAmbient += oHazeColorBelowCloud; + + // needs this to compile on mac + //vary_AtmosAttenuation = vec3(0.0,0.0,0.0); + + // END CLOUDS +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/linden/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl new file mode 100644 index 0000000..5410889 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl @@ -0,0 +1,24 @@ +/** + * @file gammaF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform vec4 gamma; + +vec3 getAtmosAttenuation(); + +/// Soft clips the light with a gamma correction +vec3 scaleSoftClip(vec3 light) { + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + + return light; +} + +vec3 fullbrightScaleSoftClip(vec3 light) { + return mix(scaleSoftClip(light.rgb), light.rgb, getAtmosAttenuation()); +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/linden/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl new file mode 100644 index 0000000..bc6d6d3 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl @@ -0,0 +1,41 @@ +/** + * @file WLSkyF.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +///////////////////////////////////////////////////////////////////////// +// The fragment shader for the sky +///////////////////////////////////////////////////////////////////////// + +varying vec4 vary_HazeColor; + +uniform sampler2D cloud_noise_texture; +uniform vec4 gamma; + +/// Soft clips the light with a gamma correction +vec3 scaleSoftClip(vec3 light) { + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + + return light; +} + +void main() +{ + // Potential Fill-rate optimization. Add cloud calculation + // back in and output alpha of 0 (so that alpha culling kills + // the fragment) if the sky wouldn't show up because the clouds + // are fully opaque. + + vec4 color; + color = vary_HazeColor; + color *= 2.; + + /// Gamma correct for WL (soft clip effect). + gl_FragColor.rgb = scaleSoftClip(color.rgb); + gl_FragColor.a = 1.0; +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/linden/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl new file mode 100644 index 0000000..e396aea --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl @@ -0,0 +1,138 @@ +/** + * @file WLSkyV.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +// SKY //////////////////////////////////////////////////////////////////////// +// The vertex shader for creating the atmospheric sky +/////////////////////////////////////////////////////////////////////////////// + +// Output parameters +varying vec4 vary_HazeColor; + +// Inputs +uniform vec3 camPosLocal; + +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; + +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 max_y; + +uniform vec4 glow; + +uniform vec4 cloud_color; + +uniform vec4 cloud_scale; + +void main() +{ + + // World / view / projection + gl_Position = ftransform(); + gl_TexCoord[0] = gl_MultiTexCoord0; + + // Get relative position + vec3 P = gl_Vertex.xyz - camPosLocal.xyz + vec3(0,50,0); + //vec3 P = gl_Vertex.xyz + vec3(0,50,0); + + // Set altitude + if (P.y > 0.) + { + P *= (max_y.x / P.y); + } + else + { + P *= (-32000. / P.y); + } + + // Can normalize then + vec3 Pn = normalize(P); + float Plen = length(P); + + // Initialize temp variables + vec4 temp1 = vec4(0.); + vec4 temp2 = vec4(0.); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + + // Sunlight attenuation effect (hue and brightness) due to atmosphere + // this is used later for sunlight modulation at various altitudes + light_atten = (blue_density * 1.0 + haze_density.x * 0.25) * (density_multiplier.x * max_y.x); + + // Calculate relative weights + temp1 = blue_density + haze_density.x; + blue_weight = blue_density / temp1; + haze_weight = haze_density.x / temp1; + + // Compute sunlight from P & lightnorm (for long rays like sky) + temp2.y = max(0., max(0., Pn.y) * 1.0 + lightnorm.y ); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // Distance + temp2.z = Plen * density_multiplier.x; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z); + + + // Compute haze glow + temp2.x = dot(Pn, lightnorm.xyz); + temp2.x = 1. - temp2.x; + // temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .001); + // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + // Higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + // glow.z should be negative, so we're doing a sort of (1 / "angle") function + + // Add "minimum anti-solar illumination" + temp2.x += .25; + + + // Haze color above cloud + vary_HazeColor = ( blue_horizon * blue_weight * (sunlight + ambient) + + (haze_horizon.r * haze_weight) * (sunlight * temp2.x + ambient) + ); + + + // Increase ambient when there are more clouds + vec4 tmpAmbient = ambient; + tmpAmbient += (1. - tmpAmbient) * cloud_shadow.x * 0.5; + + // Dim sunlight by cloud shadow percentage + sunlight *= (1. - cloud_shadow.x); + + // Haze color below cloud + vec4 additiveColorBelowCloud = ( blue_horizon * blue_weight * (sunlight + tmpAmbient) + + (haze_horizon.r * haze_weight) * (sunlight * temp2.x + tmpAmbient) + ); + + // Final atmosphere additive + vary_HazeColor *= (1. - temp1); + + // Attenuate cloud color by atmosphere + temp1 = sqrt(temp1); //less atmos opacity (more transparency) below clouds + + // At horizon, blend high altitude sky color towards the darker color below the clouds + vary_HazeColor += (additiveColorBelowCloud - vary_HazeColor) * (1. - sqrt(temp1)); + + // won't compile on mac without this being set + //vary_AtmosAttenuation = vec3(0.0,0.0,0.0); +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/linden/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl new file mode 100644 index 0000000..b7678ca --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl @@ -0,0 +1,35 @@ +/** + * @file transportF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +////////////////////////////////////////////////////////// +// The fragment shader for the terrain atmospherics +////////////////////////////////////////////////////////// + +vec3 getAdditiveColor(); +vec3 getAtmosAttenuation(); + +uniform sampler2D cloudMap; +uniform vec4 cloud_pos_density1; + +vec3 atmosTransport(vec3 light) { + light *= getAtmosAttenuation().r; + 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 fullbrightShinyAtmosTransport(vec3 light) { + float brightness = dot(light.rgb, vec3(0.33333)); + + return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness); +} + diff --git a/linden/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl b/linden/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl index 2505afe..04c1053 100644 --- a/linden/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl +++ b/linden/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl @@ -1,10 +1,14 @@ -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec3 baseCol); -mat4 getSkinnedTransform(); -void default_scatter(vec3 viewVec, vec3 lightDir); +/** + * @file avatarV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ -attribute vec4 materialColor; //2 +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +mat4 getSkinnedTransform(); +void calcAtmospherics(vec3 inPositionEye); -attribute vec4 binormal; //6 attribute vec4 clothing; //4 attribute vec4 gWindDir; //7 @@ -27,102 +31,80 @@ void main() norm.z = dot(trans[2].xyz, gl_Normal); norm = normalize(norm); - vec3 binorm; - binorm.x = dot(trans[0].xyz, binormal.xyz); - binorm.y = dot(trans[1].xyz, binormal.xyz); - binorm.z = dot(trans[2].xyz, binormal.xyz); - norm = normalize(norm); - //wind vec4 windEffect; - windEffect = vec4(dot(norm, gWindDir.xyz)); // DP3 windEffect, blendNorm, gWindDir; - pos.x = dot(trans[2].xyz, gl_Vertex.xyz); // DP3 blendPos.x, blendMatZ, iPos; + windEffect = vec4(dot(norm, gWindDir.xyz)); + pos.x = dot(trans[2].xyz, gl_Vertex.xyz); windEffect.xyz = pos.x * vec3(0.015, 0.015, 0.015) - + windEffect.xyz; // MAD windEffect.xyz, blendPos.x, {0.015, 0.015, 0.015, 0}, windEffect; - windEffect.w = windEffect.w * 2.0 + 1.0; // MAD windEffect.w, windEffect, {0, 0, 0, 2}, {0, 0, 0, 1}; # move wind offset value to [-1, 3] - windEffect.w = windEffect.w*gWindDir.w; // MUL windEffect.w, windEffect, gWindDir; # modulate wind strength + + windEffect.xyz; + windEffect.w = windEffect.w * 2.0 + 1.0; // move wind offset value to [-1, 3] + windEffect.w = windEffect.w*gWindDir.w; // modulate wind strength windEffect.xyz = windEffect.xyz*gSinWaveParams.xyz - +vec3(gSinWaveParams.w); // MAD windEffect.xyz, windEffect, gSinWaveParams, gSinWaveParams.w; # use sin wave params to scale and offset input + +vec3(gSinWaveParams.w); // use sin wave params to scale and offset input //reduce to period of 2 PI vec4 temp1, temp0, temp2, offsetPos; - temp1.xyz = windEffect.xyz * gPiConstants.x; // MUL temp1.xyz, windEffect, gPiConstants.x; # change input as multiple of [0-2PI] to [0-1] - temp0.y = mod(temp1.x,1.0); // EXP temp0, temp1.x; # find mod(x, 1) - windEffect.x = temp0.y * gPiConstants.y; // MUL windEffect.x, temp0.y, gPiConstants.y; # scale from [0,1] to [0, 2PI] - temp1.z = temp1.z - gPiConstants.w; // ADD temp1.z, temp1.z, -gPiConstants.w; # shift normal oscillation by PI/2 - temp0.y = mod(temp1.z,1.0); // EXP temp0, temp1.z; # find mod(x, 1) + temp1.xyz = windEffect.xyz * gPiConstants.x; // change input as multiple of [0-2PI] to [0-1] + temp0.y = mod(temp1.x,1.0); + windEffect.x = temp0.y * gPiConstants.y; // scale from [0,1] to [0, 2PI] + temp1.z = temp1.z - gPiConstants.w; // shift normal oscillation by PI/2 + temp0.y = mod(temp1.z,1.0); - windEffect.z = temp0.y * gPiConstants.y; // MUL windEffect.z, temp0.y, gPiConstants.y; # scale from [0,1] to [0, 2PI] - windEffect.xyz = windEffect.xyz + vec3(-3.141592); // # offset to [-PI, PI] - // ADD windEffect.xyz, windEffect, {-3.141592, -3.141592, -3.141592, -3.141592}; + windEffect.z = temp0.y * gPiConstants.y; // scale from [0,1] to [0, 2PI] + windEffect.xyz = windEffect.xyz + vec3(-3.141592); // offset to [-PI, PI] + //calculate sinusoid vec4 sinWave; - temp1 = windEffect*windEffect; // MUL temp1, windEffect, windEffect; # x^2 + temp1 = windEffect*windEffect; sinWave = -temp1 * gMinMaxConstants.w - + vec4(gMinMaxConstants.z); // MAD sinWave, -temp1, gMinMaxConstants.w, gMinMaxConstants.z; # y = -(x^2)/7! + 1/5! - sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.y); // MAD sinWave, sinWave, -temp1, gMinMaxConstants.y; # y = -(x^2) * (-(x^2)/7! + 1/5!) + 1/3! - sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.x); // MAD sinWave, sinWave, -temp1, gMinMaxConstants.x; # y = -(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1 - sinWave = sinWave * windEffect; // MUL sinWave, sinWave, windEffect; # y = x * (-(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1) + + vec4(gMinMaxConstants.z); // y = -(x^2)/7! + 1/5! + sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.y); // y = -(x^2) * (-(x^2)/7! + 1/5!) + 1/3! + sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.x); // y = -(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1 + sinWave = sinWave * windEffect; // y = x * (-(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1) // sinWave.x holds sin(norm . wind_direction) with primary frequency // sinWave.y holds sin(norm . wind_direction) with secondary frequency // sinWave.z hold cos(norm . wind_direction) with primary frequency sinWave.xyz = sinWave.xyz * gWindDir.w - + vec3(windEffect.w); // MAD sinWave.xyz, sinWave, gWindDir.w, windEffect.w; # multiply by wind strength in gWindDir.w [-wind, wind] + + vec3(windEffect.w); // multiply by wind strength in gWindDir.w [-wind, wind] // add normal facing bias offset [-wind,wind] -> [-wind - .25, wind + 1] - temp1 = vec4(dot(norm, gGravity.xyz)); // DP3 temp1, blendNorm, gGravity; # how much is this normal facing in direction of gGravity? - temp1 = min(temp1, vec4(0.2,0.0,0.0,0.0)); // MIN temp1, temp1, {0.2, 0, 0, 0}; # clamp [-1, 1] to [-1, 0.2] - temp1 = temp1*vec4(1.5,0.0,0.0,0.0); // MUL temp1, temp1, {1.5, 0, 0, 0}; # scale from [-1,0.2] to [-1.5, 0.3] - sinWave.x = sinWave.x + temp1.x; // ADD sinWave.x, sinWave, temp1; # add gGravity effect to sinwave (only primary frequency) - sinWave.xyz = sinWave.xyz * clothing.w; // MUL sinWave.xyz, sinWave, iClothing.w; # modulate by clothing coverage + temp1 = vec4(dot(norm, gGravity.xyz)); // how much is this normal facing in direction of gGravity? + temp1 = min(temp1, vec4(0.2,0.0,0.0,0.0)); // clamp [-1, 1] to [-1, 0.2] + temp1 = temp1*vec4(1.5,0.0,0.0,0.0); // scale from [-1,0.2] to [-1.5, 0.3] + sinWave.x = sinWave.x + temp1.x; // add gGravity effect to sinwave (only primary frequency) + sinWave.xyz = sinWave.xyz * clothing.w; // modulate by clothing coverage - sinWave.xyz = max(sinWave.xyz, vec3(-1.0, -1.0, -1.0)); // MAX sinWave.xyz, sinWave, {-1, -1, -1, -1}; # clamp to underlying body shape - offsetPos = clothing * sinWave.x; // MUL offsetPos, iClothing, sinWave.x; # multiply wind effect times clothing displacement - temp2 = gWindDir*sinWave.z + vec4(norm,0); // MAD temp2, gWindDir, sinWave.z, blendNorm; # calculate normal offset due to wind oscillation - offsetPos = vec4(1.0,1.0,1.0,0.0)*offsetPos+gl_Vertex; // MAD offsetPos, {1.0, 1.0, 1.0, 0.0}, offsetPos, iPos; # add to offset vertex position, and zero out effect from w - norm += temp2.xyz*2.0; // MAD blendNorm, temp2, {2, 2, 2, 2}, blendNorm; # add sin wave effect on normals (exaggerated) + sinWave.xyz = max(sinWave.xyz, vec3(-1.0, -1.0, -1.0)); // clamp to underlying body shape + offsetPos = clothing * sinWave.x; // multiply wind effect times clothing displacement + temp2 = gWindDir*sinWave.z + vec4(norm,0); // calculate normal offset due to wind oscillation + offsetPos = vec4(1.0,1.0,1.0,0.0)*offsetPos+gl_Vertex; // add to offset vertex position, and zero out effect from w + norm += temp2.xyz*2.0; // add sin wave effect on normals (exaggerated) //add "backlighting" effect float colorAcc; - colorAcc = 1.0 - clothing.w; // SUB colorAcc, {1, 1, 1, 1}, iClothing; - norm.z -= colorAcc * 0.2; // MAD blendNorm, colorAcc.w, {0, 0, -0.2, 0}, blendNorm; + colorAcc = 1.0 - clothing.w; + norm.z -= colorAcc * 0.2; //renormalize normal (again) - norm = normalize(norm); // DP3 divisor.w, blendNorm, blendNorm; - // RSQ divisor.xyz, divisor.w; - // MUL blendNorm.xyz, blendNorm, divisor; - - //project binormal to normal plane to ensure orthogonality - temp2 = vec4(dot(norm, binorm)); // DP3 temp2, blendNorm, blendBinorm; - binorm = binorm - temp2.xyz; // SUB blendBinorm, blendBinorm, temp2; - - //renormalize binormal - binorm = normalize(binorm); // DP3 divisor.w, blendBinorm, blendBinorm; - // RSQ divisor.xyz, divisor.w; - // MUL blendBinorm.xyz, blendBinorm, divisor; + norm = normalize(norm); pos.x = dot(trans[0], offsetPos); pos.y = dot(trans[1], offsetPos); pos.z = dot(trans[2], offsetPos); pos.w = 1.0; + + calcAtmospherics(pos.xyz); - vec4 color = calcLighting(pos.xyz, norm, materialColor, gl_Color.rgb); + vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.0)); gl_FrontColor = color; gl_Position = gl_ProjectionMatrix * pos; - vec3 N = norm; - vec3 B = binorm; - vec3 T = cross(N,B); - //gl_TexCoord[1].xy = gl_MultiTexCoord0.xy + 1.0/512.0 * vec2(dot(T,gl_LightSource[0].position.xyz), - // dot(B,gl_LightSource[0].position.xyz)); - gl_TexCoord[2] = vec4(pos.xyz, 1.0); - default_scatter(pos.xyz, gl_LightSource[0].position.xyz); - -} \ No newline at end of file + +} diff --git a/linden/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/linden/indra/newview/app_settings/shaders/class3/environment/waterF.glsl deleted file mode 100644 index ac8b07c..0000000 --- a/linden/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ /dev/null @@ -1,145 +0,0 @@ -void applyScatter(inout vec3 color); - -uniform sampler2D diffuseMap; -uniform sampler2D bumpMap; -uniform samplerCube environmentMap; //: TEXUNIT4, // Environment map texture -uniform sampler2D screenTex; // : TEXUNIT5 - -uniform vec3 lightDir; -uniform vec3 specular; -uniform float lightExp; -uniform vec2 fbScale; -uniform float refScale; - -float msin(float x) { - float k = sin(x)+1.0; - k *= 0.5; - k *= k; - return 2.0 * k; -} - -float mcos(float x) { - float k = cos(x)+1.0; - k *= 0.5; - k *= k; - return 2.0 * k; -} - -float waveS(vec2 v, float t, float a, float f, vec2 d, float s, sampler1D sinMap) -{ - return texture1D(sinMap, (dot(d, v)*f + t*s)*f).r*a; -} - -float waveC(vec2 v, float t, float a, float f, vec2 d, float s, sampler1D sinMap) -{ - return texture1D(sinMap, (dot(d, v)*f + t*s)*f).g*a*2.0-1.0; -} - -float magnitude(vec3 vec) { - return sqrt(dot(vec,vec)); -} - -vec3 mreflect(vec3 i, vec3 n) { - return i + n * 2.0 * abs(dot(n,i))+vec3(0.0,0.0,0.5); -} - -void main() -{ - vec2 texCoord = gl_TexCoord[0].xy; // Texture coordinates - vec2 littleWave1 = gl_TexCoord[0].zw; - vec2 littleWave2 = gl_TexCoord[1].xy; - vec2 bigWave = gl_TexCoord[1].zw; - vec3 viewVec = gl_TexCoord[2].xyz; - vec4 refCoord = gl_TexCoord[3]; - vec4 col = gl_Color; - vec4 color; - - //get color from alpha map (alpha denotes water depth), rgb denotes water color - vec4 wcol = texture2D(diffuseMap, texCoord.xy); - - float dist = length(viewVec); - - //store texture alpha - float da = wcol.a; - - //modulate by incoming water color - //wcol.a *= refCoord.w; - - //scale wcol.a (water depth) for steep transition - wcol.a *= wcol.a; - - //normalize view vector - viewVec = normalize(viewVec); - - //get bigwave normal - vec3 wavef = texture2D(bumpMap, bigWave).xyz*2.0; - - vec3 view = vec3(viewVec.x, viewVec.y, viewVec.z); - - float dx = 1.0-(dot(wavef*2.0-vec3(1.0), view))*da; - dx *= 0.274; - - //get detail normals - vec3 dcol = texture2D(bumpMap, littleWave1+dx*view.xy).rgb*0.75; - dcol += texture2D(bumpMap, littleWave2+view.xy*dx*0.1).rgb*1.25; - - //interpolate between big waves and little waves (big waves in deep water) - wavef = wavef*wcol.a + dcol*(1.0-wcol.a); - - //crunch normal to range [-1,1] - wavef -= vec3(1,1,1); - wavef = normalize(wavef); - //wavef = vec3(0.0, 0.0, 1.0); - - //get base fresnel component - float df = dot(viewVec,wavef); - //translate and flip fresnel - df = 1.0-clamp(-df,0.0,1.0); - - //set output alpha based on fresnel - color.a = clamp((1.0-df+da)*0.5,0.0,1.0); - - //calculate reflection vector - vec3 refnorm = vec3(wavef.x*0.5, wavef.y*0.5, wavef.z*2.0); - - //ramp normal towards eye for far view stuff - float ramp = dist/256.0; - refnorm -= viewVec * ramp; - vec3 ref = reflect(viewVec.xyz, normalize(refnorm)); - ref.z /= sqrt(dist); - - //get diffuse component - float diff = clamp(dot(ref, wavef),0.0,1.0)*0.9; - - //fudge diffuse for extra contrast and ambience - diff *= diff; - diff += 0.4; - - vec3 fog = gl_TexCoord[5].rgb*0.5; - - //read from reflection map - vec3 refcol = textureCube(environmentMap, ref).rgb; - //tint reflection by fresnal, bias by z component of view vec - color.rgb = refcol*(df*df*dcol.x*dcol.y); - - //add diffuse contribution (fake blue water, yay!) - vec3 blue = vec3(0.1, 0.3, 0.6); - color.rgb += (diff/(max(ramp, 1.0)))*vec3(fog.r*blue.r, fog.g*blue.g, fog.b*blue.b); - - //figure out distortion vector (ripply) - vec2 distort = clamp(((refCoord.xy/refCoord.z) * 0.5 + 0.5 + wavef.xy*refScale),0.0,0.99); - - //read from framebuffer (offset) - vec4 fb = texture2D(screenTex, distort*fbScale); - - //tint by framebuffer - color.rgb = da*color.rgb + (1.0-da)*fb.rgb; - - //render as solid (previous pixel color already present) - color.a = 1.0; - - //apply fog - applyScatter(color.rgb); - - gl_FragColor = color; -} diff --git a/linden/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl b/linden/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl new file mode 100644 index 0000000..bf5c78f --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl @@ -0,0 +1,44 @@ +/** + * @file sumLightsV.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da); +vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 atmosGetDiffuseSunlightColor(); +vec3 scaleDownLight(vec3 light); + +vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol) +{ + vec4 col = vec4(0.0, 0.0, 0.0, color.a); + + vec3 view = normalize(pos); + + /// collect all the specular values from each calcXXXLightSpecular() function + vec4 specularSum = vec4(0.0); + + // Collect normal lights (need to be divided by two, as we later multiply by 2) + col.rgb += gl_LightSource[1].diffuse.rgb * calcDirectionalLightSpecular(specularColor, view, norm, gl_LightSource[1].position.xyz,gl_LightSource[1].diffuse.rgb, 1.0); + col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[2].position.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation,gl_LightSource[2].diffuse.rgb); + col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[3].position.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation,gl_LightSource[3].diffuse.rgb); + col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[4].position.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation,gl_LightSource[4].diffuse.rgb); + col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[5].position.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation,gl_LightSource[5].diffuse.rgb); + col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[6].position.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation,gl_LightSource[6].diffuse.rgb); + col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, gl_LightSource[7].position.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation,gl_LightSource[7].diffuse.rgb); + col.rgb = scaleDownLight(col.rgb); + + // Add windlight lights + col.rgb += atmosAmbient(baseCol.rgb); + col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, gl_LightSource[0].position.xyz,atmosGetDiffuseSunlightColor()*baseCol.a, 1.0)); + + col.rgb = min(col.rgb*color.rgb, 1.0); + specularColor.rgb = min(specularColor.rgb*specularSum.rgb, 1.0); + + col.rgb += specularColor.rgb; + return col; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/linden/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl new file mode 100644 index 0000000..1c5234c --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl @@ -0,0 +1,41 @@ +/** + * @file sumLightsV.glsl + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +float calcDirectionalLight(vec3 n, vec3 l); +float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); +vec3 scaleUpLight(vec3 light); + +vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight) +{ + vec4 col; + col.a = color.a; + + // Add windlight lights + col.rgb = atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz)); + col.rgb += atmosAmbient(baseLight.rgb); + col.rgb = scaleUpLight(col.rgb); + + // Collect normal lights (need to be divided by two, as we later multiply by 2) + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); + col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); + col.rgb = scaleDownLight(col.rgb); + + + col.rgb = min(col.rgb*color.rgb, 1.0); + + return col; +} + diff --git a/linden/indra/newview/app_settings/shaders/class3/objects/bumpshinyF.glsl b/linden/indra/newview/app_settings/shaders/class3/objects/bumpshinyF.glsl deleted file mode 100644 index 9d1a91d..0000000 --- a/linden/indra/newview/app_settings/shaders/class3/objects/bumpshinyF.glsl +++ /dev/null @@ -1,25 +0,0 @@ -vec4 getLightColor(); -void applyScatter(inout vec3 col); - -uniform samplerCube environmentMap; -uniform sampler2D diffuseMap; -uniform sampler2D bumpMap; - -void main() -{ - vec4 diff = texture2D(diffuseMap, gl_TexCoord[0].xy); - float b = texture2D(bumpMap, gl_TexCoord[0].xy).a; - b -= texture2D(bumpMap, gl_TexCoord[2].xy).a; - vec3 ref = textureCube(environmentMap, gl_TexCoord[1].xyz*vec3(1.0,1.0,1.0-b*5.0)).rgb; - vec4 specular = gl_TexCoord[3]; - vec3 col = mix(getLightColor().rgb * diff.rgb, ref, specular.a)+specular.rgb*diff.rgb; - col += col * b; - float m = (col.r + col.g + col.b); - m *= 1.0/3.0; - col = mix(col, vec3(m), -specular.a*specular.a); - - applyScatter(col); - - gl_FragColor.rgb = col; - gl_FragColor.a = diff.a; -} diff --git a/linden/indra/newview/app_settings/shaders/shader_heirarchy.txt b/linden/indra/newview/app_settings/shaders/shader_heirarchy.txt new file mode 100644 index 0000000..d8bbf69 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/shader_heirarchy.txt @@ -0,0 +1,176 @@ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +avatar/avatarV.glsl - gAvatarProgram, gAvatarWaterProgram + main() - avatar/avatarV.glsl + getSkinnedTransform() - avatarSkinV.glsl + calcAtmospherics() - windlight/atmosphericsV.glsl + calcLighting() - lighting/lightV.glsl + sumLights() - lighting/sumLightsV.glsl + calcDirectionalLight() - lighting/lightFuncV.glsl + calcPointLight() - lighting/lightFuncV.glsl + scaleDownLight() - windlight/atmosphericsHelpersV.glsl + atmosAmbient() - windlight/atmosphericsHelpersV.glsl + atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +avatar/avatarF.glsl - gAvatarProgram + main() - avatar/avatarF.glsl + default_lighting() - lighting/lightF.glsl + calc_default_lighting() - lighting/lightF.glsl + atmosLighting() - windlight/atmosphericsF.glsl + scaleSoftClip() - windlight/gammaF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +avatar/eyeballV.glsl - gAvatarEyeballProgram + main() - avatar/eyeballV.glsl + calcAtmospherics() - windlight/atmosphericsV.glsl + calcLightingSpecular() - lighting/lightSpecularV.glsl + sumLightsSpecular() - lighting/sumLightsSpecularV.glsl + calcDirectionalLightSpecular() - lighting/lightFuncSpecularV.glsl + calcPointLightSpecular() - lighting/lightFuncSpecularV.glsl + atmosAmbient() - windlight/atmosphericsHelpersV.glsl + atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl + atmosGetDiffuseSunlightColor() - windlight/atmosphericsHelpersV.glsl + scaleDownLight() - windlight/atmosphericsHelpersV.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +avatar/eyeballF.glsl - gAvatarEyeballProgram + main() - avatar/eyeballF.glsl + default_lighting() - lighting/lightF.glsl + calc_default_lighting() - lighting/lightF.glsl + atmosLighting() - windlight/atmosphericsF.glsl + scaleSoftClip() - windlight/gammaF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +avatar/pickAvatarV.glsl - gAvatarPickProgram + main() - avatar/pickAvatarV.glsl + getSkinnedTransform() - avatarSkinV.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +avatar/pickAvatarF.glsl - gAvatarPickProgram + main() - avatar/pickAvatarF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +environment/terrainV.glsl - gTerrainProgram, gTerrainWaterProgram + texgen_object() - environment/terrainV.glsl + main() - environment/terrainV.glsl + texgen_object() - environment/terrainV.glsl + calcAtmospherics() - windlight/atmosphericsV.glsl + calcLighting() - lighting/lightV.glsl + sumLights() - lighting/sumLightsV.glsl + calcDirectionalLight() - lighting/lightFuncV.glsl + calcPointLight() - lighting/lightFuncV.glsl + scaleDownLight() - windlight/atmosphericsHelpersV.glsl + atmosAmbient() - windlight/atmosphericsHelpersV.glsl + atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +environment/terrainF.glsl - gTerrainProgram + main() - environment/terrainF.glsl + atmosLighting() - windlight/atmosphericsF.glsl + scaleSoftClip() - windlight/gammaF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +environment/terrainWaterF.glsl - gTerrainWaterProgram + main() - environment/terrainWaterF.glsl + atmosLighting() - windlight/atmosphericsF.glsl + applyWaterFog() - environment/waterFogF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +environment/underWaterF.glsl - gUnderWaterProgram + applyWaterFog() - environment/underWaterF.glsl (NOTE: different than one in waterFogF.glsl) + main() - environment/underWaterF.glsl + applyWaterFog() - environment/underWaterF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +environment/waterV.glsl - gWaterProgram, gUnderWaterProgram + main() - environment/waterV.glsl + calcAtmospherics() - windlight/atmosphericsV.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +environment/waterF.glsl - gWaterProgram + main() - environment/waterF.glsl + atmosTransport() - windlight/transportF.glsl + scaleSoftClip() - windlight/gammaF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +objects/fullbrightV.glsl - gObjectFullbrightProgram, gObjectFullbrightWaterProgram + main() - objects/fullbrightV.glsl + calcAtmospherics() - windlight/atmosphericsV.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +objects/fullbrightF.glsl - gObjectFullbrightProgram + main() - objects/fullbrightF.glsl + fullbright_lighting() - lighting/lightFullbrightF.glsl + fullbrightAtmosTransport() - windlight/transportF.glsl + atmosTransport() - windlight/transportF.glsl + fullbrightScaleSoftClip() - windlight/gammaF.glsl + scaleSoftClip() - windlight/gammaF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +objects/fullbrightShinyV.glsl - gObjectFullbrightShinyProgram + main() - objects/fullbrightShinyV.glsl + calcAtmospherics() - windlight/atmosphericsV.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +objects/fullbrightShinyF.glsl - gObjectFullbrightShinyProgram + main() - objects/fullbrightShinyF.glsl + fullbright_shiny_lighting() - lighting/lightFullbrightShinyF.glsl + fullbrightShinyAtmosTransport() - windlight/transportF.glsl + atmosTransport() - windlight/transportF.glsl + fullbrightScaleSoftClip() - windlight/gammaF.glsl + scaleSoftClip() - windlight/gammaF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +objects/fullbrightWaterF.glsl - gObjectFullbrightWaterProgram + main() - objects/fullbrightWaterF.glsl + fullbright_lighting_water() - lighting/lightFullbrightWaterF.glsl + fullbrightAtmosTransport() - windlight/transportF.glsl + atmosTransport() - windlight/transportF.glsl + applyWaterFog() - environment/waterFogF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +objects/shinyV.glsl - gObjectShinyProgram, gObjectShinyWaterProgram + main() - objects/shinyV.glsl + calcAtmospherics() - windlight/atmosphericsV.glsl + calcLighting() - lighting/lightV.glsl + calcLighting(vec4) - lighting/lightV.glsl + sumLights() - lighting/sumLightsV.glsl + calcDirectionalLight() - lighting/lightFuncV.glsl + calcPointLight() - lighting/lightFuncV.glsl + scaleDownLight() - windlight/atmosphericsHelpersV.glsl + atmosAmbient() - windlight/atmosphericsHelpersV.glsl + atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +objects/shinyF.glsl - gObjectShinyProgram + main() - objects/shinyF.glsl + shiny_lighting() - lighting/lightShinyF.glsl + atmosLighting() - windlight/atmosphericsF.glsl + scaleSoftClip() - windlight/gammaF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +objects/shinyWaterF.glsl - gObjectShinyWaterProgram + main() - objects/shinyWaterF.glsl + shiny_lighting_water() - lighting/lightShinyWaterF.glsl + atmosLighting() - windlight/atmosphericsF.glsl + applyWaterFog() - environment/waterFogF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +objects/simpleV.glsl - gObjectSimpleProgram, gObjectSimpleWaterProgram + main() - objects/simpleV.glsl + calcAtmospherics() - windlight/atmosphericsV.glsl + calcLighting() - lighting/lightV.glsl + sumLights() - lighting/sumLightsV.glsl + calcDirectionalLight() - lighting/lightFuncV.glsl + calcPointLight() - lighting/lightFuncV.glsl + scaleDownLight() - windlight/atmosphericsHelpersV.glsl + atmosAmbient() - windlight/atmosphericsHelpersV.glsl + atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +objects/simpleF.glsl - gObjectSimpleProgram + main() - objects/simpleF.glsl + default_lighting() - lighting/lightF.glsl + atmosLighting() - windlight/atmosphericsF.glsl + scaleSoftClip() - windlight/gammaF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +objects/simpleWaterF.glsl - gObjectSimpleWaterProgram, gAvatarWaterProgram + main() - objects/simpleWaterF.glsl + default_lighting_water() - lighting/lightWaterF.glsl + atmosLighting() - windlight/atmosphericsF.glsl + applyWaterFog() - environment/waterFogF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +windlight/skyV.glsl - gWLSkyProgram + main() - windlight/skyV.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +windlight/skyF.glsl - gWLSkyProgram + main() - windlight/skyF.glsl + scaleSoftClip() - windlight/gammaF.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +windlight/cloudsV.glsl - gWLCloudProgram + main() - windlight/cloudsV.glsl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +windlight/cloudsF.glsl - gWLCloudProgram + main() - windlight/cloudsF.glsl + scaleSoftClip() - windlight/gammaF.glsl + + diff --git a/linden/indra/newview/app_settings/ultra_graphics.xml b/linden/indra/newview/app_settings/ultra_graphics.xml new file mode 100644 index 0000000..f16ec6c --- /dev/null +++ b/linden/indra/newview/app_settings/ultra_graphics.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/newview/app_settings/windlight/clouds2.tga b/linden/indra/newview/app_settings/windlight/clouds2.tga new file mode 100644 index 0000000..c95ce7f Binary files /dev/null and b/linden/indra/newview/app_settings/windlight/clouds2.tga differ diff --git a/linden/indra/newview/app_settings/windlight/days/Default.xml b/linden/indra/newview/app_settings/windlight/days/Default.xml new file mode 100644 index 0000000..3d3afd5 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/days/Default.xml @@ -0,0 +1,36 @@ + + + + 0 + A-12AM + + + 0.125 + A-3AM + + + 0.25 + A-6AM + + + 0.375 + A-9AM + + + 0.5 + A-12PM + + + 0.625 + A-3PM + + + 0.75 + A-6PM + + + 0.875 + A-9PM + + + diff --git a/linden/indra/newview/app_settings/windlight/postprocesseffects.xml b/linden/indra/newview/app_settings/windlight/postprocesseffects.xml new file mode 100644 index 0000000..4645215 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/postprocesseffects.xml @@ -0,0 +1,2 @@ +Asi Weirdbloom_strength4.5799999237060547bloom_width12.539999961853027brightness0.89999997615814209brightness_multiplier3contrast0.22999998927116394contrast_base1110.5enable_bloom1enable_color_filter1enable_night_vision0extract_high1extract_low0.47999998927116394noise_size25noise_strength0.40000000000000002saturation-1NegativeSaturationbloom_strength1.5bloom_width2.25brightness1brightness_multiplier3contrast1contrast_base1110.5enable_bloom0enable_color_filter1enable_night_vision0extract_high1extract_low0.94999999999999996noise_size25noise_strength0.40000000000000002saturation-1NightVisionbloom_strength1.5bloom_width2.25brightness1brightness_multiplier3contrast1contrast_base1110.5enable_bloom0enable_color_filter0enable_night_vision1extract_high1extract_low0.94999999999999996noise_size25noise_strength0.40000000000000002saturation1WGhostbloom_strength2.0399999618530273bloom_width2.25brightness1brightness_multiplier3contrast1contrast_base1110.5enable_bloom1enable_color_filter0enable_night_vision0extract_high1extract_low0.22999998927116394noise_size25noise_strength0.40000000000000002saturation1defaultbloom_strength1.5bloom_width2.25brightness1brightness_multiplier3contrast1contrast_base1110.5enable_bloom0enable_color_filter0enable_night_vision0extract_high1extract_low0.94999999999999996noise_size25noise_strength0.40000000000000002saturation1 +>bloom_strength1.5bloom_width2.25brightness1brightness_multiplier3contrast1contrast_base1110.5enable_bloom0enable_color_filter0enable_night_vision0extract_high1extract_low0.94999999999999996noise_size25noise_strength0.40000000000000002saturation1
diff --git a/linden/indra/newview/app_settings/windlight/skies/A%2D12AM.xml b/linden/indra/newview/app_settings/windlight/skies/A%2D12AM.xml new file mode 100644 index 0000000..0aba312 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/A%2D12AM.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.20405027270317078 + 0.24246673285961151 + 0.32999998331069946 + 0.10999999940395355 + + blue_density + + 0.44999998807907104 + 0.44999998807907104 + 0.44999998807907104 + 1 + + blue_horizon + + 0.23999999463558197 + 0.23999999463558197 + 0.23999999463558197 + 1 + + cloud_color + + 0.22615399956703186 + 0.22615399956703186 + 0.22615399956703186 + 1 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 0.87999999523162842 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940013885498 + 10.01099967956543 + + cloud_shadow + + 0.26999998092651367 + 0 + 0 + 1 + + density_multiplier + + 0.00030000001424923539 + 0 + 0 + 1 + + distance_multiplier + + 0 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.47999998927116394 + 1 + + haze_density + + 4 + 0 + 0 + 1 + + haze_horizon + + 0 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 1 + -4.8876205482883961e-007 + 1 + + max_y + + 906.20001220703125 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 2 + sun_angle + 4.7123894691467285 + sunlight_color + + 0.34876692295074463 + 0.35574248433113098 + 0.65999996662139893 + 0.2199999988079071 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/A%2D12PM.xml b/linden/indra/newview/app_settings/windlight/skies/A%2D12PM.xml new file mode 100644 index 0000000..119b3e1 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/A%2D12PM.xml @@ -0,0 +1,141 @@ + + + ambient + + 1.0499999523162842 + 1.0499999523162842 + 1.0499999523162842 + 0.34999999403953552 + + blue_density + + 0.24475815892219543 + 0.44872328639030457 + 0.75999999046325684 + 0.37999999523162842 + + blue_horizon + + 0.49548381567001343 + 0.49548381567001343 + 0.63999998569488525 + 0.31999999284744263 + + cloud_color + + 0.40999999642372131 + 0.40999999642372131 + 0.40999999642372131 + 0.40999999642372131 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 1 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.199999809265137 + 10.01099967956543 + + cloud_shadow + + 0.26999998092651367 + 0 + 0 + 1 + + density_multiplier + + 0.00017999998817685992 + 0 + 0 + 1 + + distance_multiplier + + 0.80000001192092896 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.47999998927116394 + 1 + + haze_density + + 0.69999998807907104 + 0 + 0 + 1 + + haze_horizon + + 0.18999999761581421 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 1 + -4.3711388286737929e-008 + 0 + + max_y + + 1605 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 1.5707963705062866 + sunlight_color + + 0.7342105507850647 + 0.78157895803451538 + 0.89999997615814209 + 0.29999998211860657 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/A%2D3AM.xml b/linden/indra/newview/app_settings/windlight/skies/A%2D3AM.xml new file mode 100644 index 0000000..f790d3d --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/A%2D3AM.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.22259476780891418 + 0.26450252532958984 + 0.35999998450279236 + 0.11999999731779099 + + blue_density + + 0.44999116536295314 + 0.44999854555993368 + 0.45001013284446073 + 1 + + blue_horizon + + 0.23999616268583132 + 0.239999227803052 + 0.24000028550619668 + 1 + + cloud_color + + 0.22615400241566114 + 0.22615400241566114 + 0.22615400241566114 + 1 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 0.88000000953681223 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.499400354105791 + 10.011000104419489 + + cloud_shadow + + 0.26999998092651367 + 0 + 0 + 1 + + density_multiplier + + 0.0003000046529240592 + 0 + 0 + 1 + + distance_multiplier + + 7.8213197608078763e-005 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5.0000000000023022 + 0.0010000000214220922 + -0.47999999165507345 + 1 + + haze_density + + 3.9999044060931555 + 0 + 0 + 1 + + haze_horizon + + 4.6348559691012062e-006 + 0.19915600437461423 + 0.19915600437461423 + 1 + + lightnorm + + 0 + 0.70710653066635132 + -0.70710700750350952 + 1 + + max_y + + 906.19008370909478 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 1.9999420642852783 + sun_angle + 5.4977874755859375 + sunlight_color + + 0.60242295265197754 + 0.61447036266326904 + 1.1399999856948853 + 0.37999999523162842 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/A%2D3PM.xml b/linden/indra/newview/app_settings/windlight/skies/A%2D3PM.xml new file mode 100644 index 0000000..ec97067 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/A%2D3PM.xml @@ -0,0 +1,141 @@ + + + ambient + + 1.0499999523162842 + 1.0499999523162842 + 1.0499999523162842 + 0.34999999403953552 + + blue_density + + 0.2447581488182351 + 0.44872328639030457 + 0.75999999046325684 + 0.38000004053115788 + + blue_horizon + + 0.49548382097675159 + 0.49548381382419748 + 0.63999999284744291 + 0.31999999642372146 + + cloud_color + + 0.40999999165535073 + 0.40999999165535073 + 0.40999999165535073 + 0.40999999165535073 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 0.99999999999999289 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.4199999868869746 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.199999809265137 + 10.01099967956543 + + cloud_shadow + + 0.26999998092651367 + 0 + 0 + 1 + + density_multiplier + + 0.00017999998817685818 + 0 + 0 + 1 + + distance_multiplier + + 0.80000001192093606 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.47999998927116394 + 1 + + haze_density + + 0.69999998807907104 + 0 + 0 + 1 + + haze_horizon + + 0.18999999761581243 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.70710659027099609 + -0.70710694789886475 + 0 + + max_y + + 1605 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 2.3561947345733643 + sunlight_color + + 0.73421055078505759 + 0.78157895803450828 + 0.89999997615813498 + 0.29999998211860301 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/A%2D6AM.xml b/linden/indra/newview/app_settings/windlight/skies/A%2D6AM.xml new file mode 100644 index 0000000..bbc7aee --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/A%2D6AM.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.80999994277954102 + 0.46289783716201782 + 0.62999993562698364 + 0.26999998092651367 + + blue_density + + 0.15793180465698242 + 0.43499568104743958 + 0.87000000476837158 + 0.87000000476837158 + + blue_horizon + + 0.20673196017742157 + 0.40988314151763916 + 0.47999998927116394 + 0.47999998927116394 + + cloud_color + + 0.22616604226328718 + 0.22616604226328718 + 0.22616604226328718 + 0.99997219085526012 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 0.88000025272481253 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940013883861 + 10.010999679576344 + + cloud_shadow + + 0.26999998092651367 + 0 + 0 + 1 + + density_multiplier + + 0.00062000000616535544 + 0 + 0 + 1 + + distance_multiplier + + 2.6999279499073054 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5.0009990693069994 + 0.0010000000474963411 + -0.48000101923815919 + 1 + + haze_density + + 0.53999996185302734 + 0 + 0 + 1 + + haze_horizon + + 0.15999999642372131 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.094108223915100098 + 0.99556195735931396 + 0 + + max_y + + 563 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 0.094247691333293915 + sunlight_color + + 2.369999885559082 + 2.369999885559082 + 2.369999885559082 + 0.78999996185302734 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/A%2D6PM.xml b/linden/indra/newview/app_settings/windlight/skies/A%2D6PM.xml new file mode 100644 index 0000000..6e82f2e --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/A%2D6PM.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.14840038120746613 + 0.17633917927742004 + 0.23999999463558197 + 0.079999998211860657 + + blue_density + + 0.14522500336170197 + 0.39999699592590332 + 0.80000197887420654 + 1 + + blue_horizon + + 0.10767599940299988 + 0.21348699927330017 + 0.25 + 1 + + cloud_color + + 0.22615399956703186 + 0.22615399956703186 + 0.22615399956703186 + 1 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 0.87999999523162842 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940013885498 + 10.01099967956543 + + cloud_shadow + + 0.26999998092651367 + 0 + 0 + 1 + + density_multiplier + + 0.00046000001020729542 + 0 + 0 + 1 + + distance_multiplier + + 2.7000000476837158 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.47999998927116394 + 1 + + haze_density + + 0.69999998807907104 + 0 + 0 + 1 + + haze_horizon + + 0.15999999642372131 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.07532646507024765 + -0.99715894460678101 + 0 + + max_y + + 562.5 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 3.0661947727203369 + sunlight_color + + 2.8385701179504395 + 2.8385701179504395 + 2.8385701179504395 + 1 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/A%2D9AM.xml b/linden/indra/newview/app_settings/windlight/skies/A%2D9AM.xml new file mode 100644 index 0000000..413e3a2 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/A%2D9AM.xml @@ -0,0 +1,141 @@ + + + ambient + + 1.0499999949065426 + 1.0499999988079054 + 1.0499999988079054 + 0.3500000095367426 + + blue_density + + 0.15999999642372131 + 0.44872328639030457 + 0.75999999046325684 + 0.75999999046325684 + + blue_horizon + + 0.53999996185302734 + 0.47999998927116394 + 0.69999998807907104 + 0.34999999403953552 + + cloud_color + + 0.37000000476837158 + 0.37000000476837158 + 0.37000000476837158 + 0.37000000476837158 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 0.99999998569455784 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.41999997615814166 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.199999844956437 + 10.01099967956543 + + cloud_shadow + + 0.27333331108093262 + 0 + 0 + 1 + + density_multiplier + + 0.00017999998102430359 + 0 + 0 + 1 + + distance_multiplier + + 0.80000008344649842 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 4.9999999284740397 + 0.0010000000474974513 + -0.47999999046327346 + 1 + + haze_density + + 0.70000003576435432 + 0 + 0 + 1 + + haze_horizon + + 0.18999999284767277 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.70710676908493042 + 0.70710676908493042 + 0 + + max_y + + 1605 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 0.78539818525314331 + sunlight_color + + 0.73421054104441197 + 0.7815789463510896 + 0.89999995470046912 + 0.29999997496605069 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/A%2D9PM.xml b/linden/indra/newview/app_settings/windlight/skies/A%2D9PM.xml new file mode 100644 index 0000000..292f671 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/A%2D9PM.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.20404692765200849 + 0.24246276689169122 + 0.33000383615406292 + 0.1100123608103587 + + blue_density + + 0.44999116536295314 + 0.44999854555993368 + 0.45001013284446073 + 1 + + blue_horizon + + 0.23999616268583132 + 0.239999227803052 + 0.24000028550619668 + 1 + + cloud_color + + 0.22615400241566114 + 0.22615400241566114 + 0.22615400241566114 + 1 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 0.88000000953681223 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.499400354105791 + 10.011000104419489 + + cloud_shadow + + 0.26999998092651367 + 0 + 0 + 1 + + density_multiplier + + 0.0003000046529240592 + 0 + 0 + 1 + + distance_multiplier + + 7.8213197608078763e-005 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5.0000000000023022 + 0.0010000000214220922 + -0.47999999165507345 + 1 + + haze_density + + 3.9999044060931555 + 0 + 0 + 1 + + haze_horizon + + 4.6348559691012062e-006 + 0.19915600437461423 + 0.19915600437461423 + 1 + + lightnorm + + 0 + 0.70710688829421997 + 0.70710664987564087 + 1 + + max_y + + 906.19008370909478 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 1.9999420642852783 + sun_angle + 3.9269909858703613 + sunlight_color + + 0.34878980098432066 + 0.35576509414380553 + 0.66003586768772493 + 0.22001197576412324 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Barcelona.xml b/linden/indra/newview/app_settings/windlight/skies/Barcelona.xml new file mode 100644 index 0000000..ea9cab8 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Barcelona.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.22260047495365143 + 0.26450866460800171 + 0.35999998450279236 + 0.11999999731779099 + + blue_density + + 0.14522500336170197 + 0.39999699592590332 + 0.80000197887420654 + 1 + + blue_horizon + + 0.15130999684333801 + 0.30000001192092896 + 0.35131001472473145 + 1 + + cloud_color + + 0.50999999046325684 + 0.50999999046325684 + 0.50999999046325684 + 1 + + cloud_pos_density1 + + 0.5 + 0.5 + 1 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940013885498 + 10.01099967956543 + + cloud_shadow + + 0.30000001192092896 + 0 + 0 + 1 + + density_multiplier + + 0.0003499999875202775 + 0 + 0 + 1 + + distance_multiplier + + 6 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.33000001311302185 + 1 + + haze_density + + 0.69999998807907104 + 0 + 0 + 1 + + haze_horizon + + 0.19915600121021271 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.062790460884571075 + -0.99802672863006592 + 0 + + max_y + + 600 + 0 + 0 + 1 + + preset_num + 21 + star_brightness + 0 + sun_angle + 3.0787608623504639 + sunlight_color + + 1.1699999570846558 + 1.1699999570846558 + 1.1699999570846558 + 0.38999998569488525 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Blizzard.xml b/linden/indra/newview/app_settings/windlight/skies/Blizzard.xml new file mode 100644 index 0000000..d17d279 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Blizzard.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.4823022186756134 + 0.57310229539871216 + 0.77999997138977051 + 0.25999999046325684 + + blue_density + + 0.14522500336170197 + 0.39999699592590332 + 0.80000197887420654 + 1 + + blue_horizon + + 0.15130999684333801 + 0.30000001192092896 + 0.35131001472473145 + 1 + + cloud_color + + 0.12862999737262726 + 0.12862999737262726 + 0.12862999737262726 + 1 + + cloud_pos_density1 + + 0.88419097661972046 + 0.53047597408294678 + 0.4270470142364502 + 1 + + cloud_pos_density2 + + 0.38419300317764282 + 0.5 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10 + 10 + + cloud_shadow + + 0.61711597442626953 + 0 + 0 + 1 + + density_multiplier + + 0.0001250890054507181 + 0 + 0 + 1 + + distance_multiplier + + 11.40000057220459 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 6.4079799652099609 + 0.0012815999798476696 + -0.42292699217796326 + 1 + + haze_density + + 4 + 0 + 0 + 1 + + haze_horizon + + 0.21744099259376526 + 0.21744099259376526 + 0.21744099259376526 + 1 + + lightnorm + + 0 + 0.15643447637557983 + 0.98768836259841919 + 0 + + max_y + + 4000 + 0 + 0 + 1 + + preset_num + 2 + star_brightness + 0 + sun_angle + 0.15707963705062866 + sunlight_color + + 3 + 3 + 3 + 1 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Blue%20Midday.xml b/linden/indra/newview/app_settings/windlight/skies/Blue%20Midday.xml new file mode 100644 index 0000000..570f059 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Blue%20Midday.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.14999999105930328 + 0.14999999105930328 + 0.14999999105930328 + 0.049999997019767761 + + blue_density + + 0.18153078854084015 + 0.49999505281448364 + 1 + 1 + + blue_horizon + + 0.43070217967033386 + 0.85394656658172607 + 1 + 1 + + cloud_color + + 0.53962135314941406 + 0.53962135314941406 + 0.53962135314941406 + 1 + + cloud_pos_density1 + + 0.5 + 0.5 + 0.69569224119186401 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.125 + 1 + + cloud_scale + + 0.10999999195337296 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940013885498 + 10.01099967956543 + + cloud_shadow + + 0.3765256404876709 + 0 + 0 + 1 + + density_multiplier + + 0.0003499999875202775 + 0 + 0 + 1 + + distance_multiplier + + 2.9846153259277344 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 4.2061538696289062 + 0.0010000000474974513 + -0.44246155023574829 + 1 + + haze_density + + 2.8830769062042236 + 0 + 0 + 1 + + haze_horizon + + 0.49740666151046753 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.86074197292327881 + -0.50904154777526855 + 0 + + max_y + + 600 + 0 + 0 + 1 + + preset_num + 10 + star_brightness + 0 + sun_angle + 2.1048672199249268 + sunlight_color + + 0.88526362180709839 + 1.2300000190734863 + 1.2300000190734863 + 0.40999999642372131 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml b/linden/indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml new file mode 100644 index 0000000..4925b29 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.89040267467498779 + 1.0580335855484009 + 1.4399999380111694 + 0.47999998927116394 + + blue_density + + 0.14522500336170197 + 0.39999699592590332 + 0.80000197887420654 + 1 + + blue_horizon + + 0.15130999684333801 + 0.30000001192092896 + 0.35131001472473145 + 1 + + cloud_color + + 0.21396400034427643 + 0.21396400034427643 + 0.21396400034427643 + 1 + + cloud_pos_density1 + + 0.16495099663734436 + 0.09771379828453064 + 1 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.079754598438739777 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 9.644780158996582 + 10.423800468444824 + + cloud_shadow + + 0.30061298608779907 + 0 + 0 + 1 + + density_multiplier + + 0.00015800200344529003 + 0 + 0 + 1 + + distance_multiplier + + 1 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.33000001311302185 + 1 + + haze_density + + 0.69999998807907104 + 0 + 0 + 1 + + haze_horizon + + 0.13210900127887726 + 0.13210900127887726 + 0.13210900127887726 + 1 + + lightnorm + + 0 + 0.031410444527864456 + -0.99950659275054932 + 0 + + max_y + + 600 + 0 + 0 + 1 + + preset_num + 3 + star_brightness + 0 + sun_angle + 3.1101770401000977 + sunlight_color + + 3 + 3 + 3 + 1 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml b/linden/indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml new file mode 100644 index 0000000..f4736cf --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.31535112857818604 + 0.37471914291381836 + 0.50999999046325684 + 0.17000000178813934 + + blue_density + + 0.11645399779081345 + 0.32075101137161255 + 0.64150899648666382 + 1 + + blue_horizon + + 0.054176401346921921 + 0.10741499811410904 + 0.12578600645065308 + 1 + + cloud_color + + 0.21396400034427643 + 0.21396400034427643 + 0.21396400034427643 + 1 + + cloud_pos_density1 + + 0.27044001221656799 + 1 + 1 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.10062900185585022 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 9.644780158996582 + 10.423800468444824 + + cloud_shadow + + 0.32704401016235352 + 0 + 0 + 1 + + density_multiplier + + 0.00015849100600462407 + 0 + 0 + 1 + + distance_multiplier + + 3.4000000953674316 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 6.867919921875 + 0.0013735899701714516 + -0.45328301191329956 + 1 + + haze_density + + 0.6792449951171875 + 0 + 0 + 1 + + haze_horizon + + 0.13210900127887726 + 0.13210900127887726 + 0.13210900127887726 + 1 + + lightnorm + + 0 + 0.031410444527864456 + -0.99950659275054932 + 0 + + max_y + + 1308.1800537109375 + 0 + 0 + 1 + + preset_num + 5 + star_brightness + 0 + sun_angle + 3.1101770401000977 + sunlight_color + + 3 + 3 + 3 + 1 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Default.xml b/linden/indra/newview/app_settings/windlight/skies/Default.xml new file mode 100644 index 0000000..13a2c75 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Default.xml @@ -0,0 +1,141 @@ + + + ambient + + 1.0499999523162842 + 1.0499999523162842 + 1.0499999523162842 + 0.34999999403953552 + + blue_density + + 0.24475815892219543 + 0.44872328639030457 + 0.75999999046325684 + 0.37999999523162842 + + blue_horizon + + 0.49548381567001343 + 0.49548381567001343 + 0.63999998569488525 + 0.31999999284744263 + + cloud_color + + 0.40999999642372131 + 0.40999999642372131 + 0.40999999642372131 + 0.40999999642372131 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 1 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.199999809265137 + 10.01099967956543 + + cloud_shadow + + 0.26999998092651367 + 0 + 0 + 1 + + density_multiplier + + 0.00017999998817685992 + 0 + 0 + 1 + + distance_multiplier + + 0.80000001192092896 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.47999998927116394 + 1 + + haze_density + + 0.69999998807907104 + 0 + 0 + 1 + + haze_horizon + + 0.18999999761581421 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.91269159317016602 + -0.40864911675453186 + 0 + + max_y + + 1605 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 1.9917697906494141 + sunlight_color + + 0.7342105507850647 + 0.78157895803451538 + 0.89999997615814209 + 0.29999998211860657 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml b/linden/indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml new file mode 100644 index 0000000..b2a6111 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.07420019805431366 + 0.088169597089290619 + 0.11999999731779099 + 1 + + blue_density + + 0.14522500336170197 + 0.39999699592590332 + 0.80000197887420654 + 1 + + blue_horizon + + 0.10767599940299988 + 0.21348699927330017 + 0.25 + 1 + + cloud_color + + 0.22615399956703186 + 0.22615399956703186 + 0.22615399956703186 + 1 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 1 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.199999809265137 + 10.01099967956543 + + cloud_shadow + + 0.37999999523162842 + 0 + 0 + 1 + + density_multiplier + + 0.00046000001020729542 + 0 + 0 + 1 + + distance_multiplier + + 2 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.6100000143051147 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.47999998927116394 + 1 + + haze_density + + 0.69999998807907104 + 0 + 0 + 1 + + haze_horizon + + 0.15999999642372131 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.062790460884571075 + -0.99802672863006592 + 0 + + max_y + + 562.5 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 3.0787608623504639 + sunlight_color + + 2.8385701179504395 + 2.8385701179504395 + 2.8385701179504395 + 1 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Fine%20Day.xml b/linden/indra/newview/app_settings/windlight/skies/Fine%20Day.xml new file mode 100644 index 0000000..e053815 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Fine%20Day.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.21194984018802643 + 0.25700280070304871 + 0.25999999046325684 + 0.25999999046325684 + + blue_density + + 0.10031381994485855 + 0.2849995493888855 + 0.56999999284744263 + 0.56999999284744263 + + blue_horizon + + 0.15806557238101959 + 0.31211116909980774 + 0.52999997138977051 + 0.52999997138977051 + + cloud_color + + 0.62000000476837158 + 0.72737622261047363 + 0.73626559972763062 + 1 + + cloud_pos_density1 + + 0.89999997615814209 + 0.93999999761581421 + 0.74000000953674316 + 1 + + cloud_pos_density2 + + 0.11999999731779099 + 0.20999999344348907 + 0.029999999329447746 + 1 + + cloud_scale + + 0.25999999046325684 + 0 + 0 + 1 + + cloud_scroll_rate + + 9.993240904292179 + 10.010000228881836 + + cloud_shadow + + 0.29999998211860657 + 0 + 0 + 1 + + density_multiplier + + 0.00013000000035390258 + 0 + 0 + 1 + + distance_multiplier + + 10.100000381469727 + 0 + 0 + 1 + + east_angle + 3.8955750465393066 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.4699999094009399 + 0 + 0 + 1 + + glow + + 11.200000762939453 + 0.0010000000474974513 + -0.64999997615814209 + 1 + + haze_density + + 0.35999998450279236 + 0 + 0 + 1 + + haze_horizon + + 0.11999999731779099 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.66304093599319458 + 0.24868990480899811 + -0.70606660842895508 + 0 + + max_y + + 789 + 0 + 0 + 1 + + preset_num + 24 + star_brightness + 0.18999999761581421 + sun_angle + 0.25132742524147034 + sunlight_color + + 2.25 + 1.2599999904632568 + 0.59999996423721313 + 2.25 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml b/linden/indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml new file mode 100644 index 0000000..8576ec1 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.029999999329447746 + 0 + 0 + 0.029999999329447746 + + blue_density + + 0.097999997437000275 + 0.2800000011920929 + 1 + 1 + + blue_horizon + + 0.11999999731779099 + 0.35094299912452698 + 1 + 1 + + cloud_color + + 0.48999997973442078 + 0.79000002145767212 + 0.80000001192092896 + 1 + + cloud_pos_density1 + + 0.53999996185302734 + 0.5 + 0.75999999046325684 + 1 + + cloud_pos_density2 + + 0.38999998569488525 + 0.5 + 0.039999999105930328 + 1 + + cloud_scale + + 0.43999999761581421 + 0 + 0 + 1 + + cloud_scroll_rate + + 11.809999465942383 + 12.799999237060547 + + cloud_shadow + + 0.32999998331069946 + 0 + 0 + 1 + + density_multiplier + + 0.00021999998716637492 + 0 + 0 + 1 + + distance_multiplier + + 4 + 0 + 0 + 1 + + east_angle + 3.2044246196746826 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.5399999618530273 + 0 + 0 + 1 + + glow + + 3.8000010331979865 + 0.001000000059761974 + -0.49999996688498527 + 1 + + haze_density + + 0.20999999344348907 + 0 + 0 + 1 + + haze_horizon + + 0.049999997019767761 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.056814663112163544 + 0.42577928304672241 + -0.90304160118103027 + 0 + + max_y + + 676.10003662109375 + 0 + 0 + 1 + + preset_num + 18 + star_brightness + 0.44999998807907104 + sun_angle + 0.4398229718208313 + sunlight_color + + 1.7999999523162842 + 1.4099999666213989 + 1.0199999809265137 + 1.7999999523162842 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Foggy.xml b/linden/indra/newview/app_settings/windlight/skies/Foggy.xml new file mode 100644 index 0000000..cb7395d --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Foggy.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.32999998331069946 + 0.32999998331069946 + 0.32999998331069946 + 0.10999999940395355 + + blue_density + + 0.14522500336170197 + 0.39999699592590332 + 0.80000197887420654 + 1 + + blue_horizon + + 0.43070214986801147 + 0.85394668579101563 + 1 + 1 + + cloud_color + + 0.69999998807907104 + 0.69999998807907104 + 0.69999998807907104 + 0.69999998807907104 + + cloud_pos_density1 + + 0.5 + 0.5 + 0.53999996185302734 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.125 + 1 + + cloud_scale + + 0.29999998211860657 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940013885498 + 10.01099967956543 + + cloud_shadow + + 0.39999997615814209 + 0 + 0 + 1 + + density_multiplier + + 0.0003499999875202775 + 0 + 0 + 1 + + distance_multiplier + + 4 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 3.7999999523162842 + 0.0010000000474974513 + -0.5 + 1 + + haze_density + + 4 + 0 + 0 + 1 + + haze_horizon + + 0.64999997615814209 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 1 + -4.3711388286737929e-008 + 0 + + max_y + + 600 + 0 + 0 + 1 + + preset_num + 18 + star_brightness + 0 + sun_angle + 1.5707963705062866 + sunlight_color + + 0.53999996185302734 + 0.53999996185302734 + 0.53999996185302734 + 0.17999999225139618 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml b/linden/indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml new file mode 100644 index 0000000..32be0d2 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.29999998211860657 + 0.23511900007724762 + 0.31999999284744263 + 1 + + blue_density + + 0.13977900147438049 + 0.38499599695205688 + 0.76999998092651367 + 1 + + blue_horizon + + 0.18999999761581421 + 0.18999999761581421 + 0.18999999761581421 + 1 + + cloud_color + + 0.22615399956703186 + 0.22615399956703186 + 0.22615399956703186 + 1 + + cloud_pos_density1 + + 5.3780298233032227 + 1.9675600528717041 + 1 + 1 + + cloud_pos_density2 + + 5.3780298233032227 + 1.9675600528717041 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.739999771118164 + 10.600000381469727 + + cloud_shadow + + 0.31000000238418579 + 0 + 0 + 1 + + density_multiplier + + 0.00052000000141561031 + 0 + 0 + 1 + + distance_multiplier + + 3.4000000953674316 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 0.77999997138977051 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.47999998927116394 + 1 + + haze_density + + 1.1000000238418579 + 0 + 0 + 1 + + haze_horizon + + 0.12999999523162842 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.53582650423049927 + -0.84432810544967651 + 0 + + max_y + + 656.20001220703125 + 0 + 0 + 1 + + preset_num + 28 + star_brightness + 0 + sun_angle + 2.5761063098907471 + sunlight_color + + 2.1299998760223389 + 1.5299999713897705 + 2.8385701179504395 + 1 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Funky%20Funky.xml b/linden/indra/newview/app_settings/windlight/skies/Funky%20Funky.xml new file mode 100644 index 0000000..ae16b2d --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Funky%20Funky.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.32999998331069946 + 0.32999998331069946 + 0.32999998331069946 + 0.10999999940395355 + + blue_density + + 0.14522500336170197 + 0.39999699592590332 + 0.80000197887420654 + 1 + + blue_horizon + + 0.15130999684333801 + 0.30000001192092896 + 0.35131001472473145 + 1 + + cloud_color + + 0.22615399956703186 + 0.22615399956703186 + 0.22615399956703186 + 1 + + cloud_pos_density1 + + 0.65280699729919434 + 0.50335597991943359 + 1 + 1 + + cloud_pos_density2 + + 0.65280699729919434 + 0.50335597991943359 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940013885498 + 10.01099967956543 + + cloud_shadow + + 0.33064401149749756 + 0 + 0 + 1 + + density_multiplier + + 0.0003499999875202775 + 0 + 0 + 1 + + distance_multiplier + + 1 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.33000001311302185 + 1 + + haze_density + + 0.69999998807907104 + 0 + 0 + 1 + + haze_horizon + + 0.19915600121021271 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.062790460884571075 + -0.99802672863006592 + 0 + + max_y + + 600 + 0 + 0 + 1 + + preset_num + 11 + star_brightness + 0 + sun_angle + 3.0787608623504639 + sunlight_color + + 0.86811381578445435 + 2.2200000286102295 + 2.2200000286102295 + 0.74000000953674316 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Gelatto.xml b/linden/indra/newview/app_settings/windlight/skies/Gelatto.xml new file mode 100644 index 0000000..66b3d31 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Gelatto.xml @@ -0,0 +1,141 @@ + + + ambient + + 0 + 0.15999999642372131 + 0 + 0.15999999642372131 + + blue_density + + 0.019999999552965164 + 0.22999770939350128 + 0.45999997854232788 + 0.55000001192092896 + + blue_horizon + + 0 + 0.6319204568862915 + 0.74000000953674316 + 0.84999996423721313 + + cloud_color + + 1 + 0 + 0 + 1 + + cloud_pos_density1 + + 0.53999996185302734 + 0.50999999046325684 + 0.23999999463558197 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.059999998658895493 + 1 + + cloud_scale + + 0.2800000011920929 + 0 + 0 + 1 + + cloud_scroll_rate + + 20 + 20 + + cloud_shadow + + 0.32999998331069946 + 0 + 0 + 1 + + density_multiplier + + 0.00016999999934341758 + 0 + 0 + 1 + + distance_multiplier + + 8.1000003814697266 + 0 + 0 + 1 + + east_angle + 3.7699110507965088 + enable_cloud_scroll + + 0 + 0 + + gamma + + 1.5399999618530273 + 0 + 0 + 1 + + glow + + 0.39999961853027344 + 0.0010000000474974513 + -0.49999997019767761 + 1 + + haze_density + + 3.2599999904632568 + 0 + 0 + 1 + + haze_horizon + + 0.4699999988079071 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.58749508857727051 + -0.031410761177539825 + -0.80861783027648926 + 0 + + max_y + + 1267.5999755859375 + 0 + 0 + 1 + + preset_num + 18 + star_brightness + 0 + sun_angle + -0.031415928155183792 + sunlight_color + + 0.75 + 0.71999996900558472 + 0.37800011038780212 + 0.80999994277954102 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Ghost.xml b/linden/indra/newview/app_settings/windlight/skies/Ghost.xml new file mode 100644 index 0000000..447202e --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Ghost.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.23999999463558197 + 0.23999999463558197 + 0.23999999463558197 + 0.079999998211860657 + + blue_density + + 0.16700799763202667 + 0.45999500155448914 + 0.92000001668930054 + 1 + + blue_horizon + + 0.18089599907398224 + 0.35865798592567444 + 0.41999998688697815 + 1 + + cloud_color + + 0.40999999642372131 + 0.40999999642372131 + 0.40999999642372131 + 1 + + cloud_pos_density1 + + 0.5 + 0.5 + 1 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 11.539999961853027 + 10.01099967956543 + + cloud_shadow + + 0.36000001430511475 + 0 + 0 + 1 + + density_multiplier + + 0.00042999998549930751 + 0 + 0 + 1 + + distance_multiplier + + 8.1000003814697266 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.51999998092651367 + 1 + + haze_density + + 0.75 + 0 + 0 + 1 + + haze_horizon + + 0.18000000715255737 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.89100658893585205 + 0.45399042963981628 + 0 + + max_y + + 718.70001220703125 + 0 + 0 + 1 + + preset_num + 23 + star_brightness + 2 + sun_angle + 1.0995575189590454 + sunlight_color + + 0.33000001311302185 + 0.33000001311302185 + 0.33000001311302185 + 1 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml b/linden/indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml new file mode 100644 index 0000000..098844e --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml @@ -0,0 +1,141 @@ + + + ambient + + 0 + 0 + 0.44999998807907104 + 0.44999998807907104 + + blue_density + + 0.13997539444089213 + 0.38665792478461469 + 0.77332294252195766 + 0.95108884837904384 + + blue_horizon + + 0 + 0.22876684367656708 + 0.290018230676651 + 0.31999999284744263 + + cloud_color + + 0.25999999046325684 + 0.28883209824562073 + 0.28994369506835938 + 0.28999999165534973 + + cloud_pos_density1 + + 0.17999999225139618 + 0.50999999046325684 + 0.91999995708465576 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.079999998211860657 + 1 + + cloud_scale + + 0.25 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.436104517528292 + 10 + + cloud_shadow + + 0.34000000357627869 + 0 + 0 + 1 + + density_multiplier + + 0.0002899999963119626 + 0 + 0 + 1 + + distance_multiplier + + 1.3000000715255737 + 0 + 0 + 1 + + east_angle + 2.2619466781616211 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.5399999618530273 + 0 + 0 + 1 + + glow + + 4.0000009536743164 + 0.0010000000474974513 + -0.74999994039535522 + 1 + + haze_density + + 0.12999999523162842 + 0 + 0 + 1 + + haze_horizon + + 0.14999999105930328 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + -0.74630612134933472 + 0.24868990480899811 + -0.61739814281463623 + 0 + + max_y + + 394.39999389648437 + 0 + 0 + 1 + + preset_num + 18 + star_brightness + 0.44999998807907104 + sun_angle + 0.25132742524147034 + sunlight_color + + 2.25 + 1.957500696182251 + 1.170000433921814 + 0.75 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Midday%201.xml b/linden/indra/newview/app_settings/windlight/skies/Midday%201.xml new file mode 100644 index 0000000..13a2c75 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Midday%201.xml @@ -0,0 +1,141 @@ + + + ambient + + 1.0499999523162842 + 1.0499999523162842 + 1.0499999523162842 + 0.34999999403953552 + + blue_density + + 0.24475815892219543 + 0.44872328639030457 + 0.75999999046325684 + 0.37999999523162842 + + blue_horizon + + 0.49548381567001343 + 0.49548381567001343 + 0.63999998569488525 + 0.31999999284744263 + + cloud_color + + 0.40999999642372131 + 0.40999999642372131 + 0.40999999642372131 + 0.40999999642372131 + + cloud_pos_density1 + + 1.6884100437164307 + 0.52609699964523315 + 1 + 1 + + cloud_pos_density2 + + 1.6884100437164307 + 0.52609699964523315 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.199999809265137 + 10.01099967956543 + + cloud_shadow + + 0.26999998092651367 + 0 + 0 + 1 + + density_multiplier + + 0.00017999998817685992 + 0 + 0 + 1 + + distance_multiplier + + 0.80000001192092896 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.47999998927116394 + 1 + + haze_density + + 0.69999998807907104 + 0 + 0 + 1 + + haze_horizon + + 0.18999999761581421 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.91269159317016602 + -0.40864911675453186 + 0 + + max_y + + 1605 + 0 + 0 + 1 + + preset_num + 22 + star_brightness + 0 + sun_angle + 1.9917697906494141 + sunlight_color + + 0.7342105507850647 + 0.78157895803451538 + 0.89999997615814209 + 0.29999998211860657 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Midday%202.xml b/linden/indra/newview/app_settings/windlight/skies/Midday%202.xml new file mode 100644 index 0000000..04f2ba8 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Midday%202.xml @@ -0,0 +1,141 @@ + + + ambient + + 0 + 0 + 0 + 0 + + blue_density + + 0.14522500336170197 + 0.39999699592590332 + 0.80000197887420654 + 1 + + blue_horizon + + 0.43070214986801147 + 0.85394668579101563 + 1 + 1 + + cloud_color + + 0.69999998807907104 + 0.69999998807907104 + 0.69999998807907104 + 1 + + cloud_pos_density1 + + 0.5 + 0.5 + 0.53999996185302734 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.125 + 1 + + cloud_scale + + 0.29999998211860657 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.199999809265137 + 10.069999694824219 + + cloud_shadow + + 0.22999998927116394 + 0 + 0 + 1 + + density_multiplier + + 0.0003499999875202775 + 0 + 0 + 1 + + distance_multiplier + + 0 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.6100000143051147 + 0 + 0 + 1 + + glow + + 3.7999999523162842 + 0.0010000000474974513 + -0.5 + 1 + + haze_density + + 0.69999998807907104 + 0 + 0 + 1 + + haze_horizon + + 0.41999998688697815 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 1 + -4.3711388286737929e-008 + 0 + + max_y + + 600 + 0 + 0 + 1 + + preset_num + -1163005939 + star_brightness + 0 + sun_angle + 1.5707963705062866 + sunlight_color + + 0.80999994277954102 + 0.80999994277954102 + 0.80999994277954102 + 0.26999998092651367 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Midday%203.xml b/linden/indra/newview/app_settings/windlight/skies/Midday%203.xml new file mode 100644 index 0000000..a23dcab --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Midday%203.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.33000001311302185 + 0.33000001311302185 + 0.33000001311302185 + 1 + + blue_density + + 0.16449999809265137 + 0.4699999988079071 + 0.93999999761581421 + 1 + + blue_horizon + + 0.17547200620174408 + 0.35094299912452698 + 0.62000000476837158 + 1 + + cloud_color + + 0.5899999737739563 + 0.79000002145767212 + 0.80000001192092896 + 1 + + cloud_pos_density1 + + 2.8148899078369141 + 5.6909198760986328 + 1 + 1 + + cloud_pos_density2 + + 5.9584097862243652 + 6.9909601211547852 + 0.070000000298023224 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 9.9300003051757813 + 10.199999809265137 + + cloud_shadow + + 0.25999999046325684 + 0 + 0 + 1 + + density_multiplier + + 0.00039000000106170774 + 0 + 0 + 1 + + distance_multiplier + + 0.69999998807907104 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.6100000143051147 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -1.1599999666213989 + 1 + + haze_density + + 0.20999999344348907 + 0 + 0 + 1 + + haze_horizon + + 0.11999999731779099 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 1 + -4.3711388286737929e-008 + 0 + + max_y + + 2250 + 0 + 0 + 1 + + preset_num + 24 + star_brightness + 0 + sun_angle + 1.5707963705062866 + sunlight_color + + 1.2599999904632568 + 1.2599999904632568 + 1.2599999904632568 + 1 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Midday%204.xml b/linden/indra/newview/app_settings/windlight/skies/Midday%204.xml new file mode 100644 index 0000000..255e314 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Midday%204.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.33000001311302185 + 0.33000001311302185 + 0.33000001311302185 + 1 + + blue_density + + 0.097999997437000275 + 0.2800000011920929 + 0.56000000238418579 + 0.56000000238418579 + + blue_horizon + + 0.17547200620174408 + 0.35094299912452698 + 0.61000001430511475 + 0.61000001430511475 + + cloud_color + + 0.5899999737739563 + 0.79000002145767212 + 0.80000001192092896 + 1 + + cloud_pos_density1 + + 2.8148899078369141 + 5.6909198760986328 + 1 + 1 + + cloud_pos_density2 + + 5.9584097862243652 + 6.9909601211547852 + 0.070000000298023224 + 1 + + cloud_scale + + 0.32999998331069946 + 0 + 0 + 1 + + cloud_scroll_rate + + 9.9300003051757813 + 10.199999809265137 + + cloud_shadow + + 0.22999998927116394 + 0 + 0 + 1 + + density_multiplier + + 0.00039000000106170774 + 0 + 0 + 1 + + distance_multiplier + + 0.69999998807907104 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.6100000143051147 + 0 + 0 + 1 + + glow + + 3.8000011444091797 + 0.0010000000474974513 + -0.49999997019767761 + 1 + + haze_density + + 0.20999999344348907 + 0 + 0 + 1 + + haze_horizon + + 0.19999998807907104 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 1 + -4.3711388286737929e-008 + 0 + + max_y + + 1802.800048828125 + 0 + 0 + 1 + + preset_num + 24 + star_brightness + 0 + sun_angle + 1.5707963705062866 + sunlight_color + + 1.2599999904632568 + 1.2599999904632568 + 1.2599999904632568 + 0.41999998688697815 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Night.xml b/linden/indra/newview/app_settings/windlight/skies/Night.xml new file mode 100644 index 0000000..c493894 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Night.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.20405027105862608 + 0.24246673976617727 + 0.32999997392212316 + 0.11000000166951449 + + blue_density + + 0.44999999369830818 + 0.44999999398335949 + 0.4499999944309046 + 1 + + blue_horizon + + 0.23999999567946317 + 0.23999999579784967 + 0.23999999583870221 + 1 + + cloud_color + + 0.22615400241575034 + 0.22615400241575034 + 0.22615400241575034 + 1 + + cloud_pos_density1 + + 0.5 + 0.5 + 0.88000000953711155 + 1 + + cloud_pos_density2 + + 0.5 + 0.5 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940035411295 + 10.011000104431371 + + cloud_shadow + + 0.36000001430511475 + 0 + 0 + 1 + + density_multiplier + + 0.00030000001824737163 + 0 + 0 + 1 + + distance_multiplier + + 3.0208916693946743e-009 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000214212465 + -0.47999999165502744 + 1 + + haze_density + + 3.9999999963077992 + 0 + 0 + 1 + + haze_horizon + + 1.7901579546794781e-010 + 0.19915600437467304 + 0.19915600437467304 + 1 + + lightnorm + + 0 + 1 + 3.0028815672267228e-005 + 1 + + max_y + + 906.20003957594895 + 0 + 0 + 1 + + preset_num + 26 + star_brightness + 2 + sun_angle + 4.7123589515686035 + sunlight_color + + 0.34876692389196384 + 0.3557424864638451 + 0.65999994893325931 + 0.22000000284673543 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Pirate.xml b/linden/indra/newview/app_settings/windlight/skies/Pirate.xml new file mode 100644 index 0000000..dcb9c27 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Pirate.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.27825063467025757 + 0.33063584566116333 + 0.44999998807907104 + 0.14999999105930328 + + blue_density + + 0.14522500336170197 + 0.39999699592590332 + 0.80000197887420654 + 1 + + blue_horizon + + 0.15130999684333801 + 0.30000001192092896 + 0.35131001472473145 + 1 + + cloud_color + + 0.22615399956703186 + 0.22615399956703186 + 0.22615399956703186 + 1 + + cloud_pos_density1 + + 1.2046600580215454 + 0.51547497510910034 + 1 + 1 + + cloud_pos_density2 + + 1.2046600580215454 + 0.51547497510910034 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.49940013885498 + 10.01099967956543 + + cloud_shadow + + 0.33064401149749756 + 0 + 0 + 1 + + density_multiplier + + 0.0003499999875202775 + 0 + 0 + 1 + + distance_multiplier + + 3.4000000953674316 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.36000001430511475 + 1 + + haze_density + + 0.69999998807907104 + 0 + 0 + 1 + + haze_horizon + + 0.19915600121021271 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.062790460884571075 + -0.99802672863006592 + 0 + + max_y + + 600 + 0 + 0 + 1 + + preset_num + 27 + star_brightness + 0 + sun_angle + 3.0787608623504639 + sunlight_color + + 2.8385701179504395 + 2.8385701179504395 + 2.8385701179504395 + 1 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Purple.xml b/linden/indra/newview/app_settings/windlight/skies/Purple.xml new file mode 100644 index 0000000..0e9ac3f --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Purple.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.1978670060634613 + 0.23511900007724762 + 0.31999999284744263 + 1 + + blue_density + + 0.13977900147438049 + 0.38499599695205688 + 0.76999998092651367 + 1 + + blue_horizon + + 0.18999999761581421 + 0.18999999761581421 + 0.18999999761581421 + 1 + + cloud_color + + 0.22615399956703186 + 0.22615399956703186 + 0.22615399956703186 + 1 + + cloud_pos_density1 + + 5.3780298233032227 + 1.9675600528717041 + 1 + 1 + + cloud_pos_density2 + + 5.3780298233032227 + 1.9675600528717041 + 0.125 + 1 + + cloud_scale + + 0.41999998688697815 + 0 + 0 + 1 + + cloud_scroll_rate + + 10.739999771118164 + 10.600000381469727 + + cloud_shadow + + 0.31000000238418579 + 0 + 0 + 1 + + density_multiplier + + 0.00052000000141561031 + 0 + 0 + 1 + + distance_multiplier + + 3.4000000953674316 + 0 + 0 + 1 + + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1 + 0 + 0 + 1 + + glow + + 5 + 0.0010000000474974513 + -0.47999998927116394 + 1 + + haze_density + + 1.1000000238418579 + 0 + 0 + 1 + + haze_horizon + + 0.12999999523162842 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0 + 0.094108030200004578 + -0.99556201696395874 + 0 + + max_y + + 656.20001220703125 + 0 + 0 + 1 + + preset_num + 28 + star_brightness + 0 + sun_angle + 3.0473451614379883 + sunlight_color + + 1.5 + 1.5299999713897705 + 2.8385701179504395 + 1 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml b/linden/indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml new file mode 100644 index 0000000..70df6b0 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml @@ -0,0 +1,141 @@ + + + ambient + + 0.8399999737739563 + 0.090738050639629364 + 0.1234893873333931 + 0.8399999737739563 + + blue_density + + 0.93999999761581421 + 0.69999998807907104 + 0.25 + 0.93999999761581421 + + blue_horizon + + 1 + 0.59999996423721313 + 0.25001853704452515 + 1 + + cloud_color + + 0.65999996662139893 + 0.38999998569488525 + 0.22618354856967926 + 0.65999996662139893 + + cloud_pos_density1 + + 0.76999998092651367 + 0.50999999046325684 + 1 + 1 + + cloud_pos_density2 + + 0.5 + 0.5899999737739563 + 0.019999999552965164 + 1 + + cloud_scale + + 0.26999998092651367 + 0 + 0 + 1 + + cloud_scroll_rate + + 9.4499998092651367 + 9.4399995803833008 + + cloud_shadow + + 0.5 + 0 + 0 + 1 + + density_multiplier + + 0.00019999999494757503 + 0 + 0 + 1 + + distance_multiplier + + 6.7000002861022949 + 0 + 0 + 1 + + east_angle + 3.7070791721343994 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.4800000190734863 + 0 + 0 + 1 + + glow + + 0.79999923706054688 + 0.0010000000474974513 + -0.94999998807907104 + 1 + + haze_density + + 0.89999997615814209 + 0 + 0 + 1 + + haze_horizon + + 0.29999998211860657 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + 0.53160154819488525 + 0.12533323466777802 + -0.83767020702362061 + 0 + + max_y + + 281.70001220703125 + 0 + 0 + 1 + + preset_num + 18 + star_brightness + 1.3799999952316284 + sun_angle + 0.12566371262073517 + sunlight_color + + 0.75 + 1.6800000667572021 + 1.0777359008789062 + 0.56000000238418579 + + + diff --git a/linden/indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml b/linden/indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml new file mode 100644 index 0000000..4c44a1b --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml @@ -0,0 +1,141 @@ + + + ambient + + 0 + 0.059999998658895493 + 0 + 0.059999998658895493 + + blue_density + + 0 + 0.099999994039535522 + 0.32999998331069946 + 0.32999998331069946 + + blue_horizon + + 0.029999999329447746 + 0 + 1 + 1 + + cloud_color + + 0.81999999284744263 + 0.18999999761581421 + 0.039999999105930328 + 0.81999999284744263 + + cloud_pos_density1 + + 0.74000000953674316 + 0.93999999761581421 + 0.20999999344348907 + 1 + + cloud_pos_density2 + + 0.65999996662139893 + 0.52999997138977051 + 0.0099999997764825821 + 1 + + cloud_scale + + 0.14000000059604645 + 0 + 0 + 1 + + cloud_scroll_rate + + 18 + 20 + + cloud_shadow + + 0.37999999523162842 + 0 + 0 + 1 + + density_multiplier + + 0.00018000000272877514 + 0 + 0 + 1 + + distance_multiplier + + 6.7000002861022949 + 0 + 0 + 1 + + east_angle + 2.3247785568237305 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.9499999284744263 + 0 + 0 + 1 + + glow + + 17.399999618530273 + 0.0010000000474974513 + -0.64999997615814209 + 1 + + haze_density + + 0.40999999642372131 + 0 + 0 + 1 + + haze_horizon + + 0.17000000178813934 + 0.19915600121021271 + 0.19915600121021271 + 1 + + lightnorm + + -0.72322052717208862 + 0.12533323466777802 + -0.67914927005767822 + 0 + + max_y + + 263 + 0 + 0 + 1 + + preset_num + 24 + star_brightness + 1.0399999618530273 + sun_angle + 0.12566371262073517 + sunlight_color + + 1.5899999141693115 + 1.5299999713897705 + 0.53999996185302734 + 1.5899999141693115 + + + diff --git a/linden/indra/newview/app_settings/windlight/water/Default.xml b/linden/indra/newview/app_settings/windlight/water/Default.xml new file mode 100644 index 0000000..dce4148 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/water/Default.xml @@ -0,0 +1,43 @@ + + + blurMultiplier + 0.040000002831220627 + fresnelOffset + 0.5 + fresnelScale + 0.39999997615814209 + normScale + + 2 + 2 + 2 + + normalMap + 822ded49-9a6c-f61c-cb89-6df54f42cdf4 + scaleAbove + 0.029999999329447746 + scaleBelow + 0.20000000298023224 + underWaterFogMod + 0.25 + waterFogColor + + 0.015686275437474251 + 0.14901961386203766 + 0.25098040699958801 + 1 + + waterFogDensity + 16 + wave1Dir + + 1.0499997138977051 + -0.42000007629394531 + + wave2Dir + + 1.1099996566772461 + -1.1600000858306885 + + + diff --git a/linden/indra/newview/app_settings/windlight/water/Glassy.xml b/linden/indra/newview/app_settings/windlight/water/Glassy.xml new file mode 100644 index 0000000..01183e4 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/water/Glassy.xml @@ -0,0 +1,43 @@ + + + blurMultiplier + 0.003000000026077032089233398 + fresnelOffset + 0.579999983310699462890625 + fresnelScale + 0.0999999940395355224609375 + normScale + + 2 + 2 + 2 + + normalMap + 822ded49-9a6c-f61c-cb89-6df54f42cdf4 + scaleAbove + 0.07999999821186065673828125 + scaleBelow + 0.2000000029802322387695312 + underWaterFogMod + 0.25 + waterFogColor + + 0.04999999701976776123046875 + 0.37999999523162841796875 + 0.5299999713897705078125 + 0.5299999713897705078125 + + waterFogDensity + 1 + wave1Dir + + 0.5 + -0.1700000017881393432617188 + + wave2Dir + + 0.579999983310699462890625 + -0.670000016689300537109375 + + + diff --git a/linden/indra/newview/app_settings/windlight/water/Murky.xml b/linden/indra/newview/app_settings/windlight/water/Murky.xml new file mode 100644 index 0000000..1d9e022 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/water/Murky.xml @@ -0,0 +1,43 @@ + + + blurMultiplier + 0.0030000000260770321 + fresnelOffset + 0.39999997615814209 + fresnelScale + 0.5 + normScale + + 2 + 2 + 2 + + normalMap + 822ded49-9a6c-f61c-cb89-6df54f42cdf4 + scaleAbove + 0.079999998211860657 + scaleBelow + 0.20000000298023224 + underWaterFogMod + 0.76999998092651367 + waterFogColor + + 0.08999999612569809 + 0.17000000178813934 + 0.20999999344348907 + 0.20999999344348907 + + waterFogDensity + 16 + wave1Dir + + 0.5 + -0.17000000178813934 + + wave2Dir + + 0.57999998331069946 + -0.67000001668930054 + + + diff --git a/linden/indra/newview/app_settings/windlight/water/Pond.xml b/linden/indra/newview/app_settings/windlight/water/Pond.xml new file mode 100644 index 0000000..59e3c44 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/water/Pond.xml @@ -0,0 +1,43 @@ + + + blurMultiplier + 0.0030000000260770321 + fresnelOffset + 0.50999999046325684 + fresnelScale + 0.099999994039535522 + normScale + + 2 + 2 + 2 + + normalMap + 822ded49-9a6c-f61c-cb89-6df54f42cdf4 + scaleAbove + 0.079999998211860657 + scaleBelow + 0.20000000298023224 + underWaterFogMod + 0.25 + waterFogColor + + 0.059999998658895493 + 0.37999999523162842 + 0.52999997138977051 + 0.52999997138977051 + + waterFogDensity + 2.1000001430511475 + wave1Dir + + 0.5 + -0.17000000178813934 + + wave2Dir + + 0.57999998331069946 + -0.67000001668930054 + + + diff --git a/linden/indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml b/linden/indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml new file mode 100644 index 0000000..6dbc4e8 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml @@ -0,0 +1,43 @@ + + + blurMultiplier + 0.0030000000260770321 + fresnelOffset + 0.57999998331069946 + fresnelScale + 0.099999994039535522 + normScale + + 10 + 10 + 10 + + normalMap + 470626e3-ac38-8554-d49b-90311c0176a9 + scaleAbove + 0.91999995708465576 + scaleBelow + 0.93999999761581421 + underWaterFogMod + 0.25 + waterFogColor + + 0.049999997019767761 + 0.37999999523162842 + 0.52999997138977051 + 0.52999997138977051 + + waterFogDensity + 3.2000000476837158 + wave1Dir + + 0.5 + -0.17000000178813934 + + wave2Dir + + 0.57999998331069946 + -0.67000001668930054 + + + diff --git a/linden/indra/newview/app_settings/windlight/water/Second%20Plague.xml b/linden/indra/newview/app_settings/windlight/water/Second%20Plague.xml new file mode 100644 index 0000000..137483a --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/water/Second%20Plague.xml @@ -0,0 +1,43 @@ + + + blurMultiplier + 0.017000000923871994 + fresnelOffset + 0.37000000476837158 + fresnelScale + 0 + normScale + + 2 + 2 + 2 + + normalMap + 822ded49-9a6c-f61c-cb89-6df54f42cdf4 + scaleAbove + 0.079999998211860657 + scaleBelow + 0.20000000298023224 + underWaterFogMod + 0.85999995470046997 + waterFogColor + + 0.48999997973442078 + 0 + 0 + 0.48999997973442078 + + waterFogDensity + 20 + wave1Dir + + 0.5 + -0.17000000178813934 + + wave2Dir + + 0.57999998331069946 + -0.67000001668930054 + + + diff --git a/linden/indra/newview/app_settings/windlight/water/Valdez.xml b/linden/indra/newview/app_settings/windlight/water/Valdez.xml new file mode 100644 index 0000000..eb70a14 --- /dev/null +++ b/linden/indra/newview/app_settings/windlight/water/Valdez.xml @@ -0,0 +1,43 @@ + + + blurMultiplier + 0.0020000000949949026 + fresnelOffset + 0.28999999165534973 + fresnelScale + 0 + normScale + + 2 + 2 + 2 + + normalMap + 822ded49-9a6c-f61c-cb89-6df54f42cdf4 + scaleAbove + 0.079999998211860657 + scaleBelow + 0.20000000298023224 + underWaterFogMod + 1 + waterFogColor + + 0 + 0 + 0 + 0 + + waterFogDensity + 1024 + wave1Dir + + 0.5 + -0.17000000178813934 + + wave2Dir + + 0.57999998331069946 + -0.67000001668930054 + + + diff --git a/linden/indra/newview/featuretable.txt b/linden/indra/newview/featuretable.txt index f98b42b..898751d 100644 --- a/linden/indra/newview/featuretable.txt +++ b/linden/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 10 +version 15 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -12,7 +12,7 @@ version 10 // // is the name of a feature // is 0 or 1, whether the feature is available -// is an S32 which is the recommended value +// is an F32 which is the recommended value // // For now, the first list read sets up all of the default values // @@ -23,102 +23,199 @@ version 10 // NOTE: All settings are set to the MIN of applied values, including 'all'! // list all -RenderVBO 1 1 -RenderAniso 1 0 -RenderAvatarMode 1 2 -RenderAvatarVP 1 1 -RenderDistance 1 128 -RenderLighting 1 1 -RenderObjectBump 1 1 -RenderParticleCount 1 4096 -RenderRippleWater 1 1 -RenderTerrainDetail 1 2 -VertexShaderEnable 1 1 -UseOcclusion 1 1 -RenderCubeMap 1 1 - -// -// Class 0 Hardware (Unknown or just old) +RenderAnisotropic 1 0 +RenderAvatarCloth 1 1 +RenderAvatarLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderCubeMap 1 1 +RenderFarClip 1 256 +RenderFlexTimeFactor 1 1.0 +RenderFogRatio 1 4.0 +RenderGamma 1 0 +RenderGlowResolutionPow 1 9 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 8192 +RenderNightBrightness 1 1.0 +RenderObjectBump 1 1 +RenderReflectionDetail 1 3 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTreeLODFactor 1 1.0 +RenderUseImpostors 1 1 +RenderVBOEnable 1 1 +RenderVolumeLODFactor 1 2.0 +RenderWaterReflections 1 1 +UseOcclusion 1 1 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +WLSkyDetail 1 128 +Disregard128DefaultDrawDistance 1 1 +Disregard96DefaultDrawDistance 1 1 + +// +// Low Graphics Settings +// +list Low +RenderAnisotropic 1 0 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 0.5 +RenderAvatarVP 1 0 +RenderFarClip 1 64 +RenderFlexTimeFactor 1 0.5 +RenderGlowResolutionPow 1 8 +RenderLightingDetail 1 0 +RenderMaxPartCount 1 1024 +RenderObjectBump 1 0 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 0 +RenderTerrainLODFactor 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +RenderWaterReflections 1 0 +VertexShaderEnable 1 0 +WindLightUseAtmosShaders 1 0 +WLSkyDetail 1 48 + +// +// Mid Graphics Settings +// +list Mid +RenderAnisotropic 1 0 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 0.5 +RenderAvatarVP 1 1 +RenderFarClip 1 96 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 8 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 2048 +RenderObjectBump 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 1.0 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +RenderWaterReflections 1 0 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 0 +WLSkyDetail 1 48 + +// +// High Graphics Settings (purty) +// +list High +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderReflectionDetail 1 2 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +RenderWaterReflections 1 0 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +WLSkyDetail 1 48 + +// +// Ultra graphics (REALLY PURTY!) +// +list Ultra +RenderAnisotropic 1 1 +RenderAvatarCloth 1 1 +RenderAvatarLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 256 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 8192 +RenderObjectBump 1 1 +RenderReflectionDetail 1 3 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTreeLODFactor 1 1.0 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 2.0 +RenderWaterReflections 1 1 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +WLSkyDetail 1 128 + +// +// Class Unknown Hardware (unknown) +// +list Unknown +RenderVBOEnable 1 0 + +// +// Class 0 Hardware (just old) // list Class0 -VertexShaderEnable 1 0 -RenderVBO 1 0 -RenderDistance 1 64 -RenderAvatarVP 1 0 -RenderAvatarMode 1 0 -RenderLighting 1 0 -RenderObjectBump 1 0 -RenderRippleWater 1 0 +RenderVBOEnable 1 1 // // Class 1 Hardware // list Class1 -VertexShaderEnable 1 0 -RenderVBO 1 1 -RenderDistance 1 96 -RenderAvatarVP 1 1 -RenderAvatarMode 1 0 -RenderLighting 1 0 -RenderObjectBump 1 0 -RenderRippleWater 1 0 +RenderVBOEnable 1 1 // // Class 2 Hardware (make it purty) // list Class2 -VertexShaderEnable 1 1 -RenderAvatarVP 1 1 -RenderAvatarMode 1 1 -RenderLighting 1 1 -RenderObjectBump 1 1 -RenderRippleWater 1 1 +RenderVBOEnable 1 1 // // Class 3 Hardware (make it purty) // list Class3 -VertexShaderEnable 1 1 -RenderAvatarVP 1 1 -RenderAvatarMode 1 1 -RenderLighting 1 1 -RenderObjectBump 1 1 -RenderRippleWater 1 1 +RenderVBOEnable 1 1 // // No Pixel Shaders available // list NoPixelShaders -VertexShaderEnable 0 0 -RenderAvatarVP 0 0 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +RenderWaterReflections 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 // // No Vertex Shaders available // list NoVertexShaders -VertexShaderEnable 0 0 -RenderAvatarVP 0 0 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +RenderWaterReflections 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 -// // "Default" setups for safe, low, medium, high // list safe -RenderVBO 1 0 -RenderAniso 1 0 -RenderAvatarVP 0 0 -RenderLighting 1 0 -RenderParticleCount 1 1024 -RenderTerrainDetail 1 0 - - -list low -RenderVBO 1 0 -RenderAniso 1 0 -RenderLighting 1 0 - -list medium -RenderLighting 1 0 - +RenderAnisotropic 1 0 +RenderAvatarCloth 0 0 +RenderAvatarVP 0 0 +RenderLightingDetail 1 0 +RenderObjectBump 0 0 +RenderMaxPartCount 1 1024 +RenderTerrainDetail 1 0 +RenderUseImpostors 0 0 +RenderVBOEnable 1 0 +RenderWaterReflections 0 0 +WindLightUseAtmosShaders 0 0 // // CPU based feature masks @@ -126,37 +223,266 @@ RenderLighting 1 0 // 1Ghz or less (equiv) list CPUSlow -RenderParticleCount 1 1024 - +RenderMaxPartCount 1 1024 // // RAM based feature masks // list RAM256MB -RenderObjectBump 0 0 - +RenderObjectBump 0 0 // // Graphics card based feature masks // list OpenGLPre15 -RenderVBO 1 0 +RenderVBOEnable 1 0 list Intel -RenderVBO 1 0 -RenderAniso 1 0 -RenderLighting 1 0 -RenderTerrainDetail 1 0 +RenderAnisotropic 1 0 +RenderLightingDetail 1 0 list GeForce2 -RenderVBO 1 1 -RenderAniso 1 0 -RenderLighting 1 0 -RenderParticleCount 1 2048 -RenderTerrainDetail 1 0 +RenderAnisotropic 1 0 +RenderLightingDetail 1 0 +RenderMaxPartCount 1 2048 +RenderTerrainDetail 1 0 +RenderVBOEnable 1 1 + + +list Intel_830M +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_845G +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_855GM +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_865G +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_900 +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_915GM +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_915G +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_945GM +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_945G +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_950 +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_965 +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 +UseOcclusion 0 0 + +list Intel_G33 +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_Bear_Lake +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_Broadwater +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_Brookdale +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_Montara +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_Springdale +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + + + +list ATI_Mobility_Radeon_9800 +RenderAvatarCloth 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 + +list ATI_Mobility_Radeon_9700 +RenderAvatarCloth 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 + +list ATI_Mobility_Radeon_9600 +RenderAvatarCloth 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 +Disregard96DefaultDrawDistance 1 0 + + +/// tweaked ATI to 96 Draw distance + +list ATI_Radeon_9000 +Disregard96DefaultDrawDistance 1 0 +list ATI_Radeon_9200 +Disregard96DefaultDrawDistance 1 0 +list ATI_Radeon_9500 +Disregard96DefaultDrawDistance 1 0 +list ATI_Radeon_9600 +Disregard96DefaultDrawDistance 1 0 + +/// tweaked ATI to 128 draw distance + +list ATI_Radeon_X300 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X400 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X500 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X600 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X700 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1300 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1400 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1500 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1600 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1700 +Disregard128DefaultDrawDistance 1 0 + +list ATI_Mobility_Radeon_X1xxx +Disregard128DefaultDrawDistance 1 0 + + + +// Avatar hardware skinning causes +// invisible avatars on x2600... so I masked +// out other possible bad ones till it's fixed in 8.2 + +list ATI_Radeon_HD_2300 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_HD_2400 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_HD_2600 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +list ATI_Radeon_HD_2900 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +list ATI_Radeon_HD_3800 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 + +list ATI_ASUS_AH24xx +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +Disregard128DefaultDrawDistance 1 0 +list ATI_ASUS_AH26xx +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +list ATI_ASUS_EAH24xx +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +list ATI_ASUS_EAH26xx +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +list ATI_ASUS_EAH38xx +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 + + +/// Tweaked NVIDIA + +list NVIDIA_GeForce_FX_5100 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_5200 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_5500 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_5600 +Disregard96DefaultDrawDistance 1 0 + +list NVIDIA_GeForce_FX_Go5100 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_Go5200 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_Go5300 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_Go5500 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_Go5600 +Disregard96DefaultDrawDistance 1 0 + +list NVIDIA_GeForce_6100 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_6200 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_6500 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_6600 +Disregard128DefaultDrawDistance 1 0 + +list NVIDIA_G73 +Disregard128DefaultDrawDistance 1 0 + +list NVIDIA_GeForce_Go_6100 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6200 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6500 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6600 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6700 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6800 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 + +list NVIDIA_GeForce_7200 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_7300 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_7400 +Disregard128DefaultDrawDistance 1 0 -list ATI_Mobility_Radeon_X3xx -VertexShaderEnable 1 0 +list NVIDIA_GeForce_Go_7200 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_7300 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_7400 +Disregard128DefaultDrawDistance 1 0 -list ATI_Mobility_Radeon_X6xx -VertexShaderEnable 1 0 diff --git a/linden/indra/newview/featuretable_linux.txt b/linden/indra/newview/featuretable_linux.txt index f31fc0d..d7921ff 100644 --- a/linden/indra/newview/featuretable_linux.txt +++ b/linden/indra/newview/featuretable_linux.txt @@ -1,6 +1,6 @@ -version 10 +version 15 -// NOTE: This is mostly identical to featuretable.txt with a few differences +// NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table // @@ -12,7 +12,7 @@ version 10 // // is the name of a feature // is 0 or 1, whether the feature is available -// is an S32 which is the recommended value +// is an F32 which is the recommended value // // For now, the first list read sets up all of the default values // @@ -23,104 +23,199 @@ version 10 // NOTE: All settings are set to the MIN of applied values, including 'all'! // list all -RenderVBO 1 1 -RenderAniso 1 0 -RenderAvatarMode 1 2 -RenderAvatarVP 1 1 -RenderDistance 1 128 -RenderLighting 1 1 -RenderObjectBump 1 1 -RenderParticleCount 1 4096 -RenderRippleWater 1 1 -RenderTerrainDetail 1 2 -VertexShaderEnable 1 1 -UseOcclusion 1 1 -RenderCubeMap 1 1 - -// -// Class 0 Hardware (Unknown or just old) +RenderAnisotropic 1 0 +RenderAvatarCloth 1 1 +RenderAvatarLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderCubeMap 1 1 +RenderFarClip 1 256 +RenderFlexTimeFactor 1 1.0 +RenderFogRatio 1 4.0 +RenderGamma 1 0 +RenderGlowResolutionPow 1 9 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 8192 +RenderNightBrightness 1 1.0 +RenderObjectBump 1 1 +RenderReflectionDetail 1 3 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTreeLODFactor 1 1.0 +RenderUseImpostors 1 1 +RenderVBOEnable 1 1 +RenderVolumeLODFactor 1 2.0 +RenderWaterReflections 1 1 +UseOcclusion 1 1 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +WLSkyDetail 1 128 +Disregard128DefaultDrawDistance 1 1 +Disregard96DefaultDrawDistance 1 1 + +// +// Low Graphics Settings +// +list Low +RenderAnisotropic 1 0 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 0.5 +RenderAvatarVP 1 0 +RenderFarClip 1 64 +RenderFlexTimeFactor 1 0.5 +RenderGlowResolutionPow 1 8 +RenderLightingDetail 1 0 +RenderMaxPartCount 1 1024 +RenderObjectBump 1 0 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 0 +RenderTerrainLODFactor 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +RenderWaterReflections 1 0 +VertexShaderEnable 1 0 +WindLightUseAtmosShaders 1 0 +WLSkyDetail 1 48 + +// +// Mid Graphics Settings +// +list Mid +RenderAnisotropic 1 0 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 0.5 +RenderAvatarVP 1 1 +RenderFarClip 1 96 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 8 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 2048 +RenderObjectBump 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 1.0 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +RenderWaterReflections 1 0 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 0 +WLSkyDetail 1 48 + +// +// High Graphics Settings (purty) +// +list High +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderReflectionDetail 1 2 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +RenderWaterReflections 1 0 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +WLSkyDetail 1 48 + +// +// Ultra graphics (REALLY PURTY!) +// +list Ultra +RenderAnisotropic 1 1 +RenderAvatarCloth 1 1 +RenderAvatarLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 256 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 8192 +RenderObjectBump 1 1 +RenderReflectionDetail 1 3 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTreeLODFactor 1 1.0 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 2.0 +RenderWaterReflections 1 1 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +WLSkyDetail 1 128 + +// +// Class Unknown Hardware (unknown) +// +list Unknown +RenderVBOEnable 1 0 + +// +// Class 0 Hardware (just old) // list Class0 -VertexShaderEnable 1 0 -RenderVBO 1 0 -RenderDistance 1 64 -RenderAvatarVP 1 0 -RenderAvatarMode 1 0 -RenderLighting 1 0 -RenderObjectBump 1 0 -RenderRippleWater 1 0 +RenderVBOEnable 1 1 // // Class 1 Hardware // list Class1 -VertexShaderEnable 1 0 -RenderVBO 1 1 -RenderDistance 1 96 -RenderAvatarVP 1 1 -RenderAvatarMode 1 0 -RenderLighting 1 0 -RenderObjectBump 1 0 -RenderRippleWater 1 0 +RenderVBOEnable 1 1 // // Class 2 Hardware (make it purty) // list Class2 -VertexShaderEnable 1 1 -RenderAvatarVP 1 1 -RenderAvatarMode 1 1 -RenderLighting 1 1 -RenderObjectBump 1 1 -RenderRippleWater 1 1 +RenderVBOEnable 1 1 // // Class 3 Hardware (make it purty) // list Class3 -VertexShaderEnable 1 1 -RenderAvatarVP 1 1 -RenderAvatarMode 1 1 -RenderLighting 1 1 -RenderObjectBump 1 1 -RenderRippleWater 1 1 +RenderVBOEnable 1 1 // // No Pixel Shaders available // list NoPixelShaders -VertexShaderEnable 0 0 -RenderAvatarVP 0 0 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +RenderWaterReflections 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 // // No Vertex Shaders available // list NoVertexShaders -VertexShaderEnable 0 0 -RenderAvatarVP 0 0 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +RenderWaterReflections 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 -// // "Default" setups for safe, low, medium, high // list safe -RenderVBO 1 0 -RenderAniso 1 0 -RenderAvatarVP 0 0 -RenderLighting 1 0 -RenderParticleCount 1 1024 -RenderTerrainDetail 1 0 -RenderCubeMap 0 0 -UseOcclusion 0 0 - - -list low -RenderVBO 1 0 -RenderAniso 1 0 -RenderLighting 1 0 - -list medium -RenderLighting 1 0 - +RenderAnisotropic 1 0 +RenderAvatarCloth 0 0 +RenderAvatarVP 0 0 +RenderLightingDetail 1 0 +RenderObjectBump 0 0 +RenderMaxPartCount 1 1024 +RenderTerrainDetail 1 0 +RenderUseImpostors 0 0 +RenderVBOEnable 1 0 +RenderWaterReflections 0 0 +WindLightUseAtmosShaders 0 0 // // CPU based feature masks @@ -128,52 +223,203 @@ RenderLighting 1 0 // 1Ghz or less (equiv) list CPUSlow -RenderParticleCount 1 1024 - +RenderMaxPartCount 1 1024 // // RAM based feature masks // list RAM256MB -RenderObjectBump 0 0 - +RenderObjectBump 0 0 // // Graphics card based feature masks // list OpenGLPre15 -RenderVBO 1 0 +RenderVBOEnable 1 0 list Intel -RenderVBO 1 0 -RenderAniso 1 0 -RenderLighting 1 0 -RenderTerrainDetail 1 0 -RenderCubeMap 0 0 +RenderAnisotropic 1 0 +RenderLightingDetail 1 0 +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 +RenderCubeMap 0 0 + list GeForce2 -RenderVBO 1 1 -RenderAniso 1 0 -RenderLighting 1 0 -RenderParticleCount 1 2048 -RenderTerrainDetail 1 0 +RenderAnisotropic 1 0 +RenderLightingDetail 1 0 +RenderMaxPartCount 1 2048 +RenderTerrainDetail 1 0 -list GeForce3 +list Intel_965 +UseOcclusion 0 0 list ATI -UseOcclusion 0 0 +UseOcclusion 0 0 +WindLightUseAtmosShaders 0 0 +RenderVBOEnable 1 0 + +list ATI_Mobility_Radeon_9800 +RenderAvatarCloth 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 + +list ATI_Mobility_Radeon_9700 +RenderAvatarCloth 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 + +list ATI_Mobility_Radeon_9600 +RenderAvatarCloth 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 +Disregard96DefaultDrawDistance 1 0 + + +/// tweaked ATI to 96 Draw distance + +list ATI_Radeon_9000 +Disregard96DefaultDrawDistance 1 0 +list ATI_Radeon_9200 +Disregard96DefaultDrawDistance 1 0 +list ATI_Radeon_9500 +Disregard96DefaultDrawDistance 1 0 +list ATI_Radeon_9600 +Disregard96DefaultDrawDistance 1 0 + +/// tweaked ATI to 128 draw distance + +list ATI_Radeon_X300 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X400 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X500 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X600 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X700 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1300 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1400 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1500 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1600 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1700 +Disregard128DefaultDrawDistance 1 0 +list ATI_Mobility_Radeon_X1xxx +Disregard128DefaultDrawDistance 1 0 + + + + +// Avatar hardware skinning causes +// invisible avatars on HD 2400... so I masked +// out other possible bad ones till it's fixed + +list ATI_Radeon_HD_2300 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_HD_2400 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_HD_2600 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +list ATI_Radeon_HD_2900 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +list ATI_Radeon_HD_3800 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 + +list ATI_ASUS_AH24xx +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +Disregard128DefaultDrawDistance 1 0 +list ATI_ASUS_AH26xx +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +list ATI_ASUS_EAH24xx +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +list ATI_ASUS_EAH26xx +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +list ATI_ASUS_EAH38xx +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 + + +/// Tweaked NVIDIA + +list NVIDIA_GeForce_FX_5100 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_5200 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_5500 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_5600 +Disregard96DefaultDrawDistance 1 0 + +list NVIDIA_GeForce_FX_Go5100 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_Go5200 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_Go5300 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_Go5500 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_Go5600 +Disregard96DefaultDrawDistance 1 0 + +list NVIDIA_GeForce_6100 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_6200 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_6500 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_6600 +Disregard128DefaultDrawDistance 1 0 + -list Radeon8500 -RenderLighting 1 0 -RenderParticleCount 1 4096 +list NVIDIA_GeForce_Go_6100 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6200 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6500 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6600 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6700 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6800 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 -// Hacked to be paranoid "safe" -list Radeon9700 -RenderParticleCount 1 4096 +list NVIDIA_GeForce_7200 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_7300 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_7400 +Disregard128DefaultDrawDistance 1 0 -// Hacked to be paranoid "safe" -list MobilityRadeon9000 -RenderLighting 1 0 -RenderParticleCount 1 4096 +list NVIDIA_GeForce_Go_7200 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_7300 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_7400 +Disregard128DefaultDrawDistance 1 0 -list GeForceFX diff --git a/linden/indra/newview/featuretable_mac.txt b/linden/indra/newview/featuretable_mac.txt index fe5ae7a..9645ff8 100644 --- a/linden/indra/newview/featuretable_mac.txt +++ b/linden/indra/newview/featuretable_mac.txt @@ -1,6 +1,6 @@ -version 10 +version 15 -// NOTE: This is mostly identical to featuretable.txt with a few differences +// NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table // @@ -12,7 +12,7 @@ version 10 // // is the name of a feature // is 0 or 1, whether the feature is available -// is an S32 which is the recommended value +// is an F32 which is the recommended value // // For now, the first list read sets up all of the default values // @@ -22,102 +22,201 @@ version 10 // All contains everything at their default settings for high end machines // NOTE: All settings are set to the MIN of applied values, including 'all'! // -// Mac specific: RenderAvatarVP not enabled at all list all -RenderVBO 1 0 -RenderAniso 1 0 -RenderAvatarMode 1 2 -RenderAvatarVP 1 0 -RenderDistance 1 128 -RenderLighting 1 1 -RenderObjectBump 1 1 -RenderParticleCount 1 4096 -RenderRippleWater 1 1 -RenderTerrainDetail 1 2 -VertexShaderEnable 1 1 -UseOcclusion 1 1 -RenderCubeMap 1 1 - -// -// Class 0 Hardware (Unknown or just old) +RenderAnisotropic 1 0 +RenderAvatarCloth 0 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarVP 1 0 +RenderCubeMap 1 1 +RenderFarClip 1 256 +RenderFlexTimeFactor 1 1.0 +RenderFogRatio 1 4.0 +RenderGamma 1 0 +RenderGlowResolutionPow 1 9 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 8192 +RenderNightBrightness 1 1.0 +RenderObjectBump 1 1 +RenderReflectionDetail 1 3 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTreeLODFactor 1 1.0 +RenderUseImpostors 1 1 +RenderVBOEnable 1 1 +RenderVolumeLODFactor 1 2.0 +RenderWaterReflections 1 1 +UseOcclusion 1 1 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +WLSkyDetail 1 128 +RenderUseCleverUI 1 1 +Disregard128DefaultDrawDistance 1 1 +Disregard96DefaultDrawDistance 1 1 + +// +// Low Graphics Settings +// +list Low +RenderAnisotropic 1 0 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 0.5 +RenderAvatarVP 1 0 +RenderFarClip 1 64 +RenderFlexTimeFactor 1 0.5 +RenderGlowResolutionPow 1 8 +RenderLightingDetail 1 0 +RenderMaxPartCount 1 1024 +RenderObjectBump 1 0 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 0 +RenderTerrainLODFactor 1 1 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +RenderWaterReflections 1 0 +VertexShaderEnable 1 0 +WindLightUseAtmosShaders 1 0 +WLSkyDetail 1 48 + +// +// Mid Graphics Settings +// +list Mid +RenderAnisotropic 1 0 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 0.5 +RenderAvatarVP 1 1 +RenderFarClip 1 96 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 8 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 2048 +RenderObjectBump 1 1 +RenderReflectionDetail 1 0 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 1.0 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +RenderWaterReflections 1 0 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 0 +WLSkyDetail 1 48 + +// +// High Graphics Settings (purty) +// +list High +RenderAnisotropic 1 1 +RenderAvatarCloth 1 0 +RenderAvatarLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 128 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 4096 +RenderObjectBump 1 1 +RenderReflectionDetail 1 2 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTreeLODFactor 1 0.5 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 1.125 +RenderWaterReflections 1 0 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +WLSkyDetail 1 48 + +// +// Ultra graphics (REALLY PURTY!) +// +list Ultra +RenderAnisotropic 1 1 +RenderAvatarCloth 1 1 +RenderAvatarLODFactor 1 1.0 +RenderAvatarVP 1 1 +RenderFarClip 1 256 +RenderFlexTimeFactor 1 1.0 +RenderGlowResolutionPow 1 9 +RenderLightingDetail 1 1 +RenderMaxPartCount 1 8192 +RenderObjectBump 1 1 +RenderReflectionDetail 1 3 +RenderTerrainDetail 1 1 +RenderTerrainLODFactor 1 2.0 +RenderTreeLODFactor 1 1.0 +RenderUseImpostors 1 1 +RenderVolumeLODFactor 1 2.0 +RenderWaterReflections 1 1 +VertexShaderEnable 1 1 +WindLightUseAtmosShaders 1 1 +WLSkyDetail 1 128 + +// +// Class Unknown Hardware (unknown) +// +list Unknown +RenderVBOEnable 1 0 + +// +// Class 0 Hardware (just old) // list Class0 -VertexShaderEnable 1 0 -RenderAvatarVP 1 0 -RenderAvatarMode 1 0 -RenderLighting 1 0 -RenderObjectBump 1 0 -RenderRippleWater 1 0 +RenderVBOEnable 1 1 // // Class 1 Hardware // list Class1 -VertexShaderEnable 1 0 -RenderAvatarVP 1 1 -RenderAvatarMode 1 0 -RenderLighting 1 0 -RenderObjectBump 1 0 -RenderRippleWater 1 0 +RenderVBOEnable 1 1 // // Class 2 Hardware (make it purty) // list Class2 -VertexShaderEnable 1 1 -RenderAvatarVP 1 1 -RenderAvatarMode 1 2 -RenderLighting 1 1 -RenderObjectBump 1 1 -RenderRippleWater 1 1 +RenderVBOEnable 1 1 // // Class 3 Hardware (make it purty) // list Class3 -VertexShaderEnable 1 1 -RenderAvatarVP 1 1 -RenderAvatarMode 1 2 -RenderLighting 1 1 -RenderObjectBump 1 1 -RenderRippleWater 1 1 +RenderVBOEnable 1 1 // // No Pixel Shaders available // list NoPixelShaders -VertexShaderEnable 0 0 -RenderAvatarVP 0 0 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +RenderWaterReflections 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 // // No Vertex Shaders available // list NoVertexShaders -VertexShaderEnable 0 0 -RenderAvatarVP 0 0 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +RenderWaterReflections 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 -// // "Default" setups for safe, low, medium, high // list safe -RenderVBO 1 0 -RenderAniso 1 0 -RenderAvatarVP 0 0 -RenderDistance 1 64 -RenderLighting 1 0 -RenderParticleCount 1 1024 -RenderTerrainDetail 1 0 - - -list low -RenderVBO 1 0 -RenderAniso 1 0 -RenderDistance 1 96 -RenderLighting 1 0 - -list medium -RenderLighting 1 0 - +RenderAnisotropic 1 0 +RenderAvatarCloth 0 0 +RenderAvatarVP 0 0 +RenderLightingDetail 1 0 +RenderObjectBump 0 0 +RenderMaxPartCount 1 1024 +RenderTerrainDetail 1 0 +RenderUseImpostors 0 0 +RenderVBOEnable 1 0 +RenderWaterReflections 0 0 +WindLightUseAtmosShaders 0 0 // // CPU based feature masks @@ -125,34 +224,244 @@ RenderLighting 1 0 // 1Ghz or less (equiv) list CPUSlow -RenderDistance 1 96 -RenderParticleCount 1 1024 - +RenderMaxPartCount 1 1024 // // RAM based feature masks // list RAM256MB -RenderDistance 1 96 -RenderObjectBump 0 0 +RenderObjectBump 0 0 // // Graphics card based feature masks // list OpenGLPre15 -RenderVBO 1 0 +RenderVBOEnable 1 0 -// nVidia settings -list NVIDIA +list Intel +RenderAnisotropic 1 0 +RenderLightingDetail 1 0 list GeForce2 -RenderAniso 1 0 -RenderDistance 1 64 -RenderLighting 1 0 -RenderParticleCount 1 2048 -RenderTerrainDetail 1 0 +RenderAnisotropic 1 0 +RenderLightingDetail 1 0 +RenderMaxPartCount 1 2048 +RenderTerrainDetail 1 0 +RenderVBOEnable 1 1 + +list Intel_830M +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_845G +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_855GM +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_865G +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_900 +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_915GM +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_915G +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_945GM +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_945G +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_950 +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_965 +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 +UseOcclusion 0 0 + +list Intel_G33 +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_Bear_Lake +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_Broadwater +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_Brookdale +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_X3100 +WindLightUseAtmosShaders 0 0 + +list Intel_Montara +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list Intel_Springdale +RenderTerrainDetail 1 0 +RenderVBOEnable 1 0 + +list ATI_Mobility_Radeon_9800 +RenderAvatarCloth 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 + +list ATI_Mobility_Radeon_9700 +RenderAvatarCloth 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 + +list ATI_Mobility_Radeon_9600 +RenderAvatarCloth 0 0 +VertexShaderEnable 0 0 +WindLightUseAtmosShaders 0 0 +Disregard96DefaultDrawDistance 1 0 + + +/// tweaked ATI to 96 Draw distance + +list ATI_Radeon_9000 +Disregard96DefaultDrawDistance 1 0 +list ATI_Radeon_9200 +Disregard96DefaultDrawDistance 1 0 +list ATI_Radeon_9500 +Disregard96DefaultDrawDistance 1 0 +list ATI_Radeon_9600 +Disregard96DefaultDrawDistance 1 0 + +/// tweaked ATI to 128 draw distance + +list ATI_Radeon_X300 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X400 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X500 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X600 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X700 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1300 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1400 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1500 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1600 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_X1700 +Disregard128DefaultDrawDistance 1 0 +list ATI_Mobility_Radeon_X1xxx +Disregard128DefaultDrawDistance 1 0 + + + + +// Avatar hardware skinning causes +// invisible avatars on HD 2600... so I masked +// out other possible bad ones till it's fixed + +list ATI_Radeon_HD_2300 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_HD_2400 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +Disregard128DefaultDrawDistance 1 0 +list ATI_Radeon_HD_2600 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +list ATI_Radeon_HD_2900 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 +list ATI_Radeon_HD_3800 +RenderAvatarVP 0 0 +RenderAvatarCloth 0 0 + +/// Tweaked NVIDIA + +list NVIDIA_GeForce_FX_5100 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_5200 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_5500 +Disregard96DefaultDrawDistance 1 0 + +list NVIDIA_GeForce_FX_Go5100 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_Go5200 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_Go5300 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_Go5500 +Disregard96DefaultDrawDistance 1 0 +list NVIDIA_GeForce_FX_Go5600 +Disregard96DefaultDrawDistance 1 0 + +list NVIDIA_GeForce_6100 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_6200 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_6500 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_6600 +Disregard128DefaultDrawDistance 1 0 + + +list NVIDIA_GeForce_Go_6100 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6200 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6500 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6600 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6700 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6800 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_6 +RenderVBOEnable 1 0 +Disregard128DefaultDrawDistance 1 0 + +list NVIDIA_GeForce_7200 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_7300 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_7400 +Disregard128DefaultDrawDistance 1 0 + +list NVIDIA_GeForce_Go_7200 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_7300 +Disregard128DefaultDrawDistance 1 0 +list NVIDIA_GeForce_Go_7400 +Disregard128DefaultDrawDistance 1 0 -// -// ATI settings -// -list ATI diff --git a/linden/indra/newview/featuretable_solaris.txt b/linden/indra/newview/featuretable_solaris.txt index 6c7acfa..7dd7c22 100644 --- a/linden/indra/newview/featuretable_solaris.txt +++ b/linden/indra/newview/featuretable_solaris.txt @@ -1,4 +1,4 @@ -version 10 +version 15 // NOTE: This is mostly identical to featuretable.txt with a few differences // Should be combined into one table diff --git a/linden/indra/newview/files.lst b/linden/indra/newview/files.lst index 50431fb..0f07254 100644 --- a/linden/indra/newview/files.lst +++ b/linden/indra/newview/files.lst @@ -2,7 +2,6 @@ newview/head.cpp newview/llagent.cpp newview/llagentdata.cpp newview/llagentpilot.cpp -newview/llanimalcontrols.cpp newview/llappviewer.cpp newview/llappviewerlinux.cpp newview/llassetuploadresponders.cpp @@ -13,9 +12,9 @@ newview/llcallbacklist.cpp newview/llcallingcard.cpp newview/llcameraview.cpp newview/llcaphttpsender.cpp -newview/llcape.cpp newview/llchatbar.cpp newview/llclassifiedinfo.cpp +newview/llclassifiedstatsresponder.cpp newview/llcloud.cpp newview/llcolorscheme.cpp newview/llcolorswatch.cpp @@ -33,17 +32,17 @@ newview/lldebugmessagebox.cpp newview/lldebugview.cpp newview/lldirpicker.cpp newview/lldrawable.cpp -newview/lldrawpool.cpp newview/lldrawpoolalpha.cpp newview/lldrawpoolavatar.cpp newview/lldrawpoolbump.cpp +newview/lldrawpool.cpp newview/lldrawpoolground.cpp newview/lldrawpoolsimple.cpp newview/lldrawpoolsky.cpp -newview/lldrawpoolstars.cpp newview/lldrawpoolterrain.cpp newview/lldrawpooltree.cpp newview/lldrawpoolwater.cpp +newview/lldrawpoolwlsky.cpp newview/lldriverparam.cpp newview/lldynamictexture.cpp newview/llemote.cpp @@ -71,20 +70,25 @@ newview/llfloaterbuycurrency.cpp newview/llfloaterbuyland.cpp newview/llfloaterchat.cpp newview/llfloaterchatterbox.cpp +newview/llfloaterclassified.cpp newview/llfloaterclothing.cpp newview/llfloatercolorpicker.cpp newview/llfloatercustomize.cpp +newview/llfloaterdaycycle.cpp newview/llfloaterdirectory.cpp newview/llfloatereditui.cpp +newview/llfloaterenvsettings.cpp +newview/llfloaterevent.cpp newview/llfloaterfriends.cpp newview/llfloatergesture.cpp newview/llfloatergodtools.cpp newview/llfloatergroupinfo.cpp newview/llfloatergroupinvite.cpp newview/llfloatergroups.cpp +newview/llfloaterhardwaresettings.cpp newview/llfloaterhtml.cpp +newview/llfloaterhtmlhelp.cpp newview/llfloaterimagepreview.cpp -newview/llfloaterimport.cpp newview/llfloaterinspect.cpp newview/llfloaterlagmeter.cpp newview/llfloaterland.cpp @@ -95,14 +99,15 @@ newview/llfloatermute.cpp newview/llfloaternamedesc.cpp newview/llfloaternewim.cpp newview/llfloateropenobject.cpp +newview/llfloaterparcel.cpp newview/llfloaterpermissionsmgr.cpp newview/llfloaterpostcard.cpp +newview/llfloaterpostprocess.cpp newview/llfloaterpreference.cpp newview/llfloaterproperties.cpp -newview/llfloaterreleasemsg.cpp newview/llfloaterregioninfo.cpp +newview/llfloaterreleasemsg.cpp newview/llfloaterreporter.cpp -newview/llfloatersaveavatar.cpp newview/llfloaterscriptdebug.cpp newview/llfloatersellland.cpp newview/llfloatersnapshot.cpp @@ -111,7 +116,11 @@ newview/llfloatertest.cpp newview/llfloatertools.cpp newview/llfloatertopobjects.cpp newview/llfloatertos.cpp +newview/llfloaterurldisplay.cpp +newview/llfloaterurlentry.cpp newview/llfloatervoicewizard.cpp +newview/llfloaterwater.cpp +newview/llfloaterwindlight.cpp newview/llfloaterworldmap.cpp newview/llfolderview.cpp newview/llfollowcam.cpp @@ -126,7 +135,6 @@ newview/llgroupmgr.cpp newview/llgroupnotify.cpp newview/llhippo.cpp newview/llhoverview.cpp -newview/llhudconnector.cpp newview/llhudeffectbeam.cpp newview/llhudeffect.cpp newview/llhudeffectlookat.cpp @@ -147,7 +155,6 @@ newview/llinventorymodel.cpp newview/llinventoryview.cpp newview/lljoystickbutton.cpp newview/lllandmarklist.cpp -newview/lllocalanimationobject.cpp newview/lllogchat.cpp newview/llmanip.cpp newview/llmaniprotate.cpp @@ -157,6 +164,7 @@ newview/llmapresponders.cpp newview/llmediaremotectrl.cpp newview/llmemoryview.cpp newview/llmenucommands.cpp +newview/llmimetypes.cpp newview/llmorphview.cpp newview/llmoveview.cpp newview/llmutelist.cpp @@ -195,6 +203,7 @@ newview/llpanelgroupvoting.cpp newview/llpanelinput.cpp newview/llpanelinventory.cpp newview/llpanelland.cpp +newview/llpanellandmedia.cpp newview/llpanellandobjects.cpp newview/llpanellandoptions.cpp newview/llpanellogin.cpp @@ -207,9 +216,11 @@ newview/llpanelpick.cpp newview/llpanelplace.cpp newview/llpanelvolume.cpp newview/llpanelweb.cpp +newview/llparcelselection.cpp newview/llpatchvertexarray.cpp newview/llpolymesh.cpp newview/llpolymorph.cpp +newview/llpostprocess.cpp newview/llprefschat.cpp newview/llprefsim.cpp newview/llprefsvoice.cpp @@ -223,7 +234,7 @@ newview/llpreviewsound.cpp newview/llpreviewtexture.cpp newview/llprogressview.cpp newview/llregionposition.cpp -newview/llroam.cpp +newview/llremoteparcelrequest.cpp newview/llsavedsettingsglue.cpp newview/llselectmgr.cpp newview/llsky.cpp @@ -240,8 +251,8 @@ newview/llsurface.cpp newview/llsurfacepatch.cpp newview/lltexlayer.cpp newview/lltexturecache.cpp -newview/lltexturefetch.cpp newview/lltexturectrl.cpp +newview/lltexturefetch.cpp newview/lltextureview.cpp newview/lltoolbar.cpp newview/lltoolbrush.cpp @@ -267,6 +278,7 @@ newview/lltracker.cpp newview/lluploaddialog.cpp newview/llurl.cpp newview/llurldispatcher.cpp +newview/llurlhistory.cpp newview/llurlsimstring.cpp newview/llurlwhitelist.cpp newview/lluserauth.cpp @@ -286,19 +298,21 @@ newview/llviewerinventory.cpp newview/llviewerjointattachment.cpp newview/llviewerjoint.cpp newview/llviewerjointmesh.cpp -newview/llviewerjointmesh_sse.cpp newview/llviewerjointmesh_sse2.cpp +newview/llviewerjointmesh_sse.cpp newview/llviewerjointmesh_vec.cpp -newview/llviewerjointshape.cpp newview/llviewerjoystick.cpp newview/llviewerkeyboard.cpp newview/llviewerlayer.cpp +newview/llviewermedia.cpp newview/llviewermenu.cpp newview/llviewermenufile.cpp newview/llviewermessage.cpp newview/llviewernetwork.cpp newview/llviewerobject.cpp newview/llviewerobjectlist.cpp +newview/llviewerparcelmedia.cpp +newview/llviewerparcelmediaautoplay.cpp newview/llviewerparcelmgr.cpp newview/llviewerparceloverlay.cpp newview/llviewerpartsim.cpp @@ -325,18 +339,24 @@ newview/llvoicevisualizer.cpp newview/llvoinventorylistener.cpp newview/llvopartgroup.cpp newview/llvosky.cpp -newview/llvostars.cpp newview/llvosurfacepatch.cpp newview/llvotextbubble.cpp newview/llvotree.cpp newview/llvovolume.cpp newview/llvowater.cpp +newview/llvowlsky.cpp +newview/llwaterparammanager.cpp +newview/llwaterparamset.cpp newview/llwearable.cpp newview/llwearablelist.cpp -newview/llweb.cpp newview/llwebbrowserctrl.cpp +newview/llweb.cpp newview/llwind.cpp newview/llwindebug.cpp +newview/llwlanimator.cpp +newview/llwldaycycle.cpp +newview/llwlparammanager.cpp +newview/llwlparamset.cpp newview/llworld.cpp newview/llworldmap.cpp newview/llworldmapview.cpp @@ -344,9 +364,3 @@ newview/llxmlrpctransaction.cpp newview/moviemaker.cpp newview/noise.cpp newview/pipeline.cpp -newview/llremoteparcelrequest.cpp -newview/llfloaterurldisplay.cpp -newview/llfloaterevent.cpp -newview/llfloaterclassified.cpp -newview/llfloaterparcel.cpp -newview/llclassifiedstatsresponder.cpp diff --git a/linden/indra/newview/gpu_table.txt b/linden/indra/newview/gpu_table.txt index 4b9bf65..066cd98 100644 --- a/linden/indra/newview/gpu_table.txt +++ b/linden/indra/newview/gpu_table.txt @@ -1,139 +1,191 @@ // // Categorizes graphics chips into various classes by name // -// The table contains chip names regular expressions to match -// against driver strings and a class number. +// The table contains chip names regular expressions to match +// against driver strings, a class number, and whether we claim +// to support them or not. // // Class Numbers: -// 0 - Compatibility rendering only -// 1 - Shaders available off by default -// 2 - Shaders enabled by default -// 3 - Everything on. +// 0 - Defaults to low graphics settings. No shaders on by default +// 1 - Defaults to mid graphics settings. Basic shaders on by default +// 2 - Defaults to high graphics settings. Atmospherics on by default. +// 3 - Same as class 2 for now. +// +// Supported Number: +// 0 - We claim to not support this card. +// 1 - We claim to support this card. // // Format: -// +// // -3Dfx .*3Dfx.* 0 -3Dlabs .*3Dlabs.* 0 -ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 -ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 2 -ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 -ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 -ATI ASUS X1xxx .*ASUS X1.* 3 -ATI Mobility Radeon X1xxx .*ATI.*Mobility.*X1.* 2 -ATI Mobility Radeon X3xx .*ATI.*Mobility.*X3.* 1 -ATI Mobility Radeon X6xx .*ATI.*Mobility.*X6.* 1 -ATI Mobility Radeon X7xx .*ATI.*Mobility.*X7.* 1 -ATI Mobility Radeon Xxxx .*ATI.*Mobility.*X.* 1 -ATI Mobility Radeon .*ATI.*Mobility.* 0 -ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 3 -ATI Diamond X1xxx .*ATI.*Diamond.*X1.* 3 -ATI FireGL 5xxx .*ATI.*FireGL V5.* 3 -ATI FireGL .*ATI.*Fire.*GL.* 0 -ATI FireMV .*ATI.*FireMV.* 0 -ATI Generic .*ATI.*Generic.* 0 -ATI Radeon 7000 .*ATI.*Radeon 7.* 0 -ATI Radeon 8000 .*ATI.*Radeon 8.* 0 -ATI Radeon 9000 .*ATI.*Radeon 90.* 1 -ATI Radeon 9100 .*ATI.*Radeon 91.* 1 -ATI Radeon 9200 .*ATI.*Radeon 92.* 1 -ATI Radeon 9500 .*ATI.*Radeon 95.* 1 -ATI Radeon 9600 .*ATI.*Radeon 96.* 1 -ATI Radeon 9700 .*ATI.*Radeon 97.* 1 -ATI Radeon 9800 .*ATI.*Radeon 98.* 1 -ATI Radeon X1300 .*ATI.*Radeon X13.* 3 -ATI Radeon X1400 .*ATI.*Radeon X14.* 3 -ATI Radeon X1500 .*ATI.*Radeon X15.* 3 -ATI Radeon X1600 .*ATI.*Radeon X16.* 3 -ATI Radeon X1700 .*ATI.*Radeon X17.* 3 -ATI Radeon X1800 .*ATI.*Radeon X18.* 3 -ATI Radeon X1900 .*ATI.*Radeon X19.* 3 -ATI Radeon X2400 .*ATI.*Radeon X24.* 3 -ATI Radeon X2600 .*ATI.*Radeon X26.* 3 -ATI Radeon X2900 .*ATI.*Radeon X29.* 3 -ATI Radeon X300 .*ATI.*Radeon X3.* 2 -ATI Radeon X400 .*ATI.*Radeon X4.* 2 -ATI Radeon X500 .*ATI.*Radeon X5.* 2 -ATI Radeon X600 .*ATI.*Radeon X6.* 2 -ATI Radeon X700 .*ATI.*Radeon X7.* 2 -ATI Radeon X800 .*ATI.*Radeon X8.* 2 -ATI Radeon X900 .*ATI.*Radeon X9.* 2 -ATI Radeon Xpress .*ATI.*Radeon Xpress.* 1 -ATI Rage 128 .*ATI.*Rage 128.* 0 -Intel 830M .*Intel.*830M 0 -Intel 845G .*Intel.*845G 0 -Intel 855GM .*Intel.*855GM 0 -Intel 865G .*Intel.*865G 0 -Intel 900 .*Intel.*900.*900 0 -Intel 915G .*Intel.*915G 0 -Intel 915GM .*Intel.*915GM 0 -Intel 945G .*Intel.*945G 0 -Intel 945GM .*Intel.*945GM 0 -Intel 950 .*Intel.*950.*950 0 -Intel G965 .*Intel.*G965.* 0 -Intel GM965 .*Intel.*GM965.* 0 -Intel G33 .*Intel.*G33.* 0 -Intel Brookdale .*Intel.*Brookdale.* 0 -Intel Montara .*Intel.*Montara.* 0 -Intel Springdale .*Intel.*Springdale.* 0 -Matrox .*Matrox.* 0 -NVIDIA GeForce .*GeForce 256.* 0 -NVIDIA GeForce 2 .*GeForce2.* 0 -NVIDIA GeForce 3 .*GeForce3.* 0 -NVIDIA GeForce 4 Go .*NVIDIA.*GeForce4.*Go.* 0 -NVIDIA GeForce 4 MX .*NVIDIA.*GeForce4 MX.* 0 -NVIDIA GeForce 4 Ti .*NVIDIA.*GeForce4 Ti.* 0 -NVIDIA GeForce 6100 .*NVIDIA.*GeForce 61.* 2 -NVIDIA GeForce 6200 .*NVIDIA.*GeForce 62.* 2 -NVIDIA GeForce 6500 .*NVIDIA.*GeForce 65.* 2 -NVIDIA GeForce 6600 .*NVIDIA.*GeForce 66.* 2 -NVIDIA GeForce 6700 .*NVIDIA.*GeForce 67.* 2 -NVIDIA GeForce 6800 .*NVIDIA.*GeForce 68.* 2 -NVIDIA GeForce 7300 .*NVIDIA.*GeForce 73.* 3 -NVIDIA GeForce 7600 .*NVIDIA.*GeForce 76.* 3 -NVIDIA GeForce 7800 .*NVIDIA.*GeForce 78.* 3 -NVIDIA GeForce 7900 .*NVIDIA.*GeForce 79.* 3 -NVIDIA GeForce 8800 .*NVIDIA.*GeForce 88.* 3 -NVIDIA GeForce FX 5100 .*NVIDIA.*GeForce FX 51.* 1 -NVIDIA GeForce FX 5200 .*NVIDIA.*GeForce FX 52.* 1 -NVIDIA GeForce FX 5500 .*NVIDIA.*GeForce FX 55.* 1 -NVIDIA GeForce FX 5600 .*NVIDIA.*GeForce FX 56.* 1 -NVIDIA GeForce FX 5700 .*NVIDIA.*GeForce FX 57.* 1 -NVIDIA GeForce FX 5800 .*NVIDIA.*GeForce FX 58.* 1 -NVIDIA GeForce FX 5900 .*NVIDIA.*GeForce FX 59.* 1 -NVIDIA GeForce FX Go5100 .*NVIDIA.*GeForce FX Go51.* 1 -NVIDIA GeForce FX Go5200 .*NVIDIA.*GeForce FX Go52.* 1 -NVIDIA GeForce FX Go5300 .*NVIDIA.*GeForce FX Go53.* 1 -NVIDIA GeForce FX Go5500 .*NVIDIA.*GeForce FX Go55.* 1 -NVIDIA GeForce FX Go5600 .*NVIDIA.*GeForce FX Go56.* 1 -NVIDIA GeForce FX Go5700 .*NVIDIA.*GeForce FX Go57.* 1 -NVIDIA GeForce FX Go5800 .*NVIDIA.*GeForce FX Go58.* 1 -NVIDIA GeForce FX Go5900 .*NVIDIA.*GeForce FX Go59.* 1 -NVIDIA GeForce Go 6100 .*NVIDIA.*GeForce Go 61.* 2 -NVIDIA GeForce Go 6200 .*NVIDIA.*GeForce Go 62.* 2 -NVIDIA GeForce Go 6500 .*NVIDIA.*GeForce Go 65.* 2 -NVIDIA GeForce Go 6600 .*NVIDIA.*GeForce Go 66.* 2 -NVIDIA GeForce Go 6700 .*NVIDIA.*GeForce Go 67.* 2 -NVIDIA GeForce Go 6800 .*NVIDIA.*GeForce Go 68.* 2 -NVIDIA GeForce Go 7300 .*NVIDIA.*GeForce Go 73.* 3 -NVIDIA GeForce Go 7400 .*NVIDIA.*GeForce Go 74.* 3 -NVIDIA GeForce Go 7600 .*NVIDIA.*GeForce Go 76.* 3 -NVIDIA GeForce Go 7700 .*NVIDIA.*GeForce Go 77.* 3 -NVIDIA GeForce Go 7800 .*NVIDIA.*GeForce Go 78.* 3 -NVIDIA GeForce Go 7900 .*NVIDIA.*GeForce Go 79.* 3 -NVIDIA GeForce Go 6 .*GeForce Go 6.* 2 -NVIDIA GeForce PCX .*GeForce PCX.* 1 -NVIDIA Generic .*NVIDIA.*NV.* 0 -NVIDIA Generic .*NVIDIA.*Unknown.* 0 -NVIDIA Quadro 2 .*Quadro2.* 0 -NVIDIA Quadro 4 .*Quadro4.* 0 -NVIDIA Quadro DCC .*Quadro DCC.* 0 -NVIDIA Quadro FX .*Quadro FX.* 1 -NVIDIA Quadro NVS .*Quadro NVS.* 0 -NVIDIA RIVA TNT .*RIVA TNT.* 0 -S3 .*S3 Graphics.* 0 -SiS SiS.* 0 -Trident Trident.* 0 -Tungsten Graphics Tungsten.* 0 -XGI XGI.* 0 +3Dfx .*3Dfx.* 0 0 +3Dlabs .*3Dlabs.* 0 0 +ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 +ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 +ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1 +ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 2 1 +ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 +ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 +ATI ASUS A9xxx .*ATI.*ASUS.*A9.* 1 1 +ATI ASUS AH24xx .*ATI.*ASUS.*AH24.* 1 1 +ATI ASUS AH26xx .*ATI.*ASUS.*AH26.* 3 1 +ATI ASUS AX3xx .*ATI.*ASUS.*AX3.* 1 1 +ATI ASUS AX5xx .*ATI.*ASUS.*AX5.* 1 1 +ATI ASUS AX8xx .*ATI.*ASUS.*AX8.* 2 1 +ATI ASUS EAH38xx .*ATI.*ASUS.*EAH38.* 3 1 +ATI ASUS EAH24xx .*ATI.*ASUS.*EAH24.* 2 1 +ATI ASUS EAH26xx .*ATI.*ASUS.*EAH26.* 3 1 +ATI ASUS X1xxx .*ATI.*ASUS.*X1.* 2 1 +ATI Diamond X1xxx .*ATI.*Diamond.*X1.* 3 1 +ATI Diamond X550 .*ATI.*Diamond X550.* 1 1 +ATI FireGL 5xxx .*ATI.*FireGL V5.* 1 0 +ATI FireGL .*ATI.*Fire.*GL.* 0 0 +ATI FireMV .*ATI.*FireMV.* 0 0 +ATI Generic .*ATI.*Generic.* 0 0 +ATI Hercules 9800 .*ATI.*Hercules.*9800.* 1 1 +ATI IGP 340M .*ATI.*IGP.*340M.* 0 0 +ATI M52 .*ATI.*M52.* 1 1 +ATI Mobility Radeon 9800 .*ATI.*Mobility.*98.* 1 1 +ATI Mobility Radeon 9700 .*ATI.*Mobility.*97.* 1 1 +ATI Mobility Radeon 9600 .*ATI.*Mobility.*96.* 0 1 +ATI Mobility Radeon X1xxx .*ATI.*Mobility.*X1.* 1 1 +ATI Mobility Radeon X2xxx .*ATI.*Mobility.*X2.* 1 1 +ATI Mobility Radeon X3xx .*ATI.*Mobility.*X3.* 1 1 +ATI Mobility Radeon X6xx .*ATI.*Mobility.*X6.* 1 1 +ATI Mobility Radeon X7xx .*ATI.*Mobility.*X7.* 1 1 +ATI Mobility Radeon Xxxx .*ATI.*Mobility.*X.* 1 1 +ATI Mobility Radeon .*ATI.*Mobility.* 0 1 +ATI Radeon HD 2300 .*ATI.*Radeon HD 23.* 1 1 +ATI Radeon HD 2400 .*ATI.*Radeon HD 24.* 1 1 +ATI Radeon HD 2600 .*ATI.*Radeon HD 26.* 2 1 +ATI Radeon HD 2900 .*ATI.*Radeon HD 29.* 3 1 +ATI Radeon HD 3800 .*ATI.*Radeon HD 38.* 3 1 +ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 +ATI Radeon 7000 .*ATI.*Radeon 7.* 0 1 +ATI Radeon 8000 .*ATI.*Radeon 8.* 0 1 +ATI Radeon 9000 .*ATI.*Radeon 90.* 0 1 +ATI Radeon 9100 .*ATI.*Radeon 91.* 0 1 +ATI Radeon 9200 .*ATI.*Radeon 92.* 0 1 +ATI Radeon 9500 .*ATI.*Radeon 95.* 0 1 +ATI Radeon 9600 .*ATI.*Radeon 96.* 0 1 +ATI Radeon 9700 .*ATI.*Radeon 97.* 1 1 +ATI Radeon 9800 .*ATI.*Radeon 98.* 1 1 +ATI Radeon RV250 .*ATI.*RV250.* 0 1 +ATI Radeon RX700 .*ATI.*RX70.* 1 1 +ATI Radeon RX800 .*ATI.*Radeon *RX80.* 2 1 +ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 +ATI Radeon X1000 .*ATI.*Radeon *X10.* 0 1 +ATI Radeon X1200 .*ATI.*Radeon *X12.* 0 1 +ATI Radeon X1300 .*ATI.*Radeon *X13.* 1 1 +ATI Radeon X1400 .*ATI.*Radeon X14.* 1 1 +ATI Radeon X1500 .*ATI.*Radeon X15.* 1 1 +ATI Radeon X1600 .*ATI.*Radeon X16.* 1 1 +ATI Radeon X1700 .*ATI.*Radeon X17.* 1 1 +ATI Radeon X1800 .*ATI.*Radeon X18.* 3 1 +ATI Radeon X1900 .*ATI.*Radeon X19.* 3 1 +ATI Radeon X300 .*ATI.*Radeon *X3.* 1 1 +ATI Radeon X400 .*ATI.*Radeon X4.* 1 1 +ATI Radeon X500 .*ATI.*Radeon X5.* 1 1 +ATI Radeon X600 .*ATI.*Radeon X6.* 1 1 +ATI Radeon X700 .*ATI.*Radeon X7.* 1 1 +ATI Radeon X800 .*ATI.*Radeon X8.* 2 1 +ATI Radeon X900 .*ATI.*Radeon X9.* 2 1 +ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 0 +ATI Rage 128 .*ATI.*Rage 128.* 0 1 +ATI RV250 .*ATI.*RV250.* 0 1 +ATI RV530 .*ATI.*RV530.* 1 1 +ATI RX700 .*ATI.*RX700.* 1 1 +Intel X3100 .*Intel.*X3100.* 1 1 +Intel 830M .*Intel.*830M 0 0 +Intel 845G .*Intel.*845G 0 0 +Intel 855GM .*Intel.*855GM 0 0 +Intel 865G .*Intel.*865G 0 0 +Intel 900 .*Intel.*900.*900 0 0 +Intel 915GM .*Intel.*915GM 0 0 +Intel 915G .*Intel.*915G 0 0 +Intel 945GM .*Intel.*945GM 0 1 +Intel 945G .*Intel.*945G 0 1 +Intel 950 .*Intel.*950.* 0 1 +Intel 965 .*Intel.*965.* 0 1 +Intel G33 .*Intel.*G33.* 0 0 +Intel Bear Lake .*Intel.*Bear Lake.* 0 0 +Intel Broadwater .*Intel.*Broadwater.* 0 0 +Intel Brookdale .*Intel.*Brookdale.* 0 0 +Intel Montara .*Intel.*Montara.* 0 0 +Intel Springdale .*Intel.*Springdale.* 0 0 +Matrox .*Matrox.* 0 0 +Mesa .*Mesa.* 0 0 +NVIDIA G72 .*NVIDIA.*G72.* 1 1 +NVIDIA G73 .*NVIDIA.*G73.* 1 1 +NVIDIA GeForce .*GeForce 256.* 0 0 +NVIDIA GeForce 2 .*GeForce2.* 0 1 +NVIDIA GeForce 3 .*GeForce3.* 0 1 +NVIDIA GeForce 4 Go .*NVIDIA.*GeForce4.*Go.* 0 1 +NVIDIA GeForce 4 MX .*NVIDIA.*GeForce4 MX.* 0 1 +NVIDIA GeForce 4 Ti .*NVIDIA.*GeForce4 Ti.* 0 1 +NVIDIA GeForce 6100 .*NVIDIA.*GeForce 61.* 0 1 +NVIDIA GeForce 6200 .*NVIDIA.*GeForce 62.* 0 1 +NVIDIA GeForce 6500 .*NVIDIA.*GeForce 65.* 1 1 +NVIDIA GeForce 6600 .*NVIDIA.*GeForce 66.* 1 1 +NVIDIA GeForce 6700 .*NVIDIA.*GeForce 67.* 2 1 +NVIDIA GeForce 6800 .*NVIDIA.*GeForce 68.* 2 1 +NVIDIA GeForce 7000 .*NVIDIA.*GeForce 70.* 0 1 +NVIDIA GeForce 7100 .*NVIDIA.*GeForce 71.* 0 1 +NVIDIA GeForce 7200 .*NVIDIA.*GeForce 72.* 1 1 +NVIDIA GeForce 7300 .*NVIDIA.*GeForce 73.* 1 1 +NVIDIA GeForce 7500 .*NVIDIA.*GeForce 75.* 1 1 +NVIDIA GeForce 7600 .*NVIDIA.*GeForce 76.* 2 1 +NVIDIA GeForce 7800 .*NVIDIA.*GeForce 78.* 2 1 +NVIDIA GeForce 7900 .*NVIDIA.*GeForce 79.* 2 1 +NVIDIA GeForce 8300 .*NVIDIA.*GeForce 83.* 1 1 +NVIDIA GeForce 8400 .*NVIDIA.*GeForce 84.* 1 1 +NVIDIA GeForce 8500 .*NVIDIA.*GeForce 85.* 3 1 +NVIDIA GeForce 8600 .*NVIDIA.*GeForce 86.* 3 1 +NVIDIA GeForce 8700 .*NVIDIA.*GeForce 87.* 3 1 +NVIDIA GeForce 8800 .*NVIDIA.*GeForce 88.* 3 1 +NVIDIA GeForce FX 5100 .*NVIDIA.*GeForce FX 51.* 0 1 +NVIDIA GeForce FX 5200 .*NVIDIA.*GeForce FX 52.* 0 1 +NVIDIA GeForce FX 5500 .*NVIDIA.*GeForce FX 55.* 0 1 +NVIDIA GeForce FX 5600 .*NVIDIA.*GeForce FX 56.* 1 1 +NVIDIA GeForce FX 5700 .*NVIDIA.*GeForce FX 57.* 1 1 +NVIDIA GeForce FX 5800 .*NVIDIA.*GeForce FX 58.* 1 1 +NVIDIA GeForce FX 5900 .*NVIDIA.*GeForce FX 59.* 1 1 +NVIDIA GeForce FX Go5100 .*NVIDIA.*GeForce FX Go51.* 0 1 +NVIDIA GeForce FX Go5200 .*NVIDIA.*GeForce FX Go52.* 0 1 +NVIDIA GeForce FX Go5300 .*NVIDIA.*GeForce FX Go53.* 0 1 +NVIDIA GeForce FX Go5500 .*NVIDIA.*GeForce FX Go55.* 0 1 +NVIDIA GeForce FX Go5600 .*NVIDIA.*GeForce FX Go56.* 0 1 +NVIDIA GeForce FX Go5700 .*NVIDIA.*GeForce FX Go57.* 1 1 +NVIDIA GeForce FX Go5800 .*NVIDIA.*GeForce FX Go58.* 1 1 +NVIDIA GeForce FX Go5900 .*NVIDIA.*GeForce FX Go59.* 1 1 +NVIDIA GeForce Go 6100 .*NVIDIA.*GeForce Go 61.* 0 1 +NVIDIA GeForce Go 6200 .*NVIDIA.*GeForce Go 62.* 0 1 +NVIDIA GeForce Go 6500 .*NVIDIA.*GeForce Go 65.* 1 1 +NVIDIA GeForce Go 6600 .*NVIDIA.*GeForce Go 66.* 1 1 +NVIDIA GeForce Go 6700 .*NVIDIA.*GeForce Go 67.* 1 1 +NVIDIA GeForce Go 6800 .*NVIDIA.*GeForce Go 68.* 1 1 +NVIDIA GeForce Go 7200 .*NVIDIA.*GeForce Go 72.* 1 1 +NVIDIA GeForce Go 7300 .*NVIDIA.*GeForce Go 73.* 1 1 +NVIDIA GeForce Go 7400 .*NVIDIA.*GeForce Go 74.* 1 1 +NVIDIA GeForce Go 7600 .*NVIDIA.*GeForce Go 76.* 2 1 +NVIDIA GeForce Go 7700 .*NVIDIA.*GeForce Go 77.* 2 1 +NVIDIA GeForce Go 7800 .*NVIDIA.*GeForce Go 78.* 2 1 +NVIDIA GeForce Go 7900 .*NVIDIA.*GeForce Go 79.* 2 1 +NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 +NVIDIA GeForce PCX .*GeForce PCX.* 0 1 +NVIDIA Generic .*NVIDIA.*Unknown.* 0 0 +NVIDIA NV43 .*NVIDIA.*NV43.* 1 1 +NVIDIA Quadro2 .*Quadro2.* 0 0 +NVIDIA Quadro4 .*Quadro4.* 0 0 +NVIDIA Quadro DCC .*Quadro DCC.* 0 0 +NVIDIA Quadro FX .*Quadro FX.* 1 0 +NVIDIA Quadro NVS .*Quadro NVS.* 0 0 +NVIDIA RIVA TNT .*RIVA TNT.* 0 0 +S3 .*S3 Graphics.* 0 0 +SiS SiS.* 0 0 +Trident Trident.* 0 0 +Tungsten Graphics Tungsten.* 0 0 +XGI XGI.* 0 0 +VIA VIA.* 0 0 + diff --git a/linden/indra/newview/installers/windows/installer_template.nsi b/linden/indra/newview/installers/windows/installer_template.nsi index 7a225fa..fa94a09 100644 --- a/linden/indra/newview/installers/windows/installer_template.nsi +++ b/linden/indra/newview/installers/windows/installer_template.nsi @@ -1,938 +1,956 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; secondlife setup.nsi -;; Copyright 2004-2007, Linden Research, Inc. -;; For info, see http://www.nullsoft.com/free/nsis/ -;; -;; NSIS 2.22 or higher required -;; Author: James Cook, Don Kjer, Callum Prentice -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Detect NSIS compiler version -!define "NSIS${NSIS_VERSION}" -!ifdef "NSISv2.02" | "NSISv2.03" | "NSISv2.04" | "NSISv2.05" | "NSISv2.06" - ;; before 2.07 defaulted lzma to solid (whole file) - SetCompressor lzma -!else - ;; after 2.07 required /solid for whole file compression - SetCompressor /solid lzma -!endif - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Compiler flags -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -SetOverwrite on ; overwrite files -SetCompress auto ; compress iff saves space -SetDatablockOptimize off ; only saves us 0.1%, not worth it -XPStyle on ; add an XP manifest to the installer - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Project flags -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -%%VERSION%% - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; - language files - one for each language (or flavor thereof) -;; (these files are in the same place as the nsi template but the python script generates a new nsi file in the -;; application directory so we have to add a path to these include files) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -!include "installers\windows\lang_de.nsi" -!include "installers\windows\lang_en-us.nsi" -!include "installers\windows\lang_ja.nsi" -!include "installers\windows\lang_ko.nsi" - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Tweak for different servers/builds (this placeholder is replaced by viewer_manifest.py) -%%GRID_VARS%% - -Name ${INSTNAME} - -SubCaption 0 $(LicenseSubTitleSetup) ; override "license agreement" text - -BrandingText " " ; bottom of window text -Icon res\install_icon.ico ; our custom icon -UninstallIcon res\uninstall_icon.ico ; our custom icon -WindowIcon on ; show our icon in left corner -BGGradient off ; no big background window -CRCCheck on ; make sure CRC is OK -InstProgressFlags smooth colored ; new colored smooth look -ShowInstDetails nevershow ; no details, no "show" button -SetOverwrite on ; stomp files by default -AutoCloseWindow true ; after all files install, close window - -!ifdef UPDATE -LicenseText $(LicenseDescUpdate) $(LicenseDescNext) -!else -LicenseText $(LicenseDescSetup) $(LicenseDescNext) -!endif - -LicenseData "releasenotes.txt" - -InstallDir "$PROGRAMFILES\${INSTNAME}" -InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "" -!ifdef UPDATE -DirText $(DirectoryChooseTitle) $(DirectoryChooseUpdate) -!else -DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup) -!endif - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Variables -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Var INSTPROG -Var INSTEXE -Var INSTFLAGS -Var LANGFLAGS -Var INSTSHORTCUT - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Sections -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Section "" ; (default section) - -SetShellVarContext all ; install for all users (if you change this, change it in the uninstall as well) - -; Start with some default values. -StrCpy $INSTFLAGS "${INSTFLAGS}" -StrCpy $INSTFLAGS "$INSTFLAGS $LANGFLAGS" -StrCpy $INSTPROG "${INSTNAME}" -StrCpy $INSTEXE "${INSTEXE}" -StrCpy $INSTSHORTCUT "${SHORTCUT}" - -IfSilent +2 -Goto NOT_SILENT - Call CheckStartupParams ; Figure out where, what and how to install. -NOT_SILENT: -Call CheckWindowsVersion ; warn if on Windows 98/ME -Call CheckIfAdministrator ; Make sure the user can install/uninstall -Call CheckIfAlreadyCurrent ; Make sure that we haven't already installed this version -Call CloseSecondLife ; Make sure we're not running -Call RemoveNSIS ; Check for old NSIS install to remove - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Don't remove cache files during a regular install, removing the inventory cache on upgrades results in lots of damage to the servers. -;Call RemoveCacheFiles ; Installing over removes potentially corrupted - ; VFS and cache files. - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Files -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py -%%INSTALL_FILES%% - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; If this is a silent update, we don't need to re-create these shortcuts or registry entries. -IfSilent POST_INSTALL - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Shortcuts in start menu -CreateDirectory "$SMPROGRAMS\$INSTSHORTCUT" -SetOutPath "$INSTDIR" -CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \ - "$INSTDIR\$INSTEXE" "$INSTFLAGS" - -!ifdef MUSEUM -CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT Museum.lnk" \ - - "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple" -CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT Museum Spanish.lnk" \ - - "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple -spanish" -!endif - -WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Create Trial Account.url" \ - "InternetShortcut" "URL" \ - "http://www.secondlife.com/registration/" -WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Your Account.url" \ - "InternetShortcut" "URL" \ - "http://www.secondlife.com/account/" -CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk" \ - "$INSTDIR\releasenotes.txt" -CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\SL Scripting Language Help.lnk" \ - "$INSTDIR\lsl_guide.html" -CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\Uninstall $INSTSHORTCUT.lnk" \ - '"$INSTDIR\uninst.exe"' '/P="$INSTPROG"' - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Other shortcuts -SetOutPath "$INSTDIR" -CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS" -CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS" -CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \ - '"$INSTDIR\uninst.exe"' '/P="$INSTPROG"' - -!ifdef MUSEUM -CreateShortCut "$DESKTOP\$INSTSHORTCUT Museum.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple" - -CreateShortCut "$DESKTOP\$INSTSHORTCUT Museum Spanish.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple -spanish" - -CreateShortCut "$INSTDIR\$INSTSHORTCUT Museum.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple" - -CreateShortCut "$INSTDIR\$INSTSHORTCUT Museum Spanish.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple -spanish" - -!endif - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Write registry -WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" "$INSTDIR" -WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" "${VERSION_LONG}" -WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Flags" "$INSTFLAGS" -WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" "$INSTSHORTCUT" -WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" "$INSTEXE" -WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayName" "$INSTPROG (remove only)" -WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "UninstallString" '"$INSTDIR\uninst.exe" /P="$INSTPROG"' - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Write URL registry info -WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "(default)" "URL:Second Life" -WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "URL Protocol" "" -WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\DefaultIcon" "" '"$INSTDIR\$INSTEXE"' -WriteRegExpandStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open\command" "" '"$INSTDIR\$INSTEXE" $INSTFLAGS -url "%1"' - -Goto WRITE_UNINST - -POST_INSTALL: -; Run a post-executable script if necessary. -Call PostInstallExe - -WRITE_UNINST: -; write out uninstaller -WriteUninstaller "$INSTDIR\uninst.exe" - -; end of default section -SectionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; PostInstallExe -; This just runs any post installation scripts. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function PostInstallExe -push $0 - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "PostInstallExe" - ;MessageBox MB_OK '$0' - ExecWait '$0' -pop $0 -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; CheckStartupParameters -; Sets INSTFLAGS, INSTPROG, and INSTEXE. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function CheckStartupParams -push $0 -push $R0 - - ; Look for a registry entry with info about where to update. - Call GetProgramName - pop $R0 - StrCpy $INSTPROG "$R0" - StrCpy $INSTEXE "$R0.exe" - - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" - ; If key doesn't exist, skip install - IfErrors ABORT - StrCpy $INSTDIR "$0" - - ; We now have a directory to install to. Get the startup parameters and shortcut as well. - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Flags" - IfErrors +2 - StrCpy $INSTFLAGS "$0" - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" - IfErrors +2 - StrCpy $INSTSHORTCUT "$0" - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" - IfErrors +2 - StrCpy $INSTEXE "$0" - Goto FINISHED - -ABORT: - MessageBox MB_OK $(CheckStartupParamsMB) - Quit - -FINISHED: - ;MessageBox MB_OK "INSTPROG: $INSTPROG, INSTEXE: $INSTEXE, INSTFLAGS: $INSTFLAGS" -pop $R0 -pop $0 -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function un.CheckStartupParams -push $0 -push $R0 - - ; Look for a registry entry with info about where to update. - Call un.GetProgramName - pop $R0 - StrCpy $INSTPROG "$R0" - StrCpy $INSTEXE "$R0.exe" - - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" - ; If key doesn't exist, skip install - IfErrors ABORT - StrCpy $INSTDIR "$0" - - ; We now have a directory to install to. Get the startup parameters and shortcut as well. - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Flags" - IfErrors +2 - StrCpy $INSTFLAGS "$0" - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" - IfErrors +2 - StrCpy $INSTSHORTCUT "$0" - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" - IfErrors +2 - StrCpy $INSTEXE "$0" - Goto FINISHED - -ABORT: - MessageBox MB_OK $(CheckStartupParamsMB) - Quit - -FINISHED: - ;MessageBox MB_OK "INSTPROG: $INSTPROG, INSTEXE: $INSTEXE, INSTFLAGS: $INSTFLAGS" -pop $R0 -pop $0 -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; After install completes, offer readme file -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function .onInstSuccess - MessageBox MB_YESNO \ - $(InstSuccesssQuestion) /SD IDYES IDNO NoReadme - ; Assumes SetOutPath $INSTDIR - Exec '"$INSTDIR\$INSTEXE" $INSTFLAGS' - NoReadme: -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Remove old NSIS version. Modifies no variables. -; Does NOT delete the LindenWorld directory, or any -; user files in that directory. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function RemoveNSIS - Push $0 - ; Grab the installation directory of the old version - DetailPrint $(RemoveOldNSISVersion) - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" - - ; If key doesn't exist, skip uninstall - IfErrors NO_NSIS - - ; Clean up legacy beta shortcuts - Delete "$SMPROGRAMS\Second Life Beta.lnk" - Delete "$DESKTOP\Second Life Beta.lnk" - Delete "$SMPROGRAMS\Second Life.lnk" - - ; Clean up old newview.exe file - Delete "$INSTDIR\newview.exe" - - ; Intentionally don't delete the stuff in - ; Documents and Settings, so we keep the user's settings - - NO_NSIS: - Pop $0 -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Make sure we're not on Windows 98 / ME -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function CheckWindowsVersion - DetailPrint "Checking Windows version..." - Call GetWindowsVersion - Pop $R0 - ; Just get first two characters, ignore 4.0 part of "NT 4.0" - StrCpy $R0 $R0 2 - ; Blacklist certain OS versions - StrCmp $R0 "95" win_ver_bad - StrCmp $R0 "98" win_ver_bad - StrCmp $R0 "ME" win_ver_bad - StrCmp $R0 "NT" win_ver_bad - Return -win_ver_bad: - MessageBox MB_YESNO $(CheckWindowsVersionMB) IDNO win_ver_abort - Return -win_ver_abort: - Quit -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Make sure the user can install/uninstall -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function CheckIfAdministrator - DetailPrint $(CheckAdministratorInstDP) - UserInfo::GetAccountType - Pop $R0 - StrCmp $R0 "Admin" is_admin - MessageBox MB_OK $(CheckAdministratorInstMB) - Quit -is_admin: - Return -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function un.CheckIfAdministrator - DetailPrint $(CheckAdministratorUnInstDP) - UserInfo::GetAccountType - Pop $R0 - StrCmp $R0 "Admin" is_admin - MessageBox MB_OK $(CheckAdministratorUnInstMB) - Quit -is_admin: - Return -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Checks to see if the current version has already been installed (according to the registry). -; If it has, allow user to bail out of install process. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function CheckIfAlreadyCurrent - Push $0 - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" - StrCmp $0 ${VERSION_LONG} 0 DONE - MessageBox MB_OKCANCEL $(CheckIfCurrentMB) /SD IDOK IDOK DONE - Quit - - DONE: - Pop $0 - Return -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Close the program, if running. Modifies no variables. -; Allows user to bail out of install process. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function CloseSecondLife - Push $0 - FindWindow $0 "Second Life" "" - IntCmp $0 0 DONE - MessageBox MB_OKCANCEL $(CloseSecondLifeInstMB) IDOK CLOSE IDCANCEL CANCEL_INSTALL - - CANCEL_INSTALL: - Quit - - CLOSE: - DetailPrint $(CloseSecondLifeInstDP) - SendMessage $0 16 0 0 - - LOOP: - FindWindow $0 "Second Life" "" - IntCmp $0 0 DONE - Sleep 500 - Goto LOOP - - DONE: - Pop $0 - Return -FunctionEnd - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Delete files in Documents and Settings\\SecondLife\cache -; Delete files in Documents and Settings\All Users\SecondLife\cache -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;Function RemoveCacheFiles -; -;; Delete files in Documents and Settings\\SecondLife -;Push $0 -;Push $1 -;Push $2 -; DetailPrint $(RemoveCacheFilesDP) -; -; StrCpy $0 0 ; Index number used to iterate via EnumRegKey -; -; LOOP: -; EnumRegKey $1 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $0 -; StrCmp $1 "" DONE ; no more users -; -; ReadRegStr $2 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$1" "ProfileImagePath" -; StrCmp $2 "" CONTINUE 0 ; "ProfileImagePath" value is missing -; -; ; Required since ProfileImagePath is of type REG_EXPAND_SZ -; ExpandEnvStrings $2 $2 -; -; ; When explicitly uninstalling, everything goes away -; RMDir /r "$2\Application Data\SecondLife\cache" -; -; CONTINUE: -; IntOp $0 $0 + 1 -; Goto LOOP -; DONE: -;Pop $2 -;Pop $1 -;Pop $0 -; -;; Delete files in Documents and Settings\All Users\SecondLife -;Push $0 -; ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" "Common AppData" -; StrCmp $0 "" +2 -; RMDir /r "$0\SecondLife\cache" -;Pop $0 -; -;; Delete filse in C:\Windows\Application Data\SecondLife -;; If the user is running on a pre-NT system, Application Data lives here instead of -;; in Documents and Settings. -;RMDir /r "$WINDIR\Application Data\SecondLife\cache" -; -;FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Delete files in Documents and Settings\\SecondLife -; Delete files in Documents and Settings\All Users\SecondLife -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function un.DocumentsAndSettingsFolder - -; Delete files in Documents and Settings\\SecondLife -Push $0 -Push $1 -Push $2 - - DetailPrint "Deleting files in Documents and Settings folder" - - StrCpy $0 0 ; Index number used to iterate via EnumRegKey - - LOOP: - EnumRegKey $1 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $0 - StrCmp $1 "" DONE ; no more users - - ReadRegStr $2 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$1" "ProfileImagePath" - StrCmp $2 "" CONTINUE 0 ; "ProfileImagePath" value is missing - - ; Required since ProfileImagePath is of type REG_EXPAND_SZ - ExpandEnvStrings $2 $2 - - ; If uninstalling a normal install remove everything - ; Otherwise (preview/dmz etc) just remove cache - StrCmp $INSTFLAGS "" RM_ALL RM_CACHE - RM_ALL: - RMDir /r "$2\Application Data\SecondLife" - GoTo CONTINUE - RM_CACHE: - RMDir /r "$2\Application Data\SecondLife\Cache" - - CONTINUE: - IntOp $0 $0 + 1 - Goto LOOP - DONE: - -Pop $2 -Pop $1 -Pop $0 - -; Delete files in Documents and Settings\All Users\SecondLife -Push $0 - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" "Common AppData" - StrCmp $0 "" +2 - RMDir /r "$0\SecondLife" -Pop $0 - -; Delete filse in C:\Windows\Application Data\SecondLife -; If the user is running on a pre-NT system, Application Data lives here instead of -; in Documents and Settings. -RMDir /r "$WINDIR\Application Data\SecondLife" - -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Close the program, if running. Modifies no variables. -; Allows user to bail out of uninstall process. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function un.CloseSecondLife - Push $0 - FindWindow $0 "Second Life" "" - IntCmp $0 0 DONE - MessageBox MB_OKCANCEL $(CloseSecondLifeUnInstMB) IDOK CLOSE IDCANCEL CANCEL_UNINSTALL - - CANCEL_UNINSTALL: - Quit - - CLOSE: - DetailPrint $(CloseSecondLifeUnInstDP) - SendMessage $0 16 0 0 - - LOOP: - FindWindow $0 "Second Life" "" - IntCmp $0 0 DONE - Sleep 500 - Goto LOOP - - DONE: - Pop $0 - Return -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Delete the installed files -;;; This deletes the uninstall executable, but it works -;;; because it is copied to temp directory before running -;;; -;;; Note: You must list all files here, because we only -;;; want to delete our files, not things users left in the -;;; application directories. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function un.ProgramFiles - -;; Remove mozilla file first so recursive directory deletion doesn't get hung up -Delete "$INSTDIR\app_settings\mozilla\components" - -;; This placeholder is replaced by the complete list of files to uninstall by viewer_manifest.py -%%DELETE_FILES%% - -;; Optional/obsolete files. Delete won't fail if they don't exist. -Delete "$INSTDIR\dronesettings.ini" -Delete "$INSTDIR\message_template.msg" -Delete "$INSTDIR\newview.pdb" -Delete "$INSTDIR\newview.map" -Delete "$INSTDIR\SecondLife.pdb" -Delete "$INSTDIR\SecondLife.map" -Delete "$INSTDIR\comm.dat" -Delete "$INSTDIR\*.glsl" -Delete "$INSTDIR\motions\*.lla" -Delete "$INSTDIR\trial\*.html" -Delete "$INSTDIR\newview.exe" -;; Remove entire help directory -Delete "$INSTDIR\help\Advanced\*" -RMDir "$INSTDIR\help\Advanced" -Delete "$INSTDIR\help\basics\*" -RMDir "$INSTDIR\help\basics" -Delete "$INSTDIR\help\Concepts\*" -RMDir "$INSTDIR\help\Concepts" -Delete "$INSTDIR\help\welcome\*" -RMDir "$INSTDIR\help\welcome" -Delete "$INSTDIR\help\*" -RMDir "$INSTDIR\help" - -Delete "$INSTDIR\uninst.exe" -RMDir "$INSTDIR" - -IfFileExists "$INSTDIR" FOLDERFOUND NOFOLDER - -FOLDERFOUND: - MessageBox MB_YESNO $(DeleteProgramFilesMB) IDNO NOFOLDER - RMDir /r "$INSTDIR" - -NOFOLDER: - -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Uninstall settings -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -UninstallText $(UninstallTextMsg) -ShowUninstDetails show - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Uninstall section -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Section Uninstall - -; Start with some default values. -StrCpy $INSTFLAGS "" -StrCpy $INSTPROG "${INSTNAME}" -StrCpy $INSTEXE "${INSTEXE}" -StrCpy $INSTSHORTCUT "${SHORTCUT}" -Call un.CheckStartupParams ; Figure out where, what and how to uninstall. -Call un.CheckIfAdministrator ; Make sure the user can install/uninstall - -; uninstall for all users (if you change this, change it in the install as well) -SetShellVarContext all - -; Make sure we're not running -Call un.CloseSecondLife - -; Clean up registry keys (these should all be !defines somewhere) -DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" -DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" -DeleteRegKey HKEY_LOCAL_MACHINE "Software\Linden Research, Inc.\Installer Language" - -; Clean up shortcuts -Delete "$SMPROGRAMS\$INSTSHORTCUT\*.*" -RMDir "$SMPROGRAMS\$INSTSHORTCUT" - -Delete "$DESKTOP\$INSTSHORTCUT.lnk" -Delete "$INSTDIR\$INSTSHORTCUT.lnk" -Delete "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" - -; Clean up cache and log files. -; Leave them in-place for non AGNI installs. - -!ifdef UNINSTALL_SETTINGS -Call un.DocumentsAndSettingsFolder -!endif - -Call un.ProgramFiles - -SectionEnd ; end of uninstall section - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; (From the NSIS wiki, DK) -; GetParameterValue -; -; Usage: -; !insertmacro GetParameterValue "/L=" "1033" -; pop $R0 -; -; Returns on top of stack -; -; Example command lines: -; foo.exe /S /L=1033 /D=C:\Program Files\Foo -; or: -; foo.exe /S "/L=1033" /D="C:\Program Files\Foo" -; gpv "/L=" "1033" -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - !macro GetParameterValue SWITCH DEFAULT - Push $0 - Push $1 - Push $2 - Push $3 - Push $4 - - ;$CMDLINE='"My Setup\Setup.exe" /L=1033 /S' - Push "$CMDLINE" - Push '${SWITCH}"' - !insertmacro StrStr - Pop $0 - StrCmp "$0" "" gpv_notquoted - ;$0='/L="1033" /S' - StrLen $2 "$0" - Strlen $1 "${SWITCH}" - IntOp $1 $1 + 1 - StrCpy $0 "$0" $2 $1 - ;$0='1033" /S' - Push "$0" - Push '"' - !insertmacro StrStr - Pop $1 - StrLen $2 "$0" - StrLen $3 "$1" - IntOp $4 $2 - $3 - StrCpy $0 $0 $4 0 - Goto gpv_done - - gpv_notquoted: - Push "$CMDLINE" - Push "${SWITCH}" - !insertmacro StrStr - Pop $0 - StrCmp "$0" "" gpv_done - ;$0='/L="1033" /S' - StrLen $2 "$0" - Strlen $1 "${SWITCH}" - StrCpy $0 "$0" $2 $1 - ;$0=1033 /S' - Push "$0" - Push ' ' - !insertmacro StrStr - Pop $1 - StrLen $2 "$0" - StrLen $3 "$1" - IntOp $4 $2 - $3 - StrCpy $0 $0 $4 0 - Goto gpv_done - - gpv_done: - StrCmp "$0" "" 0 +2 - StrCpy $0 "${DEFAULT}" - - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Exch $0 - !macroend - -; And I had to modify StrStr a tiny bit. -; Possible upgrade switch the goto's to use ${__LINE__} - -!macro STRSTR - Exch $R1 ; st=haystack,old$R1, $R1=needle - Exch ; st=old$R1,haystack - Exch $R2 ; st=old$R1,old$R2, $R2=haystack - Push $R3 - Push $R4 - Push $R5 - StrLen $R3 $R1 - StrCpy $R4 0 - ; $R1=needle - ; $R2=haystack - ; $R3=len(needle) - ; $R4=cnt - ; $R5=tmp - ; loop; - StrCpy $R5 $R2 $R3 $R4 - StrCmp $R5 $R1 +4 - StrCmp $R5 "" +3 - IntOp $R4 $R4 + 1 - Goto -4 - ; done; - StrCpy $R1 $R2 "" $R4 - Pop $R5 - Pop $R4 - Pop $R3 - Pop $R2 - Exch $R1 -!macroend - -Function GetProgramName - !insertmacro GetParameterValue "/P=" "SecondLife" -FunctionEnd - -Function un.GetProgramName - !insertmacro GetParameterValue "/P=" "SecondLife" -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; (From the NSIS documentation, JC) -; GetWindowsVersion -; -; Based on Yazno's function, http://yazno.tripod.com/powerpimpit/ -; Updated by Joost Verburg -; -; Returns on top of stack -; -; Windows Version (95, 98, ME, NT x.x, 2000, XP, 2003) -; or -; '' (Unknown Windows Version) -; -; Usage: -; Call GetWindowsVersion -; Pop $R0 -; ; at this point $R0 is "NT 4.0" or whatnot -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function GetWindowsVersion - - Push $R0 - Push $R1 - - ReadRegStr $R0 HKLM \ - "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion - - IfErrors 0 lbl_winnt - - ; we are not NT - ReadRegStr $R0 HKLM \ - "SOFTWARE\Microsoft\Windows\CurrentVersion" VersionNumber - - StrCpy $R1 $R0 1 - StrCmp $R1 '4' 0 lbl_error - - StrCpy $R1 $R0 3 - - StrCmp $R1 '4.0' lbl_win32_95 - StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98 - - lbl_win32_95: - StrCpy $R0 '95' - Goto lbl_done - - lbl_win32_98: - StrCpy $R0 '98' - Goto lbl_done - - lbl_win32_ME: - StrCpy $R0 'ME' - Goto lbl_done - - lbl_winnt: - - StrCpy $R1 $R0 1 - - StrCmp $R1 '3' lbl_winnt_x - StrCmp $R1 '4' lbl_winnt_x - - StrCpy $R1 $R0 3 - - StrCmp $R1 '5.0' lbl_winnt_2000 - StrCmp $R1 '5.1' lbl_winnt_XP - StrCmp $R1 '5.2' lbl_winnt_2003 lbl_error - - lbl_winnt_x: - StrCpy $R0 "NT $R0" 6 - Goto lbl_done - - lbl_winnt_2000: - Strcpy $R0 '2000' - Goto lbl_done - - lbl_winnt_XP: - Strcpy $R0 'XP' - Goto lbl_done - - lbl_winnt_2003: - Strcpy $R0 '2003' - Goto lbl_done - - lbl_error: - Strcpy $R0 '' - lbl_done: - - Pop $R1 - Exch $R0 - -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Note: to add new languages, add a language file include to the list -;; at the top of this file, add an entry to the menu and then add an -;; entry to the language ID selector below -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function .onInit - - ; read the language from registry (ok if not there) and set langauge menu - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage" - StrCpy $LANGUAGE $0 - - Push "" - Push ${LANG_ENGLISH} - Push English - Push ${LANG_GERMAN} - Push German - Push ${LANG_JAPANESE} - Push Japanese - Push ${LANG_KOREAN} - Push Korean - Push A ; A means auto count languages for the auto count to work the first empty push (Push "") must remain - LangDLL::LangDialog "Installer Language" "Please select the language of the installer" - Pop $LANGUAGE - StrCmp $LANGUAGE "cancel" 0 +2 - Abort - - ; save language in registry - WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage" $LANGUAGE - - ; generate language ID that will be used as a command line arg - StrCmp $LANGUAGE "1042" 0 +3 - StrCpy $LANGFLAGS " -set SystemLanguage ko" - Goto EndOfFunc - - StrCmp $LANGUAGE "1041" 0 +3 - StrCpy $LANGFLAGS " -set SystemLanguage ja" - Goto EndOfFunc - - StrCmp $LANGUAGE "1031" 0 +3 - StrCpy $LANGFLAGS " -set SystemLanguage de" - Goto EndOfFunc - - StrCmp $LANGUAGE "1033" 0 +3 - StrCpy $LANGFLAGS " -set SystemLanguage en-us" - Goto EndOfFunc - - EndOfFunc: - -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function un.onInit - - ; read language from registry and set for ininstaller - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage" - StrCpy $LANGUAGE $0 - -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EOF ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \ No newline at end of file +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; secondlife setup.nsi +;; Copyright 2004-2007, Linden Research, Inc. +;; For info, see http://www.nullsoft.com/free/nsis/ +;; +;; NSIS 2.22 or higher required +;; Author: James Cook, Don Kjer, Callum Prentice +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Detect NSIS compiler version +!define "NSIS${NSIS_VERSION}" +!ifdef "NSISv2.02" | "NSISv2.03" | "NSISv2.04" | "NSISv2.05" | "NSISv2.06" + ;; before 2.07 defaulted lzma to solid (whole file) + SetCompressor lzma +!else + ;; after 2.07 required /solid for whole file compression + SetCompressor /solid lzma +!endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Compiler flags +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +SetOverwrite on ; overwrite files +SetCompress auto ; compress iff saves space +SetDatablockOptimize off ; only saves us 0.1%, not worth it +XPStyle on ; add an XP manifest to the installer + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Project flags +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%%VERSION%% + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; - language files - one for each language (or flavor thereof) +;; (these files are in the same place as the nsi template but the python script generates a new nsi file in the +;; application directory so we have to add a path to these include files) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +!include "installers\windows\lang_de.nsi" +!include "installers\windows\lang_en-us.nsi" +!include "installers\windows\lang_ja.nsi" +!include "installers\windows\lang_ko.nsi" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Tweak for different servers/builds (this placeholder is replaced by viewer_manifest.py) +%%GRID_VARS%% + +Name ${INSTNAME} + +SubCaption 0 $(LicenseSubTitleSetup) ; override "license agreement" text + +BrandingText " " ; bottom of window text +Icon res\install_icon.ico ; our custom icon +UninstallIcon res\uninstall_icon.ico ; our custom icon +WindowIcon on ; show our icon in left corner +BGGradient off ; no big background window +CRCCheck on ; make sure CRC is OK +InstProgressFlags smooth colored ; new colored smooth look +ShowInstDetails nevershow ; no details, no "show" button +SetOverwrite on ; stomp files by default +AutoCloseWindow true ; after all files install, close window + +!ifdef UPDATE +LicenseText $(LicenseDescUpdate) $(LicenseDescNext) +!else +LicenseText $(LicenseDescSetup) $(LicenseDescNext) +!endif + +LicenseData "releasenotes.txt" + +InstallDir "$PROGRAMFILES\${INSTNAME}" +InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "" +!ifdef UPDATE +DirText $(DirectoryChooseTitle) $(DirectoryChooseUpdate) +!else +DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup) +!endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Var INSTPROG +Var INSTEXE +Var INSTFLAGS +Var LANGFLAGS +Var INSTSHORTCUT + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Sections +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Section "" ; (default section) + +SetShellVarContext all ; install for all users (if you change this, change it in the uninstall as well) + +; Start with some default values. +StrCpy $INSTFLAGS "${INSTFLAGS}" +StrCpy $INSTFLAGS "$INSTFLAGS $LANGFLAGS" +StrCpy $INSTPROG "${INSTNAME}" +StrCpy $INSTEXE "${INSTEXE}" +StrCpy $INSTSHORTCUT "${SHORTCUT}" + +IfSilent +2 +Goto NOT_SILENT + Call CheckStartupParams ; Figure out where, what and how to install. +NOT_SILENT: +Call CheckWindowsVersion ; warn if on Windows 98/ME +Call CheckIfAdministrator ; Make sure the user can install/uninstall +Call CheckIfAlreadyCurrent ; Make sure that we haven't already installed this version +Call CloseSecondLife ; Make sure we're not running +Call RemoveNSIS ; Check for old NSIS install to remove + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Don't remove cache files during a regular install, removing the inventory cache on upgrades results in lots of damage to the servers. +;Call RemoveCacheFiles ; Installing over removes potentially corrupted + ; VFS and cache files. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Need to clean out shader files from previous installs to fix DEV-5663 +Call RemoveOldShaders + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Files +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py +%%INSTALL_FILES%% + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; If this is a silent update, we don't need to re-create these shortcuts or registry entries. +IfSilent POST_INSTALL + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Shortcuts in start menu +CreateDirectory "$SMPROGRAMS\$INSTSHORTCUT" +SetOutPath "$INSTDIR" +CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \ + "$INSTDIR\$INSTEXE" "$INSTFLAGS" + +!ifdef MUSEUM +CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT Museum.lnk" \ + + "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple" +CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT Museum Spanish.lnk" \ + + "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple -spanish" +!endif + +WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Create Trial Account.url" \ + "InternetShortcut" "URL" \ + "http://www.secondlife.com/registration/" +WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Your Account.url" \ + "InternetShortcut" "URL" \ + "http://www.secondlife.com/account/" +CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk" \ + "$INSTDIR\releasenotes.txt" +CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\SL Scripting Language Help.lnk" \ + "$INSTDIR\lsl_guide.html" +CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\Uninstall $INSTSHORTCUT.lnk" \ + '"$INSTDIR\uninst.exe"' '/P="$INSTPROG"' + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Other shortcuts +SetOutPath "$INSTDIR" +CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS" +CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS" +CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \ + '"$INSTDIR\uninst.exe"' '/P="$INSTPROG"' + +!ifdef MUSEUM +CreateShortCut "$DESKTOP\$INSTSHORTCUT Museum.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple" + +CreateShortCut "$DESKTOP\$INSTSHORTCUT Museum Spanish.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple -spanish" + +CreateShortCut "$INSTDIR\$INSTSHORTCUT Museum.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple" + +CreateShortCut "$INSTDIR\$INSTSHORTCUT Museum Spanish.lnk" "$INSTDIR\$INSTEXE" "$INSTFLAGS -simple -spanish" + +!endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Write registry +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" "$INSTDIR" +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" "${VERSION_LONG}" +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Flags" "$INSTFLAGS" +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" "$INSTSHORTCUT" +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" "$INSTEXE" +WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayName" "$INSTPROG (remove only)" +WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "UninstallString" '"$INSTDIR\uninst.exe" /P="$INSTPROG"' + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Write URL registry info +WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "(default)" "URL:Second Life" +WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "URL Protocol" "" +WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\DefaultIcon" "" '"$INSTDIR\$INSTEXE"' +WriteRegExpandStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open\command" "" '"$INSTDIR\$INSTEXE" $INSTFLAGS -url "%1"' + +Goto WRITE_UNINST + +POST_INSTALL: +; Run a post-executable script if necessary. +Call PostInstallExe + +WRITE_UNINST: +; write out uninstaller +WriteUninstaller "$INSTDIR\uninst.exe" + +; end of default section +SectionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; PostInstallExe +; This just runs any post installation scripts. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function PostInstallExe +push $0 + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "PostInstallExe" + ;MessageBox MB_OK '$0' + ExecWait '$0' +pop $0 +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CheckStartupParameters +; Sets INSTFLAGS, INSTPROG, and INSTEXE. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function CheckStartupParams +push $0 +push $R0 + + ; Look for a registry entry with info about where to update. + Call GetProgramName + pop $R0 + StrCpy $INSTPROG "$R0" + StrCpy $INSTEXE "$R0.exe" + + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" + ; If key doesn't exist, skip install + IfErrors ABORT + StrCpy $INSTDIR "$0" + + ; We now have a directory to install to. Get the startup parameters and shortcut as well. + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Flags" + IfErrors +2 + StrCpy $INSTFLAGS "$0" + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" + IfErrors +2 + StrCpy $INSTSHORTCUT "$0" + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" + IfErrors +2 + StrCpy $INSTEXE "$0" + Goto FINISHED + +ABORT: + MessageBox MB_OK $(CheckStartupParamsMB) + Quit + +FINISHED: + ;MessageBox MB_OK "INSTPROG: $INSTPROG, INSTEXE: $INSTEXE, INSTFLAGS: $INSTFLAGS" +pop $R0 +pop $0 +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function un.CheckStartupParams +push $0 +push $R0 + + ; Look for a registry entry with info about where to update. + Call un.GetProgramName + pop $R0 + StrCpy $INSTPROG "$R0" + StrCpy $INSTEXE "$R0.exe" + + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" + ; If key doesn't exist, skip install + IfErrors ABORT + StrCpy $INSTDIR "$0" + + ; We now have a directory to install to. Get the startup parameters and shortcut as well. + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Flags" + IfErrors +2 + StrCpy $INSTFLAGS "$0" + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" + IfErrors +2 + StrCpy $INSTSHORTCUT "$0" + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" + IfErrors +2 + StrCpy $INSTEXE "$0" + Goto FINISHED + +ABORT: + MessageBox MB_OK $(CheckStartupParamsMB) + Quit + +FINISHED: + ;MessageBox MB_OK "INSTPROG: $INSTPROG, INSTEXE: $INSTEXE, INSTFLAGS: $INSTFLAGS" +pop $R0 +pop $0 +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; After install completes, offer readme file +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function .onInstSuccess + MessageBox MB_YESNO \ + $(InstSuccesssQuestion) /SD IDYES IDNO NoReadme + ; Assumes SetOutPath $INSTDIR + Exec '"$INSTDIR\$INSTEXE" $INSTFLAGS' + NoReadme: +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Remove old NSIS version. Modifies no variables. +; Does NOT delete the LindenWorld directory, or any +; user files in that directory. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function RemoveNSIS + Push $0 + ; Grab the installation directory of the old version + DetailPrint $(RemoveOldNSISVersion) + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" + + ; If key doesn't exist, skip uninstall + IfErrors NO_NSIS + + ; Clean up legacy beta shortcuts + Delete "$SMPROGRAMS\Second Life Beta.lnk" + Delete "$DESKTOP\Second Life Beta.lnk" + Delete "$SMPROGRAMS\Second Life.lnk" + + ; Clean up old newview.exe file + Delete "$INSTDIR\newview.exe" + + ; Intentionally don't delete the stuff in + ; Documents and Settings, so we keep the user's settings + + NO_NSIS: + Pop $0 +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Make sure we're not on Windows 98 / ME +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function CheckWindowsVersion + DetailPrint "Checking Windows version..." + Call GetWindowsVersion + Pop $R0 + ; Just get first two characters, ignore 4.0 part of "NT 4.0" + StrCpy $R0 $R0 2 + ; Blacklist certain OS versions + StrCmp $R0 "95" win_ver_bad + StrCmp $R0 "98" win_ver_bad + StrCmp $R0 "ME" win_ver_bad + StrCmp $R0 "NT" win_ver_bad + Return +win_ver_bad: + MessageBox MB_YESNO $(CheckWindowsVersionMB) IDNO win_ver_abort + Return +win_ver_abort: + Quit +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Make sure the user can install/uninstall +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function CheckIfAdministrator + DetailPrint $(CheckAdministratorInstDP) + UserInfo::GetAccountType + Pop $R0 + StrCmp $R0 "Admin" is_admin + MessageBox MB_OK $(CheckAdministratorInstMB) + Quit +is_admin: + Return +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function un.CheckIfAdministrator + DetailPrint $(CheckAdministratorUnInstDP) + UserInfo::GetAccountType + Pop $R0 + StrCmp $R0 "Admin" is_admin + MessageBox MB_OK $(CheckAdministratorUnInstMB) + Quit +is_admin: + Return +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Checks to see if the current version has already been installed (according to the registry). +; If it has, allow user to bail out of install process. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function CheckIfAlreadyCurrent + Push $0 + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" + StrCmp $0 ${VERSION_LONG} 0 DONE + MessageBox MB_OKCANCEL $(CheckIfCurrentMB) /SD IDOK IDOK DONE + Quit + + DONE: + Pop $0 + Return +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Close the program, if running. Modifies no variables. +; Allows user to bail out of install process. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function CloseSecondLife + Push $0 + FindWindow $0 "Second Life" "" + IntCmp $0 0 DONE + MessageBox MB_OKCANCEL $(CloseSecondLifeInstMB) IDOK CLOSE IDCANCEL CANCEL_INSTALL + + CANCEL_INSTALL: + Quit + + CLOSE: + DetailPrint $(CloseSecondLifeInstDP) + SendMessage $0 16 0 0 + + LOOP: + FindWindow $0 "Second Life" "" + IntCmp $0 0 DONE + Sleep 500 + Goto LOOP + + DONE: + Pop $0 + Return +FunctionEnd + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Delete files in Documents and Settings\\SecondLife\cache +; Delete files in Documents and Settings\All Users\SecondLife\cache +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Function RemoveCacheFiles +; +;; Delete files in Documents and Settings\\SecondLife +;Push $0 +;Push $1 +;Push $2 +; DetailPrint $(RemoveCacheFilesDP) +; +; StrCpy $0 0 ; Index number used to iterate via EnumRegKey +; +; LOOP: +; EnumRegKey $1 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $0 +; StrCmp $1 "" DONE ; no more users +; +; ReadRegStr $2 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$1" "ProfileImagePath" +; StrCmp $2 "" CONTINUE 0 ; "ProfileImagePath" value is missing +; +; ; Required since ProfileImagePath is of type REG_EXPAND_SZ +; ExpandEnvStrings $2 $2 +; +; ; When explicitly uninstalling, everything goes away +; RMDir /r "$2\Application Data\SecondLife\cache" +; +; CONTINUE: +; IntOp $0 $0 + 1 +; Goto LOOP +; DONE: +;Pop $2 +;Pop $1 +;Pop $0 +; +;; Delete files in Documents and Settings\All Users\SecondLife +;Push $0 +; ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" "Common AppData" +; StrCmp $0 "" +2 +; RMDir /r "$0\SecondLife\cache" +;Pop $0 +; +;; Delete filse in C:\Windows\Application Data\SecondLife +;; If the user is running on a pre-NT system, Application Data lives here instead of +;; in Documents and Settings. +;RMDir /r "$WINDIR\Application Data\SecondLife\cache" +; +;FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Delete the installed shader files +;;; Since shaders are in active development, we'll likely need to shuffle them +;;; around a bit from build to build. This ensures that shaders that we move +;;; or rename in the dev tree don't get left behind in the install. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function RemoveOldShaders + +;; Remove old shader files first so fallbacks will work. see DEV-5663 +RMDir /r "$INSTDIR\app_settings\shaders\*" + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Delete files in Documents and Settings\\SecondLife +; Delete files in Documents and Settings\All Users\SecondLife +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function un.DocumentsAndSettingsFolder + +; Delete files in Documents and Settings\\SecondLife +Push $0 +Push $1 +Push $2 + + DetailPrint "Deleting files in Documents and Settings folder" + + StrCpy $0 0 ; Index number used to iterate via EnumRegKey + + LOOP: + EnumRegKey $1 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $0 + StrCmp $1 "" DONE ; no more users + + ReadRegStr $2 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$1" "ProfileImagePath" + StrCmp $2 "" CONTINUE 0 ; "ProfileImagePath" value is missing + + ; Required since ProfileImagePath is of type REG_EXPAND_SZ + ExpandEnvStrings $2 $2 + + ; If uninstalling a normal install remove everything + ; Otherwise (preview/dmz etc) just remove cache + StrCmp $INSTFLAGS "" RM_ALL RM_CACHE + RM_ALL: + RMDir /r "$2\Application Data\SecondLife" + GoTo CONTINUE + RM_CACHE: + RMDir /r "$2\Application Data\SecondLife\Cache" + Delete "$2\Application Data\SecondLife\user_settings\settings_windlight.xml" + + CONTINUE: + IntOp $0 $0 + 1 + Goto LOOP + DONE: + +Pop $2 +Pop $1 +Pop $0 + +; Delete files in Documents and Settings\All Users\SecondLife +Push $0 + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" "Common AppData" + StrCmp $0 "" +2 + RMDir /r "$0\SecondLife" +Pop $0 + +; Delete filse in C:\Windows\Application Data\SecondLife +; If the user is running on a pre-NT system, Application Data lives here instead of +; in Documents and Settings. +RMDir /r "$WINDIR\Application Data\SecondLife" + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Close the program, if running. Modifies no variables. +; Allows user to bail out of uninstall process. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function un.CloseSecondLife + Push $0 + FindWindow $0 "Second Life" "" + IntCmp $0 0 DONE + MessageBox MB_OKCANCEL $(CloseSecondLifeUnInstMB) IDOK CLOSE IDCANCEL CANCEL_UNINSTALL + + CANCEL_UNINSTALL: + Quit + + CLOSE: + DetailPrint $(CloseSecondLifeUnInstDP) + SendMessage $0 16 0 0 + + LOOP: + FindWindow $0 "Second Life" "" + IntCmp $0 0 DONE + Sleep 500 + Goto LOOP + + DONE: + Pop $0 + Return +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Delete the installed files +;;; This deletes the uninstall executable, but it works +;;; because it is copied to temp directory before running +;;; +;;; Note: You must list all files here, because we only +;;; want to delete our files, not things users left in the +;;; application directories. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function un.ProgramFiles + +;; Remove mozilla file first so recursive directory deletion doesn't get hung up +Delete "$INSTDIR\app_settings\mozilla\components" + +;; This placeholder is replaced by the complete list of files to uninstall by viewer_manifest.py +%%DELETE_FILES%% + +;; Optional/obsolete files. Delete won't fail if they don't exist. +Delete "$INSTDIR\dronesettings.ini" +Delete "$INSTDIR\message_template.msg" +Delete "$INSTDIR\newview.pdb" +Delete "$INSTDIR\newview.map" +Delete "$INSTDIR\SecondLife.pdb" +Delete "$INSTDIR\SecondLife.map" +Delete "$INSTDIR\comm.dat" +Delete "$INSTDIR\*.glsl" +Delete "$INSTDIR\motions\*.lla" +Delete "$INSTDIR\trial\*.html" +Delete "$INSTDIR\newview.exe" +;; Remove entire help directory +Delete "$INSTDIR\help\Advanced\*" +RMDir "$INSTDIR\help\Advanced" +Delete "$INSTDIR\help\basics\*" +RMDir "$INSTDIR\help\basics" +Delete "$INSTDIR\help\Concepts\*" +RMDir "$INSTDIR\help\Concepts" +Delete "$INSTDIR\help\welcome\*" +RMDir "$INSTDIR\help\welcome" +Delete "$INSTDIR\help\*" +RMDir "$INSTDIR\help" + +Delete "$INSTDIR\uninst.exe" +RMDir "$INSTDIR" + +IfFileExists "$INSTDIR" FOLDERFOUND NOFOLDER + +FOLDERFOUND: + MessageBox MB_YESNO $(DeleteProgramFilesMB) IDNO NOFOLDER + RMDir /r "$INSTDIR" + +NOFOLDER: + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Uninstall settings +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +UninstallText $(UninstallTextMsg) +ShowUninstDetails show + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Uninstall section +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Section Uninstall + +; Start with some default values. +StrCpy $INSTFLAGS "" +StrCpy $INSTPROG "${INSTNAME}" +StrCpy $INSTEXE "${INSTEXE}" +StrCpy $INSTSHORTCUT "${SHORTCUT}" +Call un.CheckStartupParams ; Figure out where, what and how to uninstall. +Call un.CheckIfAdministrator ; Make sure the user can install/uninstall + +; uninstall for all users (if you change this, change it in the install as well) +SetShellVarContext all + +; Make sure we're not running +Call un.CloseSecondLife + +; Clean up registry keys (these should all be !defines somewhere) +DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" +DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" +DeleteRegKey HKEY_LOCAL_MACHINE "Software\Linden Research, Inc.\Installer Language" + +; Clean up shortcuts +Delete "$SMPROGRAMS\$INSTSHORTCUT\*.*" +RMDir "$SMPROGRAMS\$INSTSHORTCUT" + +Delete "$DESKTOP\$INSTSHORTCUT.lnk" +Delete "$INSTDIR\$INSTSHORTCUT.lnk" +Delete "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" + +; Clean up cache and log files. +; Leave them in-place for non AGNI installs. + +!ifdef UNINSTALL_SETTINGS +Call un.DocumentsAndSettingsFolder +!endif + +Call un.ProgramFiles + +SectionEnd ; end of uninstall section + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; (From the NSIS wiki, DK) +; GetParameterValue +; +; Usage: +; !insertmacro GetParameterValue "/L=" "1033" +; pop $R0 +; +; Returns on top of stack +; +; Example command lines: +; foo.exe /S /L=1033 /D=C:\Program Files\Foo +; or: +; foo.exe /S "/L=1033" /D="C:\Program Files\Foo" +; gpv "/L=" "1033" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + !macro GetParameterValue SWITCH DEFAULT + Push $0 + Push $1 + Push $2 + Push $3 + Push $4 + + ;$CMDLINE='"My Setup\Setup.exe" /L=1033 /S' + Push "$CMDLINE" + Push '${SWITCH}"' + !insertmacro StrStr + Pop $0 + StrCmp "$0" "" gpv_notquoted + ;$0='/L="1033" /S' + StrLen $2 "$0" + Strlen $1 "${SWITCH}" + IntOp $1 $1 + 1 + StrCpy $0 "$0" $2 $1 + ;$0='1033" /S' + Push "$0" + Push '"' + !insertmacro StrStr + Pop $1 + StrLen $2 "$0" + StrLen $3 "$1" + IntOp $4 $2 - $3 + StrCpy $0 $0 $4 0 + Goto gpv_done + + gpv_notquoted: + Push "$CMDLINE" + Push "${SWITCH}" + !insertmacro StrStr + Pop $0 + StrCmp "$0" "" gpv_done + ;$0='/L="1033" /S' + StrLen $2 "$0" + Strlen $1 "${SWITCH}" + StrCpy $0 "$0" $2 $1 + ;$0=1033 /S' + Push "$0" + Push ' ' + !insertmacro StrStr + Pop $1 + StrLen $2 "$0" + StrLen $3 "$1" + IntOp $4 $2 - $3 + StrCpy $0 $0 $4 0 + Goto gpv_done + + gpv_done: + StrCmp "$0" "" 0 +2 + StrCpy $0 "${DEFAULT}" + + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Exch $0 + !macroend + +; And I had to modify StrStr a tiny bit. +; Possible upgrade switch the goto's to use ${__LINE__} + +!macro STRSTR + Exch $R1 ; st=haystack,old$R1, $R1=needle + Exch ; st=old$R1,haystack + Exch $R2 ; st=old$R1,old$R2, $R2=haystack + Push $R3 + Push $R4 + Push $R5 + StrLen $R3 $R1 + StrCpy $R4 0 + ; $R1=needle + ; $R2=haystack + ; $R3=len(needle) + ; $R4=cnt + ; $R5=tmp + ; loop; + StrCpy $R5 $R2 $R3 $R4 + StrCmp $R5 $R1 +4 + StrCmp $R5 "" +3 + IntOp $R4 $R4 + 1 + Goto -4 + ; done; + StrCpy $R1 $R2 "" $R4 + Pop $R5 + Pop $R4 + Pop $R3 + Pop $R2 + Exch $R1 +!macroend + +Function GetProgramName + !insertmacro GetParameterValue "/P=" "SecondLife" +FunctionEnd + +Function un.GetProgramName + !insertmacro GetParameterValue "/P=" "SecondLife" +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; (From the NSIS documentation, JC) +; GetWindowsVersion +; +; Based on Yazno's function, http://yazno.tripod.com/powerpimpit/ +; Updated by Joost Verburg +; +; Returns on top of stack +; +; Windows Version (95, 98, ME, NT x.x, 2000, XP, 2003) +; or +; '' (Unknown Windows Version) +; +; Usage: +; Call GetWindowsVersion +; Pop $R0 +; ; at this point $R0 is "NT 4.0" or whatnot +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function GetWindowsVersion + + Push $R0 + Push $R1 + + ReadRegStr $R0 HKLM \ + "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion + + IfErrors 0 lbl_winnt + + ; we are not NT + ReadRegStr $R0 HKLM \ + "SOFTWARE\Microsoft\Windows\CurrentVersion" VersionNumber + + StrCpy $R1 $R0 1 + StrCmp $R1 '4' 0 lbl_error + + StrCpy $R1 $R0 3 + + StrCmp $R1 '4.0' lbl_win32_95 + StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98 + + lbl_win32_95: + StrCpy $R0 '95' + Goto lbl_done + + lbl_win32_98: + StrCpy $R0 '98' + Goto lbl_done + + lbl_win32_ME: + StrCpy $R0 'ME' + Goto lbl_done + + lbl_winnt: + + StrCpy $R1 $R0 1 + + StrCmp $R1 '3' lbl_winnt_x + StrCmp $R1 '4' lbl_winnt_x + + StrCpy $R1 $R0 3 + + StrCmp $R1 '5.0' lbl_winnt_2000 + StrCmp $R1 '5.1' lbl_winnt_XP + StrCmp $R1 '5.2' lbl_winnt_2003 lbl_error + + lbl_winnt_x: + StrCpy $R0 "NT $R0" 6 + Goto lbl_done + + lbl_winnt_2000: + Strcpy $R0 '2000' + Goto lbl_done + + lbl_winnt_XP: + Strcpy $R0 'XP' + Goto lbl_done + + lbl_winnt_2003: + Strcpy $R0 '2003' + Goto lbl_done + + lbl_error: + Strcpy $R0 '' + lbl_done: + + Pop $R1 + Exch $R0 + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Note: to add new languages, add a language file include to the list +;; at the top of this file, add an entry to the menu and then add an +;; entry to the language ID selector below +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function .onInit + + ; read the language from registry (ok if not there) and set langauge menu + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage" + StrCpy $LANGUAGE $0 + + Push "" + Push ${LANG_ENGLISH} + Push English + Push ${LANG_GERMAN} + Push German + Push ${LANG_JAPANESE} + Push Japanese + Push ${LANG_KOREAN} + Push Korean + Push A ; A means auto count languages for the auto count to work the first empty push (Push "") must remain + LangDLL::LangDialog "Installer Language" "Please select the language of the installer" + Pop $LANGUAGE + StrCmp $LANGUAGE "cancel" 0 +2 + Abort + + ; save language in registry + WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage" $LANGUAGE + + ; generate language ID that will be used as a command line arg + StrCmp $LANGUAGE "1042" 0 +3 + StrCpy $LANGFLAGS " -set SystemLanguage ko" + Goto EndOfFunc + + StrCmp $LANGUAGE "1041" 0 +3 + StrCpy $LANGFLAGS " -set SystemLanguage ja" + Goto EndOfFunc + + StrCmp $LANGUAGE "1031" 0 +3 + StrCpy $LANGFLAGS " -set SystemLanguage de" + Goto EndOfFunc + + StrCmp $LANGUAGE "1033" 0 +3 + StrCpy $LANGFLAGS " -set SystemLanguage en-us" + Goto EndOfFunc + + EndOfFunc: + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function un.onInit + + ; read language from registry and set for ininstaller + ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage" + StrCpy $LANGUAGE $0 + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EOF ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/linden/indra/newview/licenses-linux.txt b/linden/indra/newview/licenses-linux.txt index 795b7cc..b43c402 100644 --- a/linden/indra/newview/licenses-linux.txt +++ b/linden/indra/newview/licenses-linux.txt @@ -148,6 +148,49 @@ BRIAN PAUL 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. +========================= +glh OpenGL helper library +========================= + +glh - is a platform-indepenedent C++ OpenGL helper library + + +Copyright (c) 2000 Cass Everitt + Copyright (c) 2000 NVIDIA Corporation +All rights reserved. + +Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * The names of contributors to this software may not be used + to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + +Cass Everitt - cass@r3.nu + ======================= JPEG Library 6b License ======================= diff --git a/linden/indra/newview/licenses-mac.txt b/linden/indra/newview/licenses-mac.txt index e87d244..d488c74 100644 --- a/linden/indra/newview/licenses-mac.txt +++ b/linden/indra/newview/licenses-mac.txt @@ -148,6 +148,49 @@ BRIAN PAUL 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. +========================= +glh OpenGL helper library +========================= + +glh - is a platform-indepenedent C++ OpenGL helper library + + +Copyright (c) 2000 Cass Everitt + Copyright (c) 2000 NVIDIA Corporation +All rights reserved. + +Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * The names of contributors to this software may not be used + to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + +Cass Everitt - cass@r3.nu + ======================= JPEG Library 6b License ======================= diff --git a/linden/indra/newview/licenses-solaris.txt b/linden/indra/newview/licenses-solaris.txt index 792330f..c19f939 100644 --- a/linden/indra/newview/licenses-solaris.txt +++ b/linden/indra/newview/licenses-solaris.txt @@ -148,6 +148,49 @@ BRIAN PAUL 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. +========================= +glh OpenGL helper library +========================= + +glh - is a platform-indepenedent C++ OpenGL helper library + + +Copyright (c) 2000 Cass Everitt + Copyright (c) 2000 NVIDIA Corporation +All rights reserved. + +Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * The names of contributors to this software may not be used + to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + +Cass Everitt - cass@r3.nu + ======================= JPEG Library 6b License ======================= diff --git a/linden/indra/newview/licenses-win32.txt b/linden/indra/newview/licenses-win32.txt index 3d9ef9b..5f6cf14 100644 --- a/linden/indra/newview/licenses-win32.txt +++ b/linden/indra/newview/licenses-win32.txt @@ -187,6 +187,51 @@ BRIAN PAUL 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. + +========================= +glh OpenGL helper library +========================= + +glh - is a platform-indepenedent C++ OpenGL helper library + + +Copyright (c) 2000 Cass Everitt + Copyright (c) 2000 NVIDIA Corporation +All rights reserved. + +Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * The names of contributors to this software may not be used + to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + +Cass Everitt - cass@r3.nu + ======================= JPEG Library 6b License ======================= diff --git a/linden/indra/newview/linux_tools/launch_url.sh b/linden/indra/newview/linux_tools/launch_url.sh index e6450ad..d2c8919 100755 --- a/linden/indra/newview/linux_tools/launch_url.sh +++ b/linden/indra/newview/linux_tools/launch_url.sh @@ -17,10 +17,16 @@ URL="$1" if [ -z "$URL" ]; then - echo Usage: $0 URL + echo "Usage: $0 URL" exit fi +# restore LD_LIBRARY_PATH from SAVED_LD_LIBRARY_PATH if it exists +if [ "${SAVED_LD_LIBRARY_PATH+isset}" = "isset" ]; then + export LD_LIBRARY_PATH="${SAVED_LD_LIBRARY_PATH}" + echo "$0: Restored library path to '${SAVED_LD_LIBRARY_PATH}'" +fi + # if $BROWSER is defined, use it. XBROWSER=`echo "$BROWSER" |cut -f1 -d:` if [ ! -z "$XBROWSER" ]; then @@ -37,8 +43,8 @@ if [ ! -z "$XBROWSER" ]; then $XBROWSER "$URL" & exit fi - echo "Couldn't find the browser specified by \$BROWSER ($BROWSER)" - echo "Trying some others..." + echo "$0: Couldn't find the browser specified by \$BROWSER ($BROWSER)" + echo "$0: Trying some others..." fi # else kfmclient @@ -81,6 +87,6 @@ if which netscape >/dev/null; then exit fi -echo 'Failed to find a known browser. Please consider setting the $BROWSER environment variable.' +echo '$0: Failed to find a known browser. Please consider setting the $BROWSER environment variable.' # end. diff --git a/linden/indra/newview/linux_tools/wrapper.sh b/linden/indra/newview/linux_tools/wrapper.sh index 587c56f..070d45a 100755 --- a/linden/indra/newview/linux_tools/wrapper.sh +++ b/linden/indra/newview/linux_tools/wrapper.sh @@ -17,7 +17,9 @@ ## on some hardware. Disabling this option may cause BETTER PERFORMANCE but ## may also cause CRASHES and hangs on some unstable combinations of drivers ## and hardware. -export LL_GL_BASICEXT=x +## NOTE: This is 'off' for WindLight to help testing. Hopefully it's not +## really needed any more anyway. +#export LL_GL_BASICEXT=x ## - Avoids *all* optional OpenGL extensions. This is the safest and least- ## exciting option. Enable this if you experience stability issues, and @@ -61,10 +63,16 @@ fi SCRIPTSRC=`readlink -f "$0" || echo "$0"` RUN_PATH=`dirname "${SCRIPTSRC}" || echo .` +echo "Running from ${RUN_PATH}" cd "${RUN_PATH}" # Re-register the secondlife:// protocol handler every launch, for now. ./register_secondlifeprotocol.sh +## Before we mess with LD_LIBRARY_PATH, save the old one to restore for +## subprocesses that care. +if [ "${LD_LIBRARY_PATH+isset}" = "isset" ]; then + export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" +fi if [ -n "$LL_TCMALLOC" ]; then tcmalloc_libs='/usr/lib/libtcmalloc.so.0 /usr/lib/libstacktrace.so.0 /lib/libpthread.so.0' diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 77e743d..2dab8ff 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -463,7 +463,6 @@ void LLAgent::cleanup() mPointAt = NULL; mRegionp = NULL; setFocusObject(NULL); - mFadeObjects.clear(); } //----------------------------------------------------------------------------- @@ -833,20 +832,18 @@ void LLAgent::setRegion(LLViewerRegion *regionp) setPositionAgent(getPositionAgent() - delta); LLVector3 camera_position_agent = gCamera->getOrigin(); + gCamera->setOrigin(camera_position_agent - delta); // Update all of the regions. gWorldPointer->updateAgentOffset(agent_offset_global); // Hack to keep sky in the agent's region, otherwise it may get deleted - DJS 08/02/02 + // *TODO: possibly refactor into gSky->setAgentRegion(regionp)? -Brad if (gSky.mVOSkyp) { gSky.mVOSkyp->setRegion(regionp); } - if (gSky.mVOStarsp) - { - gSky.mVOStarsp->setRegion(regionp); - } if (gSky.mVOGroundp) { gSky.mVOGroundp->setRegion(regionp); @@ -969,12 +966,12 @@ void LLAgent::sendReliableMessage() { if (gDisconnected) { - llwarns << "Trying to send message when disconnected!" << llendl; + lldebugs << "Trying to send message when disconnected!" << llendl; return; } if (!mRegionp) { - llwarns << "LLAgent::sendReliableMessage No region for agent yet, not sending message!" << llendl; + lldebugs << "LLAgent::sendReliableMessage No region for agent yet, not sending message!" << llendl; return; } gMessageSystem->sendReliable(mRegionp->getHost()); @@ -1390,12 +1387,6 @@ LLVector3d LLAgent::calcFocusOffset(LLViewerObject *object, S32 x, S32 y) if (!is_avatar) { //unproject relative clicked coordinate from window coordinate using GL - glPushMatrix(); - glMatrixMode(GL_PROJECTION); - glLoadMatrixf((const GLfloat*) gCamera->getProjection().mMatrix); - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf((const GLfloat*) gCamera->getModelview().mMatrix); - glMultMatrixf((const GLfloat*) obj_matrix.mMatrix); GLint viewport[4]; GLdouble modelview[16]; @@ -1403,8 +1394,16 @@ LLVector3d LLAgent::calcFocusOffset(LLViewerObject *object, S32 x, S32 y) GLfloat winX, winY, winZ; GLdouble posX, posY, posZ; - glGetDoublev( GL_MODELVIEW_MATRIX, modelview ); - glGetDoublev( GL_PROJECTION_MATRIX, projection ); + // convert our matrices to something that has a multiply that works + glh::matrix4f newModel((F32*)gCamera->getModelview().mMatrix); + glh::matrix4f tmpObjMat((F32*)obj_matrix.mMatrix); + newModel *= tmpObjMat; + + for(U32 i = 0; i < 16; ++i) + { + modelview[i] = newModel.m[i]; + projection[i] = gCamera->getProjection().mMatrix[i/4][i%4]; + } glGetIntegerv( GL_VIEWPORT, viewport ); winX = ((F32)x) * gViewerWindow->getDisplayScale().mV[VX]; @@ -1413,14 +1412,12 @@ LLVector3d LLAgent::calcFocusOffset(LLViewerObject *object, S32 x, S32 y) gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ); - glPopMatrix(); - - LLVector3 obj_rel = LLVector3((F32)posX, (F32)posY, (F32)posZ); - LLVector3 obj_center = LLVector3(0, 0, 0); - obj_rel = obj_rel * object->getRenderMatrix(); //mDrawable->getWorldMatrix(); - obj_center = obj_center * object->getRenderMatrix();//mDrawable->getWorldMatrix(); - obj_rel -= object->getRenderPosition();//mDrawable->getWorldPosition(); + LLVector3 obj_rel((F32)posX, (F32)posY, (F32)posZ); + obj_rel = obj_rel * object->getRenderMatrix(); + obj_rel -= object->getRenderPosition(); + LLVector3 obj_center = LLVector3(0, 0, 0) * object->getRenderMatrix(); + //now that we have the object relative position, we should bias toward the center of the object //based on the distance of the camera to the focus point vs. the distance of the camera to the focus @@ -3151,74 +3148,6 @@ void LLAgent::updateCamera() mCameraFOVZoomFactor = calcCameraFOVZoomFactor(); camera_target_global = focus_target_global + (camera_target_global - focus_target_global) * (1.f + mCameraFOVZoomFactor); - // do alpha fade on focus object - F32 fade_increment = mFocusObjectFadeTimer.getElapsedTimeAndResetF32(); - - if (mFocusObject.notNull() && !mFocusObject->isAttachment() && mFocusObject->mDrawable.notNull()) - { - F32 increment = fade_increment; - if (mFocusObjectDist < -0.2f) - { - increment *= -1.f; - } - - if (mFocusObject->getVObjRadius() > MIN_RADIUS_ALPHA_SIZZLE) - { - S32 num_faces = mFocusObject->mDrawable->getNumFaces(); - for (S32 i = 0; i < num_faces; i++) - { - LLFace* facep = mFocusObject->mDrawable->getFace(i); - F32 fade = facep->mAlphaFade; - fade = llclamp(fade + increment, 0.f, 1.f); - facep->mAlphaFade = fade; - } - } - } - - // do alpha fade in on fade objects - std::set< LLPointer >::iterator fade_object_it; - for (fade_object_it = mFadeObjects.begin(); fade_object_it != mFadeObjects.end(); ) - { - LLViewerObject* fade_object = *fade_object_it; - if (fade_object->isDead()) - { - // remove from list - mFadeObjects.erase(fade_object_it++); - } - else - { - LLDrawable* drawablep = fade_object->mDrawable; - if (drawablep && fade_object->getVObjRadius() > MIN_RADIUS_ALPHA_SIZZLE) - { - S32 num_faces = drawablep->getNumFaces(); - BOOL fade_done = TRUE; - for (S32 i = 0; i < num_faces; i++) - { - LLFace* facep = drawablep->getFace(i); - F32 fade = facep->mAlphaFade; - fade = llclamp(fade - fade_increment, 0.f, 1.f); - facep->mAlphaFade = fade; - if (fade > 0.f) - { - fade_done = FALSE; - } - } - if (fade_done) - { - mFadeObjects.erase(fade_object_it++); - } - else - { - fade_object_it++; - } - } - else - { - fade_object_it++; - } - } - } - mShowAvatar = TRUE; // can see avatar by default // Adjust position for animation @@ -3373,10 +3302,11 @@ void LLAgent::updateCamera() mAvatarObject->mRoot.updateWorldMatrixChildren(); - for(LLViewerJointAttachment *attachment = mAvatarObject->mAttachmentPoints.getFirstData(); - attachment; - attachment = mAvatarObject->mAttachmentPoints.getNextData()) + for (LLVOAvatar::attachment_map_t::iterator iter = mAvatarObject->mAttachmentPoints.begin(); + iter != mAvatarObject->mAttachmentPoints.end(); ) { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; LLViewerObject *attached_object = attachment->getObject(); if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull()) { @@ -4315,19 +4245,6 @@ void LLAgent::clearFocusObject() void LLAgent::setFocusObject(LLViewerObject* object) { - if (mFocusObject.notNull() && - mFocusObject->mDrawable.notNull() && - mFocusObject->getPCode() == LL_PCODE_VOLUME && - mFocusObject != object) - { - LLPointer fade_object_ptr(mFocusObject); - - if (fade_object_ptr.notNull() && mFadeObjects.find(fade_object_ptr) == mFadeObjects.end()) - { - mFadeObjects.insert(fade_object_ptr); - } - } - mFocusObject = object; } @@ -5749,6 +5666,19 @@ bool LLAgent::teleportCore(bool is_local) return false; } + // Stop all animation before actual teleporting + LLVOAvatar* avatarp = gAgent.getAvatarObject(); + if (avatarp) + { + for ( LLVOAvatar::AnimIterator anim_it= avatarp->mPlayingAnimations.begin() + ; anim_it != avatarp->mPlayingAnimations.end() + ; anim_it++) + { + avatarp->stopMotion(anim_it->first); + } + avatarp->processAnimationStateChanges(); + } + // Don't call LLFirstUse::useTeleport because we don't know // yet if the teleport will succeed. Look in // process_teleport_location_reply @@ -5769,6 +5699,9 @@ bool LLAgent::teleportCore(bool is_local) { gTeleportDisplay = TRUE; gAgent.setTeleportState( LLAgent::TELEPORT_START ); + + //release geometry from old location + gPipeline.resetVertexBuffers(); } make_ui_sound("UISndTeleportOut"); @@ -6830,11 +6763,10 @@ void LLAgent::makeNewOutfit( { BOOL msg_started = FALSE; LLMessageSystem* msg = gMessageSystem; - S32 i; - for( i = 0; i < attachments_to_include.count(); i++ ) + for( S32 i = 0; i < attachments_to_include.count(); i++ ) { S32 attachment_pt = attachments_to_include[i]; - LLViewerJointAttachment* attachment = mAvatarObject->mAttachmentPoints.getIfThere( attachment_pt ); + LLViewerJointAttachment* attachment = get_if_there(mAvatarObject->mAttachmentPoints, attachment_pt, (LLViewerJointAttachment*)NULL ); if(!attachment) continue; LLViewerObject* attached_object = attachment->getObject(); if(!attached_object) continue; @@ -7454,11 +7386,11 @@ void LLAgent::userRemoveAllAttachments( void* userdata ) gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - LLViewerJointAttachment* attachment; - for (attachment = avatarp->mAttachmentPoints.getFirstData(); - attachment; - attachment = avatarp->mAttachmentPoints.getNextData()) + for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); + iter != avatarp->mAttachmentPoints.end(); ) { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; LLViewerObject* objectp = attachment->getObject(); if (objectp) { diff --git a/linden/indra/newview/llagent.h b/linden/indra/newview/llagent.h index f87bb02..2a875a0 100644 --- a/linden/indra/newview/llagent.h +++ b/linden/indra/newview/llagent.h @@ -117,6 +117,8 @@ inline bool operator==(const LLGroupData &a, const LLGroupData &b) class LLAgent : public LLObservable { + LOG_CLASS(LLAgent); + public: // When the agent hasn't typed anything for this duration, it leaves the // typing state (for both chat and IM). @@ -839,7 +841,6 @@ private: U8 mGodLevel; LLFrameTimer mFidgetTimer; LLFrameTimer mFocusObjectFadeTimer; - std::set > mFadeObjects; F32 mNextFidgetTime; S32 mCurrentFidget; BOOL mFirstLogin; diff --git a/linden/indra/newview/llanimalcontrols.cpp b/linden/indra/newview/llanimalcontrols.cpp deleted file mode 100644 index f3ba729..0000000 --- a/linden/indra/newview/llanimalcontrols.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/** - * @file llanimalcontrols.cpp - * @brief LLAnimalControl class implementation - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llanimalcontrols.h" -#include "llglheaders.h" -#include "llsphere.h" -#include "llrand.h" -#include "llviewerobject.h" - -/* -//const F32 ANIMAL_CONTROLS_MAX_TENSION_FORCE = 0.99f;// I'll explain in a minute... -//const F32 ANIMAL_CONTROLS_MINIMUM_RADIUS = 0.005f; - -const F32 OPACITY = 1.0f; -const int _X_ = 0; -const int _Y_ = 1; -const int _Z_ = 2; -const F32 BODY_RADIUS = 0.2f; -const F32 HEAD_RADIUS = 0.1f; -const F32 ONE_HALF = 0.5f; - -//----------------------------------------------- -// constructor -//----------------------------------------------- -LLHUDAnimalControls::LLHUDAnimalControls() -: LLHUDObject( LL_HUD_ANIMAL_CONTROLS )// cal the base class and pass this in, K? -{ - mParentObject = NULL; - -}//------------------------------------------------------------------------------ - - - - -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- -// Virtual Server methods... -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- -LLAnimalControlsVirtualServer::LLAnimalControlsVirtualServer() -{ - focusPosition.setVec( 0.0f, 0.0f, 0.0f ); - animalPosition.setVec( 0.0f, 0.0f, 0.0f ); - animalRotation = LLQuaternion::DEFAULT; - fakeClock = 0; - settingFocusPosition = false; - -}//--------------------------------------------------------------------------------- - - - -//--------------------------------------------------------------------------------- -void LLAnimalControlsVirtualServer::update() -{ - fakeClock ++; - - if ( settingFocusPosition ) - { - settingFocusPosition = false; - } - - if ( fakeClock == 20 ) - { - fakeClock = 0; - - settingFocusPosition = true; - - LLMatrix3 bodyRotationMatrix = animalRotation.getMatrix3(); - - LLVector3 forwardDirection = bodyRotationMatrix.getLeftRow(); - LLVector3 leftDirection = bodyRotationMatrix.getFwdRow(); - - forwardDirection.mV[_Z_] = 0.0f; - forwardDirection.normVec(); - - focusPosition = animalPosition + forwardDirection * 5.0f; - - F32 leftRightSpan = 5.0f; - - F32 randomSpan = ll_frand( leftRightSpan ); - - focusPosition += leftDirection * ( - leftRightSpan * ONE_HALF + randomSpan ); - } - -}//------------------------------------------------------------------------------ - - - -//--------------------------------------------------------------------------------- -bool LLAnimalControlsVirtualServer::getSettingFocusPosition() -{ - return settingFocusPosition; - -}//------------------------------------------------------------------------------ - -//--------------------------------------------------------------------------------- -LLVector3 LLAnimalControlsVirtualServer::getFocusPosition() -{ - return focusPosition; - -}//------------------------------------------------------------------------------ - - -//--------------------------------------------------------------------------------- -void LLAnimalControlsVirtualServer::setParentPositionAndRotation( LLVector3 p, LLQuaternion r ) -{ - animalPosition = p; - animalRotation = r; - -}//------------------------------------------------------------------------------ - -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- -// End of Virtual Server methods... -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- - - - - -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- -// Head behavior methods... -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- -LLAnimalControlsHeadBehavior::LLAnimalControlsHeadBehavior() -{ - mPosition.setVec ( 0.0f, 0.0f, 0.0f ); - mFocusPosition.setVec ( 0.0f, 0.0f, 0.0f ); - mBodyPosition.setVec ( 0.0f, 0.0f, 0.0f ); - mRotation = LLQuaternion::DEFAULT; - mEyesBlinking = true; - mEyeBlinkRate = 0.1f; - mBodyRotation = LLQuaternion::DEFAULT; - - LLFlexibleObjectAttributes headFeatherAttributes; - headFeatherAttributes.mAnchorPositionOffset.setVec( 0.0f, 0.0f, 0.1f ); - headFeatherAttributes.mAnchorDirection.setVec( 0.0f, 1.0f, 1.0f ); - headFeatherAttributes.mAnchorDirection.normVec(); - headFeatherAttributes.mColor = LLColor4( 1.0f, 0.4f, 0.0f, 1.0f ); - headFeatherAttributes.mAnchorRadius = 0.01f; - headFeatherAttributes.mLength = 0.4f; - headFeatherAttributes.mEndRadius = 0.06f; - headFeatherAttributes.mRenderStyle = "tube"; - - mFeather.setAttributes( headFeatherAttributes ); - -}//------------------------------------------------------------------ - -//------------------------------------------------------------------ -void LLAnimalControlsHeadBehavior::setBodyPositionAndRotation( LLVector3 p, LLQuaternion r ) -{ - mBodyPosition = p; - mBodyRotation = r; - -}//------------------------------------------------------------------ - -//------------------------------------------------------------------ -void LLAnimalControlsHeadBehavior::setFocusPosition( LLVector3 f ) -{ - mFocusPosition = f; - -}//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -void LLAnimalControlsHeadBehavior::update() -{ - //-------------------------------------------------------------------------- - // Let's get the parent orientation and associated components - //-------------------------------------------------------------------------- - LLQuaternion parentOrientation = mBodyRotation; - LLMatrix3 parentMatrix = parentOrientation.getMatrix3(); - LLVector3 parentForwardDirection = parentMatrix.getLeftRow(); - LLVector3 parentUpwardDirection = parentMatrix.getUpRow(); - - //-------------------------------------------------------------------------- - // head position is based on this - //-------------------------------------------------------------------------- - mPosition = mBodyPosition + parentForwardDirection * 0.5f + parentUpwardDirection * 0.5f; - - //-------------------------------------------------------------------------------------------------- - // let's figure out how the head would have to rotate in order to aim in the focus direction - //-------------------------------------------------------------------------------------------------- - LLVector3 headFocusDirection = mFocusPosition - mPosition; - LLQuaternion headRotationToFocusDirection; - headRotationToFocusDirection.shortestArc( parentForwardDirection, headFocusDirection ); - - //-------------------------------------------------------------------------------------------------- - // Now we rotate the head towards its focus direction - //-------------------------------------------------------------------------------------------------- - mRotation = parentOrientation * headRotationToFocusDirection; - - //-------------------------------------------------------------------------------------------------- - // now, setting the head feather position and orientation, and updating it... - //-------------------------------------------------------------------------------------------------- - mFeather.setParentPositionAndRotationDirectly( mPosition, mRotation ); - mFeather.update(); - -}//------------------------------------------------------------------ - -//------------------------------------------------------------------ - - -{ - //-------------------------------------------------------------------------------------------------- - // let's get the head rotation components... - //-------------------------------------------------------------------------------------------------- - LLMatrix3 headMatrix = mRotation.getMatrix3(); - LLVector3 headForwardDirection = headMatrix.getLeftRow(); - LLVector3 headUpwardDirection = headMatrix.getUpRow(); - LLVector3 headLeftDirection = headMatrix.getFwdRow(); - - //------------------------------------------------------ - // show head ball - //------------------------------------------------------ - glColor4fv( LLColor4( 1.0f, 1.0f, 1.0f, OPACITY ).mV ); - glPushMatrix(); - glTranslatef( mPosition.mV[_X_], mPosition.mV[_Y_], mPosition.mV[_Z_] ); - glScalef( HEAD_RADIUS, HEAD_RADIUS, HEAD_RADIUS ); - gSphere.render(); - glPopMatrix(); - - //------------------------------------------------------ - // show head direction - //------------------------------------------------------ - LLVector3 end = mPosition + headForwardDirection * 0.4f; - glBegin( GL_LINES ); - glVertex3fv( mPosition.mV ); - glVertex3fv( end.mV ); - glEnd(); - - - //------------------------------------------------------ - // show eye behavior - //------------------------------------------------------ - LLVector3 leftEyePosition = mPosition + headForwardDirection * HEAD_RADIUS + headUpwardDirection * HEAD_RADIUS + headLeftDirection * HEAD_RADIUS * ONE_HALF; - LLVector3 rightEyePosition = mPosition + headForwardDirection * HEAD_RADIUS + headUpwardDirection * HEAD_RADIUS - headLeftDirection * HEAD_RADIUS * ONE_HALF; - glColor4fv( LLColor4( 0.0f, 0.0f, 0.0f, 1.0f ).mV ); - - glPushMatrix(); - glTranslatef( leftEyePosition.mV[_X_], leftEyePosition.mV[_Y_], leftEyePosition.mV[_Z_] ); - glScalef( 0.03f, 0.03f, 0.03f ); - gSphere.render(); - glPopMatrix(); - - glPushMatrix(); - glTranslatef( rightEyePosition.mV[_X_], rightEyePosition.mV[_Y_], rightEyePosition.mV[_Z_] ); - glScalef( 0.03f, 0.03f, 0.03f ); - gSphere.render(); - glPopMatrix(); - - //------------------------------------------------------------------ - // render feather - //------------------------------------------------------------------ - mFeather.render(); - -}//------------------------------------------------------------------ - -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- -// End of head behavior methods... -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- - - - - -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- -// Leg behavior methods... -//--------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------- -LLAnimalControlsLegBehavior::LLAnimalControlsLegBehavior() -{ - mBodyPosition.setVec ( 0.0f, 0.0f, 0.0f ); - mHipAnchorPosition.setVec ( 0.0f, 0.0f, 0.0f ); - mBodyRotation = LLQuaternion::DEFAULT; - mWalking = false; - mIsLeft = true; - -}//------------------------------------------------------------- - - -//------------------------------------------------------------------ -void LLAnimalControlsLegBehavior::setBodyPositionAndRotation( LLVector3 p, LLQuaternion r ) -{ - mBodyPosition = p; - mBodyRotation = r; - -}//------------------------------------------------------------------ - - -//--------------------------------------------------------------------------------- -void LLAnimalControlsLegBehavior::update() -{ - -}//------------------------------------------------------------- - - -//--------------------------------------------------------------------------------- -void LLAnimalControlsLegBehavior::render() -{ -}//------------------------------------------------------------- - - - - - - - - -//--------------------------------------------------------------------------------- -void LLHUDAnimalControls::update() -{ - if ( ! mParentObject ) - { - return; - } - - //----------------------------------------------------------------------------------- - // To help in development of this client-side functionality, - // we are pretending that the server is periodically sending us information, - // such as focus position (what we want the animal head to look at) - //----------------------------------------------------------------------------------- - mVirtualServer.setParentPositionAndRotation( mParentObject->getRenderPosition(), mParentObject->getRenderRotation() ); // fake, hacky, temporary, just ignore this. - mVirtualServer.update(); - - // here is where we ask the virtual server stuff. - if ( mVirtualServer.getSettingFocusPosition() ) - { - mHeadBehavior.setFocusPosition( mVirtualServer.getFocusPosition() ); - } - - updateBodyBehavior(); - - mHeadBehavior.setBodyPositionAndRotation ( mParentObject->getPosition(), mParentObject->getRenderRotation() ); - mLeftLegBehavior.setBodyPositionAndRotation ( mParentObject->getPosition(), mParentObject->getRenderRotation() ); - mRightLegBehavior.setBodyPositionAndRotation( mParentObject->getPosition(), mParentObject->getRenderRotation() ); - - mHeadBehavior.update(); - mLeftLegBehavior.update(); - mRightLegBehavior.update(); - -}//------------------------------------------------------------------ - - - - - -//------------------------------------------------------------------ -void LLHUDAnimalControls::updateBodyBehavior() -{ - -}//------------------------------------------------------------------ - - - - -//------------------------------------------------------------------ -void LLHUDAnimalControls::render() -{ - mHeadBehavior.render(); - mLeftLegBehavior.render(); - mRightLegBehavior.render(); - -}//------------------------------------------------------------------ - - - - - - - - - -//------------------------------------------------------------------ -void LLHUDAnimalControls::setAttributes( LLAnimalControlsAttributes a ) -{ - //mAttributes = a; // ???? // how do I do this? - - //mAttributes.mAnchorPositionOffset = a.mAnchorPositionOffset; - //mAttributes.mAnchorDirection = a.mAnchorDirection; - //mAttributes.mAnchorRadius = a.mAnchorRadius; - //mAttributes.mNumSections = a.mNumSections; - //mAttributes.mLength = a.mLength; - //mAttributes.mGravity = a.mGravity; - //mAttributes.mAirFriction = a.mAirFriction; - //mAttributes.mTension = a.mTension; - //mAttributes.mRadiusChange = a.mRadiusChange; - -}//------------------------------------------------------------------ - - - -//------------------------------------------------------------------ -void LLHUDAnimalControls::setParentObject( LLViewerObject * p ) -{ - printf( "Setting parent of animal controls %x to object %x \n", this, p ); - mParentObject = p; - -}//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -LLViewerObject * LLHUDAnimalControls::getParentObject() -{ - return mParentObject; - -}//------------------------------------------------------------------ - - - -//------------------------------------------------------------------ -void LLHUDAnimalControls::markAsDead() -{ - mDead = TRUE; - mParentObject = NULL; - -}//------------------------------------------------------------------ - - - - -*/ - - - diff --git a/linden/indra/newview/llanimalcontrols.h b/linden/indra/newview/llanimalcontrols.h deleted file mode 100644 index 4235d98..0000000 --- a/linden/indra/newview/llanimalcontrols.h +++ /dev/null @@ -1,196 +0,0 @@ -/** - * @file llanimalcontrols.h - * @brief LLAnimalControls class definition - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLANIMALCONTROLS_H -#define LL_LLANIMALCONTROLS_H - -#include "llhudobject.h" -#include "llflexibleobject.h" - -//----------------------------------------------------------------------------------- -// Default setting for the attributes of a animalControls object... -//----------------------------------------------------------------------------------- -//const LLVector3 ANIMAL_CONTROLS_DEFAULT_ANCHOR_DIRECTION = LLVector3::z_axis; -//const LLVector3 ANIMAL_CONTROLS_DEFAULT_ANCHOR_POSITION_OFFSET = LLVector3::zero; -//const LLColor4 ANIMAL_CONTROLS_DEFAULT_COLOR = LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ); -//const F32 ANIMAL_CONTROLS_DEFAULT_GRAVITY = 0.3f; -//const F32 ANIMAL_CONTROLS_DEFAULT_TENSION = 10.0f; -//const F32 ANIMAL_CONTROLS_DEFAULT_AIR_FRICTION = 10.0f; -//const F32 ANIMAL_CONTROLS_DEFAULT_LENGTH = 1.0f; -//const int ANIMAL_CONTROLS_DEFAULT_NUM_SECTIONS = 4; -//const F32 ANIMAL_CONTROLS_DEFAULT_ANCHOR_RADIUS = 0.05f; -//const F32 ANIMAL_CONTROLS_DEFAULT_RADIUS_CHANGE = -0.01f; - -class LLViewerObject; - -/*struct LLAnimalControlsBodyBehavior -{ - LLVector3 mPosition; - LLQuaternion mHipRotation; -}; - -class LLAnimalControlsHeadBehavior -{ - private: - LLVector3 mBodyPosition; - LLQuaternion mBodyRotation; - LLHUDFlexibleObject mFeather; - LLVector3 mPosition; - LLQuaternion mRotation; - LLVector3 mFocusPosition; - bool mEyesBlinking; - F32 mEyeBlinkRate; - - public: - LLAnimalControlsHeadBehavior(); - void setBodyPositionAndRotation( LLVector3 p, LLQuaternion r ); - void setFocusPosition( LLVector3 focusPosition ); - void update(); - void render(); -}; - - -class LLAnimalControlsLegBehavior -{ - private: - LLVector3 mBodyPosition; - LLQuaternion mBodyRotation; - LLVector3 mHipAnchorPosition; - bool mWalking; - bool mIsLeft; - - public: - LLAnimalControlsLegBehavior(); - void setBodyPositionAndRotation( LLVector3 p, LLQuaternion r ); - void update(); - void render(); -}; - - -class LLAnimalControlsVirtualServer -{ - private: - int fakeClock; - LLVector3 focusPosition; - bool settingFocusPosition; - LLVector3 animalPosition; - LLQuaternion animalRotation; - - public: - LLAnimalControlsVirtualServer(); - bool getSettingFocusPosition(); - LLVector3 getFocusPosition(); - void update(); - void setParentPositionAndRotation( LLVector3 p, LLQuaternion q ); -}; - - -//------------------------------------------------- -// This structure is also used in the part of the -// code that creates new animalControls objects. -//------------------------------------------------- -struct LLAnimalControlsAttributes -{ - //LLVector3 mAnchorPositionOffset; - //LLVector3 mAnchorDirection; - //LLColor4 mColor; - //F32 mAnchorRadius; - //S32 mNumSections; - //F32 mLength; - //F32 mGravity; - //F32 mAirFriction; - //F32 mTension; - //F32 mRadiusChange; - bool mUsingBodyControls; - bool mUsingHeadControls; - bool mUsingTailControls; - bool mUsingLegControls; - - //------ the constructor for the structure ------------ - LLAnimalControlsAttributes() - { - //mAnchorPositionOffset = ANIMAL_CONTROLS_DEFAULT_ANCHOR_DIRECTION; - //mAnchorDirection = ANIMAL_CONTROLS_DEFAULT_ANCHOR_POSITION_OFFSET; - //mAnchorRadius = ANIMAL_CONTROLS_DEFAULT_ANCHOR_RADIUS; - //mColor = ANIMAL_CONTROLS_DEFAULT_COLOR; - //mNumSections = ANIMAL_CONTROLS_DEFAULT_NUM_SECTIONS; - //mLength = ANIMAL_CONTROLS_DEFAULT_LENGTH; - //mGravity = ANIMAL_CONTROLS_DEFAULT_GRAVITY; - //mAirFriction = ANIMAL_CONTROLS_DEFAULT_AIR_FRICTION; - //mTension = ANIMAL_CONTROLS_DEFAULT_TENSION; - //mRadiusChange = ANIMAL_CONTROLS_DEFAULT_RADIUS_CHANGE; - } -};// end of attributes structure - - - -//--------------------------------------------------------- -// The LLHUDAnimalControls class -//--------------------------------------------------------- -class LLHUDAnimalControls : public LLHUDObject -{ - public: - LLHUDAnimalControls(); - void setParentObject( LLViewerObject * ); - void setAttributes( LLAnimalControlsAttributes ); - void markAsDead(); - void update(); - LLViewerObject * getParentObject(); - void render(); - - private: - //-------------------------------------- - // private members - //-------------------------------------- - LLViewerObject* mParentObject; - LLAnimalControlsAttributes mAttributes; - LLAnimalControlsHeadBehavior mHeadBehavior; - LLAnimalControlsLegBehavior mLeftLegBehavior; - LLAnimalControlsLegBehavior mRightLegBehavior; - LLAnimalControlsVirtualServer mVirtualServer; - - //-------------------------------------- - // private methods - //-------------------------------------- - void updateVirtualServer(); - void updateBodyBehavior(); - void renderBodyBehavior(); - //void updateLegBehavior(); - //void renderLegBehavior(); - //void updateHeadBehavior(); - //void renderHeadBehavior(); - - friend class LLHUDObject; - -};// end of class definition - -*/ -#endif // LL_LLANIMALCONTROLS_H diff --git a/linden/indra/newview/llappearance.h b/linden/indra/newview/llappearance.h index 582b559..ee8c22c 100644 --- a/linden/indra/newview/llappearance.h +++ b/linden/indra/newview/llappearance.h @@ -32,24 +32,24 @@ #ifndef LL_LLAPPEARANCE_H #define LL_LLAPPEARANCE_H -#include "llskiplist.h" #include "lluuid.h" class LLAppearance { public: LLAppearance() {} - ~LLAppearance() { mParamMap.deleteAllData(); } + ~LLAppearance() { mParamMap.clear(); } - void addParam( S32 id, F32 value ) { mParamMap.addData( id, new F32(value) ); } - F32* getParam( S32 id ) { F32* temp = mParamMap.getIfThere( id ); return temp; } // temp works around an invalid warning. + void addParam( S32 id, F32 value ) { mParamMap[id] = value; } + F32 getParam( S32 id, F32 defval ) { return get_if_there(mParamMap, id, defval ); } void addTexture( S32 te, const LLUUID& uuid ) { if( te < LLVOAvatar::TEX_NUM_ENTRIES ) mTextures[te] = uuid; } const LLUUID& getTexture( S32 te ) { return ( te < LLVOAvatar::TEX_NUM_ENTRIES ) ? mTextures[te] : LLUUID::null; } - void clear() { mParamMap.deleteAllData(); for( S32 i=0; i mParamMap; + typedef std::map param_map_t; + param_map_t mParamMap; LLUUID mTextures[LLVOAvatar::TEX_NUM_ENTRIES]; }; diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index cda3ba5..5baf7b6 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -47,9 +47,11 @@ #include "llpumpio.h" #include "llfloateractivespeakers.h" #include "llimpanel.h" +#include "llmimetypes.h" #include "llstartup.h" #include "llfocusmgr.h" #include "llviewerjoystick.h" +#include "llares.h" #include "llcurl.h" #include "llfloatersnapshot.h" #include "llviewerwindow.h" @@ -59,6 +61,7 @@ #include "llworldmap.h" #include "llmutelist.h" #include "llurldispatcher.h" +#include "llurlhistory.h" #include "llweb.h" #include "llsecondlifeurls.h" @@ -76,7 +79,6 @@ #include "llnotify.h" -#include "llmediaengine.h" #include "llviewerkeyboard.h" #include "lllfsthread.h" #include "llworkerthread.h" @@ -97,9 +99,11 @@ #include "llviewermenu.h" #include "llselectmgr.h" #include "lltracker.h" -#include "llmozlib.h" #include "llviewerparcelmgr.h" #include "llworldmapview.h" +#include "llpostprocess.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" #include "lldebugview.h" #include "llconsole.h" @@ -127,6 +131,9 @@ #include "llframestats.h" #include "llagentpilot.h" #include "llsrv.h" +#include "llvovolume.h" +#include "llflexibleobject.h" +#include "llvosurfacepatch.h" // includes for idle() idleShutdown() #include "llviewercontrol.h" @@ -169,21 +176,6 @@ static char** gTempArgV; #if LL_WINDOWS && LL_LCD_COMPILE #include "lllcd.h" #endif -// -#if LL_QUICKTIME_ENABLED - #if LL_DARWIN - #include - #else - // quicktime specific includes - #include "MacTypes.h" - #include "QTML.h" - #include "Movies.h" - #include "FixMath.h" - #endif -#endif -// -////// - //---------------------------------------------------------------------------- // viewer.cpp - these are only used in viewer, should be easily moved. @@ -228,10 +220,6 @@ extern BOOL gbCapturing; extern BOOL gRandomizeFramerate; extern BOOL gPeriodicSlowFrame; -#if LL_GSTREAMER_ENABLED -void UnloadGStreamer(); -#endif - //////////////////////////////////////////////////////////// // All from the last globals push... bool gVerifySSLCert = true; @@ -257,6 +245,7 @@ BOOL gShowObjectUpdates = FALSE; BOOL gLogMessages = FALSE; std::string gChannelName = LL_CHANNEL; BOOL gUseAudio = TRUE; +BOOL gUseQuickTime = TRUE; LLString gCmdLineFirstName; LLString gCmdLineLastName; LLString gCmdLinePassword; @@ -394,7 +383,6 @@ static const char USAGE[] = "\n" " -set specify the value of a particular\n" " configuration variable that\n" " overrides all other settings\n" -" -user specify userserver in dotted quad\n" #if !LL_RELEASE_FOR_DOWNLOAD " -sim specify the simulator ip address\n" #endif @@ -477,8 +465,6 @@ static void saved_settings_to_globals() LLCOMBOBOX_WIDTH = 128; LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); - - LLVOSky::sNighttimeBrightness = gSavedSettings.getF32("RenderNightBrightness"); LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor"); @@ -511,6 +497,11 @@ static void saved_settings_to_globals() gHandleKeysAsync = gSavedSettings.getBOOL("AsyncKeyboard"); LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips"); + LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderUseFBO"); + LLVOAvatar::sUseImpostors = gSavedSettings.getBOOL("RenderUseImpostors"); + LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor"); + LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //sqaure lod factor to get exponential range of [1,4] + #if LL_VECTORIZE if (gSysCPU.hasAltivec()) { @@ -664,21 +655,6 @@ int parse_args(int argc, char **argv) gGridChoice = GRID_INFO_YAMI; sprintf(gGridName,"%s", gGridInfo[gGridChoice].mName); } - else if (!strcmp(argv[j], "-user") && (++j < argc)) - { - if (!strcmp(argv[j], "-")) - { - gGridChoice = GRID_INFO_LOCAL; - snprintf(gGridName, MAX_STRING, "%s", LOOPBACK_ADDRESS_STRING); // Flawfinder: ignore - } - else - { - gGridChoice = GRID_INFO_OTHER; - ip_string.assign( argv[j] ); - LLString::trim(ip_string); - snprintf(gGridName, MAX_STRING, "%s", ip_string.c_str()); // Flawfinder: ignore - } - } else if (!strcmp(argv[j], "-loginpage") && (++j < argc)) { LLAppViewer::instance()->setLoginPage(utf8str_trim(argv[j])); @@ -1046,13 +1022,6 @@ bool LLAppViewer::init() gCurrentVersion = llformat("%s %d.%d.%d.%d", gChannelName.c_str(), LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VERSION_BUILD ); // - // Load the feature tables - // - llinfos << "Loading feature tables." << llendl; - - gFeatureManagerp->loadFeatureTables(); - gFeatureManagerp->initCPUFeatureMasks(); - // Merge with the command line overrides gSavedSettings.applyOverrides(gCommandLineSettings); @@ -1196,6 +1165,9 @@ bool LLAppViewer::init() LLAgent::parseTeleportMessages("teleport_strings.xml"); + // load MIME type -> media impl mappings + LLMIMETypes::parseMIMETypes( "mime_types.xml" ); + mCrashBehavior = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING); LLVectorPerformanceOptions::initClass(); @@ -1294,26 +1266,64 @@ bool LLAppViewer::init() llinfos << "Viewer Digest: " << gViewerDigest << llendl; // If we don't have the right GL requirements, exit. - // BUG: This should just be changed to a generic GL "Not good enough" flag - if (!gGLManager.mHasMultitexture && !gNoRender) - { - std::ostringstream msg; - msg << - "You do not appear to have the proper hardware requirements " - "for " << gSecondLife << ". " << gSecondLife << " requires an OpenGL graphics " - "card that has multitexture support. If this is the case, " - "you may want to make sure that you have the latest drivers for " - "your graphics card, and service packs and patches for your " - "operating system.\n" - "If you continue to have problems, please go to: " - "www.secondlife.com/support "; + if (!gGLManager.mHasRequirements && !gNoRender) + { + // can't use an alert here since we're existing and + // all hell breaks lose. OSMessageBox( - msg.str().c_str(), + LLAlertDialog::getTemplateMessage("UnsupportedGLRequirements").c_str(), NULL, OSMB_OK); return 0; } + // alert the user if they are using unsupported hardware + if(!gSavedSettings.getBOOL("AlertedUnsupportedHardware")) + { + bool unsupported = false; + LLString::format_map_t args; + LLString minSpecs; + + // get cpu data from xml + std::stringstream minCPUString(LLAlertDialog::getTemplateMessage("UnsupportedCPUAmount")); + S32 minCPU = 0; + minCPUString >> minCPU; + + // get RAM data from XML + std::stringstream minRAMString(LLAlertDialog::getTemplateMessage("UnsupportedRAMAmount")); + U64 minRAM = 0; + minRAMString >> minRAM; + minRAM = minRAM * 1024 * 1024; + + if(!gFeatureManagerp->isGPUSupported()) + { + minSpecs += LLAlertDialog::getTemplateMessage("UnsupportedGPU"); + minSpecs += "\n"; + unsupported = true; + } + if(gSysCPU.getMhz() < minCPU) + { + minSpecs += LLAlertDialog::getTemplateMessage("UnsupportedCPU"); + minSpecs += "\n"; + unsupported = true; + } + if(gSysMemory.getPhysicalMemoryClamped() < minRAM) + { + minSpecs += LLAlertDialog::getTemplateMessage("UnsupportedRAM"); + minSpecs += "\n"; + unsupported = true; + } + + if(unsupported) + { + args["MINSPECS"] = minSpecs; + gViewerWindow->alertXml("UnsupportedHardware", args ); + + // turn off flag + gSavedSettings.setBOOL("AlertedUnsupportedHardware", TRUE); + } + } + // Save the current version to the prefs file gSavedSettings.setString("LastRunVersion", gCurrentVersion); @@ -1332,7 +1342,7 @@ bool LLAppViewer::mainLoop() // Create IO Pump to use for HTTP Requests. gServicePump = new LLPumpIO(gAPRPoolp); LLHTTPClient::setPump(*gServicePump); - LLHTTPClient::setCABundle(gDirUtilp->getCAFile()); + LLCurl::setCAFile(gDirUtilp->getCAFile()); // initialize voice stuff here gLocalSpeakerMgr = new LLLocalSpeakerMgr(); @@ -1371,6 +1381,7 @@ bool LLAppViewer::mainLoop() debugTime.reset(); } #endif + if (!LLApp::isExiting()) { // Scan keyboard for movement keys. Command keys and typing @@ -1391,10 +1402,14 @@ bool LLAppViewer::mainLoop() { LLFastTimer t3(LLFastTimer::FTM_IDLE); idle(); - LLCurl::process(); - // this pump is necessary to make the login screen show up - gServicePump->pump(); - gServicePump->callback(); + + { + LLFastTimer t4(LLFastTimer::FTM_PUMP); + gAres->process(); + // this pump is necessary to make the login screen show up + gServicePump->pump(); + gServicePump->callback(); + } } if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) @@ -1468,7 +1483,7 @@ bool LLAppViewer::mainLoop() const F64 min_frame_time = 0.0; //(.0333 - .0010); // max video frame rate = 30 fps const F64 min_idle_time = 0.0; //(.0010); // min idle time = 1 ms - const F64 max_idle_time = run_multiple_threads ? min_idle_time : .005; // 5 ms + const F64 max_idle_time = run_multiple_threads ? min_idle_time : llmin(.005*10.0*gFrameTimeSeconds, 0.005); // 5 ms a second idleTimer.reset(); while(1) { @@ -1596,32 +1611,6 @@ bool LLAppViewer::cleanup() llwarns << "Hack, skipping audio engine cleanup" << llendflush; #endif - - // moved to main application shutdown for now because it's non-trivial and only needs to be done once - // (even though it goes against the media framework design) - - LLMediaEngine::cleanupClass(); - -#if LL_QUICKTIME_ENABLED - if (gQuickTimeInitialized) - { - // clean up media stuff - llinfos << "Cleaning up QuickTime" << llendl; - ExitMovies (); - #if LL_WINDOWS - // Only necessary/available on Windows. - TerminateQTML (); - #endif - } - llinfos << "Quicktime cleaned up" << llendflush; -#endif - -#if LL_GSTREAMER_ENABLED - llinfos << "Cleaning up GStreamer" << llendl; - UnloadGStreamer(); - llinfos << "GStreamer cleaned up" << llendflush; -#endif - llinfos << "Cleaning up feature manager" << llendflush; delete gFeatureManagerp; gFeatureManagerp = NULL; @@ -1680,21 +1669,19 @@ bool LLAppViewer::cleanup() LLSelectMgr::cleanupGlobals(); LLViewerObject::cleanupVOClasses(); - + + LLWaterParamManager::cleanupClass(); + LLWLParamManager::cleanupClass(); + LLPostProcess::cleanupClass(); + LLTracker::cleanupInstance(); -#if LL_LIBXUL_ENABLED - // this must be done after floater cleanup (delete gViewerWindow) since - // floaters potentially need the manager to destroy their contents. - LLMozLib::getInstance()->reset(); -#endif - // *FIX: This is handled in LLAppViewerWin32::cleanup(). // I'm keeping the comment to remember its order in cleanup, // in case of unforseen dependency. -//#if LL_WINDOWS -// gDXHardware.cleanup(); -//#endif // LL_WINDOWS + //#if LL_WINDOWS + // gDXHardware.cleanup(); + //#endif // LL_WINDOWS #if LL_WINDOWS && LL_LCD_COMPILE // shut down the LCD window on a logitech keyboard, if there is one @@ -1751,6 +1738,9 @@ bool LLAppViewer::cleanup() gColors.cleanup(); gCrashSettings.cleanup(); + // Save URL history file + LLURLHistory::saveFile("url_history.xml"); + if (gMuteListp) { // save mute list @@ -1829,7 +1819,7 @@ bool LLAppViewer::cleanup() end_messaging_system(); // *NOTE:Mani - The following call is not thread safe. - LLCurl::cleanup(); + LLCurl::cleanupClass(); // If we're exiting to launch an URL, do that here so the screen // is at the right resolution before we launch IE. @@ -1933,17 +1923,6 @@ bool LLAppViewer::initEarlyConfiguration() { sprintf(gGridName,"%s", gGridInfo[GRID_INFO_ARUNA].mName); } - else if (!strcmp(argv[j], "-user") && (++j < argc)) - { - if (!strcmp(argv[j], "-")) - { - snprintf(gGridName, MAX_STRING, "%s", LOOPBACK_ADDRESS_STRING); // Flawfinder: ignore - } - else - { - snprintf(gGridName, MAX_STRING, "%s", argv[j]); // Flawfinder: ignore - } - } else if (!strcmp(argv[j], "-multiple")) { // Hack to detect -multiple so we can disable the marker file check (which will always fail) @@ -2390,18 +2369,33 @@ bool LLAppViewer::initWindow() gViewerWindow->getWindow()->setNativeAspectRatio(gSavedSettings.getF32("FullScreenAspectRatio")); } + if (!gNoRender) + { + // + // Initialize GL stuff + // + + // Set this flag in case we crash while initializing GL + gSavedSettings.setBOOL("RenderInitError", TRUE); + gSavedSettings.saveToFile( gSettingsFileName, TRUE ); + + gPipeline.init(); + stop_glerror(); + gViewerWindow->initGLDefaults(); + + gSavedSettings.setBOOL("RenderInitError", FALSE); + gSavedSettings.saveToFile( gSettingsFileName, TRUE ); + } + LLUI::sWindow = gViewerWindow->getWindow(); LLAlertDialog::parseAlerts("alerts.xml"); LLNotifyBox::parseNotify("notify.xml"); - LLMediaEngine::initClass(); - - // - // Clean up the feature manager lookup table - settings were updated - // in the LLViewerWindow constructor - // - gFeatureManagerp->cleanupFeatureTables(); + // *TODO - remove this when merging into release + // DON'T Clean up the feature manager lookup table - settings are needed + // for setting the graphics level. + //gFeatureManagerp->cleanupFeatureTables(); // Show watch cursor gViewerWindow->setCursor(UI_CURSOR_WAIT); @@ -3206,6 +3200,14 @@ void LLAppViewer::loadNameCache() std::string name_cache; name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache"); + llifstream cache_file(name_cache.c_str()); + if(cache_file.is_open()) + { + if(gCacheName->importFile(cache_file)) return; + } + + // Try to load from the legacy format. This should go away after a + // while. Phoenix 2008-01-30 FILE* name_cache_fp = LLFile::fopen(name_cache.c_str(), "r"); // Flawfinder: ignore if (name_cache_fp) { @@ -3220,11 +3222,10 @@ void LLAppViewer::saveNameCache() std::string name_cache; name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache"); - FILE* name_cache_fp = LLFile::fopen(name_cache.c_str(), "w"); // Flawfinder: ignore - if (name_cache_fp) + llofstream cache_file(name_cache.c_str()); + if(cache_file.is_open()) { - gCacheName->exportFile(name_cache_fp); - fclose(name_cache_fp); + gCacheName->exportFile(cache_file); } } @@ -3315,8 +3316,7 @@ void LLAppViewer::idle() if (!gDisconnected) { LLFastTimer t(LLFastTimer::FTM_NETWORK); - - // Update spaceserver timeinfo + // Update spaceserver timeinfo gWorldp->setSpaceTimeUSec(gWorldp->getSpaceTimeUSec() + (U32)(dt_raw * SEC_TO_MICROSEC)); @@ -3419,8 +3419,6 @@ void LLAppViewer::idle() // Update statistics for this frame update_statistics(gFrameCount); - - gViewerWindow->updateDebugText(); } //////////////////////////////////////// @@ -3450,11 +3448,7 @@ void LLAppViewer::idle() // LLCoordGL current_mouse = gViewerWindow->getCurrentMouse(); -// BOOL was_in_prelude = gAgent.inPrelude(); - { - //LLFastTimer t(LLFastTimer::FTM_TEMP1); - // After agent and camera moved, figure out if we need to // deselect objects. gSelectMgr->deselectAllIfTooFar(); @@ -3462,19 +3456,6 @@ void LLAppViewer::idle() } { - LLFastTimer t(LLFastTimer::FTM_RESET_DRAWORDER); - - ////////////////////////////////////////////// - // - // Clear draw orders - // - // Should actually be done after render, but handlePerFrameHover actually does a "render" - // to do its selection. - // - - gPipeline.resetDrawOrders(); - } - { // Handle pending gesture processing gGestureManager.update(); @@ -3491,11 +3472,6 @@ void LLAppViewer::idle() } } - { - LLFastTimer t(LLFastTimer::FTM_UPDATE_SKY); - gSky.updateSky(); - } - ////////////////////////////////////// // // Deletes objects... @@ -3523,8 +3499,6 @@ void LLAppViewer::idle() // { - //LLFastTimer t(LLFastTimer::FTM_TEMP3); - gFrameStats.start(LLFrameStats::UPDATE_EFFECTS); gSelectMgr->updateEffects(); gHUDManager->cleanupEffects(); @@ -3599,16 +3573,18 @@ void LLAppViewer::idle() // gFrameStats.start(LLFrameStats::IMAGE_UPDATE); - LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE); - - LLViewerImage::updateClass(gCamera->getVelocityStat()->getMean(), - gCamera->getAngularVelocityStat()->getMean()); + { + LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE); + + LLViewerImage::updateClass(gCamera->getVelocityStat()->getMean(), + gCamera->getAngularVelocityStat()->getMean()); - gBumpImageList.updateImages(); // must be called before gImageList version so that it's textures are thrown out first. + gBumpImageList.updateImages(); // must be called before gImageList version so that it's textures are thrown out first. - const F32 max_image_decode_time = 0.005f; // 5 ms decode time - gImageList.updateImages(max_image_decode_time); - stop_glerror(); + const F32 max_image_decode_time = llmin(0.005f, 0.005f*10.f*gFrameIntervalSeconds); // 50 ms/second decode time (no more than 5ms/frame) + gImageList.updateImages(max_image_decode_time); + stop_glerror(); + } ////////////////////////////////////// // @@ -3618,6 +3594,7 @@ void LLAppViewer::idle() if (!gNoRender) { + LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE); gFrameStats.start(LLFrameStats::UPDATE_MOVE); gPipeline.updateMove(); diff --git a/linden/indra/newview/llappviewerwin32.cpp b/linden/indra/newview/llappviewerwin32.cpp index 9c416a1..b665cb4 100644 --- a/linden/indra/newview/llappviewerwin32.cpp +++ b/linden/indra/newview/llappviewerwin32.cpp @@ -127,7 +127,14 @@ LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *excepti return retval; } -int APIENTRY WinMain(HINSTANCE hInstance, + +#if DEBUGGING_SEH_FILTER +# define WINMAIN DebuggingWinMain +#else +# define WINMAIN WinMain +#endif + +int APIENTRY WINMAIN(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) @@ -207,6 +214,27 @@ int APIENTRY WinMain(HINSTANCE hInstance, return 0; } +#if DEBUGGING_SEH_FILTER +// The compiler doesn't like it when you use __try/__except blocks +// in a method that uses object destructors. Go figure. +// This winmain just calls the real winmain inside __try. +// The __except calls our exception filter function. For debugging purposes. +int APIENTRY WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) +{ + __try + { + WINMAIN(hInstance, hPrevInstance, lpCmdLine, nCmdShow); + } + __except( viewer_windows_exception_handler( GetExceptionInformation() ) ) + { + _tprintf( _T("Exception handled.\n") ); + } +} +#endif + void LLAppViewerWin32::disableWinErrorReporting() { const char win_xp_string[] = "Microsoft Windows XP"; diff --git a/linden/indra/newview/llbox.cpp b/linden/indra/newview/llbox.cpp index bbab7c4..49dacc1 100644 --- a/linden/indra/newview/llbox.cpp +++ b/linden/indra/newview/llbox.cpp @@ -34,6 +34,7 @@ #include "llbox.h" #include "llgl.h" +#include "llglimmediate.h" #include "llglheaders.h" LLBox gBox; @@ -61,7 +62,7 @@ void LLBox::cleanupGL() void LLBox::renderface(S32 which_face) { - static F32 normals[6][3] = + /*static F32 normals[6][3] = { {-1.0f, 0.0f, 0.0f}, { 0.0f, 1.0f, 0.0f}, @@ -69,7 +70,7 @@ void LLBox::renderface(S32 which_face) { 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, { 0.0f, 0.0f, -1.0f} - }; + };*/ static S32 faces[6][4] = { {0, 1, 2, 3}, @@ -80,17 +81,17 @@ void LLBox::renderface(S32 which_face) {7, 4, 0, 3} }; - glBegin(GL_QUADS); - glNormal3fv(&normals[which_face][0]); - glTexCoord2f(1,0); - glVertex3fv(&mVertex[ faces[which_face][0] ][0]); - glTexCoord2f(1,1); - glVertex3fv(&mVertex[ faces[which_face][1] ][0]); - glTexCoord2f(0,1); - glVertex3fv(&mVertex[ faces[which_face][2] ][0]); - glTexCoord2f(0,0); - glVertex3fv(&mVertex[ faces[which_face][3] ][0]); - glEnd(); + gGL.begin(GL_QUADS); + //gGL.normal3fv(&normals[which_face][0]); + gGL.texCoord2f(1,0); + gGL.vertex3fv(&mVertex[ faces[which_face][0] ][0]); + gGL.texCoord2f(1,1); + gGL.vertex3fv(&mVertex[ faces[which_face][1] ][0]); + gGL.texCoord2f(0,1); + gGL.vertex3fv(&mVertex[ faces[which_face][2] ][0]); + gGL.texCoord2f(0,0); + gGL.vertex3fv(&mVertex[ faces[which_face][3] ][0]); + gGL.end(); } void LLBox::render() @@ -125,4 +126,5 @@ void LLBox::render() renderface(2); renderface(1); renderface(0); + gGL.flush(); } diff --git a/linden/indra/newview/llcallingcard.cpp b/linden/indra/newview/llcallingcard.cpp index 38d9beb..86e0bfb 100644 --- a/linden/indra/newview/llcallingcard.cpp +++ b/linden/indra/newview/llcallingcard.cpp @@ -193,7 +193,7 @@ bool LLAvatarTracker::haveTrackingInfo() LLVector3d LLAvatarTracker::getGlobalPos() { - if(!mTrackedAgentValid) return LLVector3d(); + if(!mTrackedAgentValid || !mTrackingData) return LLVector3d(); LLVector3d global_pos; LLViewerObject* object = gObjectList.findObject(mTrackingData->mAvatarID); @@ -266,9 +266,8 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds) { using namespace std; - U32 new_buddy_count = 0; - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + U32 new_buddy_count = 0; + std::string first,last; LLUUID agent_id; for(buddy_map_t::const_iterator itr = buds.begin(); itr != buds.end(); ++itr) { @@ -453,8 +452,10 @@ void LLAvatarTracker::empowerList(const buddy_map_t& list, bool grant) void LLAvatarTracker::deleteTrackingData() { - delete mTrackingData; + //make sure mTrackingData never points to freed memory + LLTrackingData* tmp = mTrackingData; mTrackingData = NULL; + delete tmp; } void LLAvatarTracker::findAgent() @@ -588,8 +589,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg) { if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS) { - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + std::string first, last; LLStringBase::format_map_t args; if(gCacheName->getName(agent_id, first, last)) { @@ -646,8 +646,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) setBuddyOnline(agent_id,online); if(chat_notify) { - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + std::string first, last; if(gCacheName->getName(agent_id, first, last)) { notify = TRUE; @@ -801,8 +800,6 @@ bool LLCollectProxyBuddies::operator()(const LLUUID& buddy_id, LLRelationship* b bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy) { - mFirst[0] = '\0'; - mLast[0] = '\0'; gCacheName->getName(buddy_id, mFirst, mLast); std::ostringstream fullname; fullname << mFirst << " " << mLast; @@ -816,8 +813,6 @@ bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship bool LLCollectOnlineBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy) { - mFirst[0] = '\0'; - mLast[0] = '\0'; gCacheName->getName(buddy_id, mFirst, mLast); std::ostringstream fullname; fullname << mFirst << " " << mLast; @@ -831,8 +826,6 @@ bool LLCollectOnlineBuddies::operator()(const LLUUID& buddy_id, LLRelationship* bool LLCollectAllBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy) { - mFirst[0] = '\0'; - mLast[0] = '\0'; gCacheName->getName(buddy_id, mFirst, mLast); std::ostringstream fullname; fullname << mFirst << " " << mLast; diff --git a/linden/indra/newview/llcallingcard.h b/linden/indra/newview/llcallingcard.h index 664c293..aca5099 100644 --- a/linden/indra/newview/llcallingcard.h +++ b/linden/indra/newview/llcallingcard.h @@ -212,8 +212,8 @@ public: virtual bool operator()(const LLUUID& buddy_id, LLRelationship* buddy); typedef std::map buddy_map_t; buddy_map_t mMappable; - char mFirst[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - char mLast[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ + std::string mFirst; + std::string mLast; }; // collect dictionary sorted map of name -> agent_id for every online buddy @@ -225,8 +225,8 @@ public: virtual bool operator()(const LLUUID& buddy_id, LLRelationship* buddy); typedef std::map buddy_map_t; buddy_map_t mOnline; - char mFirst[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char mLast[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + std::string mFirst; + std::string mLast; }; // collect dictionary sorted map of name -> agent_id for every buddy, @@ -240,8 +240,8 @@ public: typedef std::map buddy_map_t; buddy_map_t mOnline; buddy_map_t mOffline; - char mFirst[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char mLast[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + std::string mFirst; + std::string mLast; }; #endif // LL_LLCALLINGCARD_H diff --git a/linden/indra/newview/llcameraview.cpp b/linden/indra/newview/llcameraview.cpp index 0c82374..80e64f3 100644 --- a/linden/indra/newview/llcameraview.cpp +++ b/linden/indra/newview/llcameraview.cpp @@ -62,7 +62,7 @@ LLFloaterCamera::LLFloaterCamera(const std::string& name) { setIsChrome(TRUE); - S32 top = mRect.getHeight(); + S32 top = getRect().getHeight(); S32 bottom = 0; S32 left = 16; @@ -181,7 +181,7 @@ LLFloaterJoystick::~LLFloaterJoystick() void LLFloaterJoystick::draw() { - for (U32 i = 0; i < 6; i++) + for (U32 i = 0; i < 8; i++) { F32 value = gViewerWindow->getWindow()->getJoystickAxis(i); mAxis[i]->addValue(value*gFrameIntervalSeconds); @@ -212,10 +212,10 @@ void LLFloaterJoystick::show(void*) gUICtrlFactory->buildFloater(floater, "floater_joystick.xml"); F32 range = gSavedSettings.getBOOL("FlycamAbsolute") ? 1024.f : 2.f; - LLUIString axis = floater->childGetText("Axis"); - LLUIString joystick = floater->childGetText("JoystickMonitor"); + LLUIString axis = floater->getUIString("Axis"); + LLUIString joystick = floater->getUIString("JoystickMonitor"); - LLView* child = floater->getChildByName("ZoomLabel"); + LLView* child = floater->getChild("ZoomLabel"); LLRect rect; if (child) @@ -228,7 +228,7 @@ void LLFloaterJoystick::show(void*) floater->mAxisStats = new LLStatView("axis values", joystick, "", rect); floater->mAxisStats->setDisplayChildren(TRUE); - for (U32 i = 0; i < 6; i++) + for (U32 i = 0; i < 8; i++) { axis.setArg("[NUM]", llformat("%d", i)); floater->mAxis[i] = new LLStat(4); diff --git a/linden/indra/newview/llcameraview.h b/linden/indra/newview/llcameraview.h index e64ac56..ebe3cc6 100644 --- a/linden/indra/newview/llcameraview.h +++ b/linden/indra/newview/llcameraview.h @@ -83,8 +83,8 @@ public: protected: static LLFloaterJoystick* sInstance; LLStatView* mAxisStats; - LLStat* mAxis[6]; - LLStatBar* mAxisBar[6]; + LLStat* mAxis[8]; + LLStatBar* mAxisBar[8]; }; extern LLFloaterCamera *gFloaterCamera; diff --git a/linden/indra/newview/llcape.cpp b/linden/indra/newview/llcape.cpp deleted file mode 100644 index c054ccb..0000000 --- a/linden/indra/newview/llcape.cpp +++ /dev/null @@ -1,642 +0,0 @@ -/** - * @file llcape.cpp - * @brief LLVOCloth class implementation - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llcape.h" - -#include "llglheaders.h" -#include "llsphere.h" -#include "llrand.h" -#include "llvoavatar.h" -#include "llagent.h" -#include "llviewerobject.h" -#include "llimagegl.h" -#include "llviewerimagelist.h" -#include "llviewercontrol.h" -#include "llflexibleobject.h" - -const int _X_ = 0; -const int _Y_ = 1; -const int _Z_ = 2; -const F32 ONE_HALF = 0.5f; -const F32 STRAND_VISUALIZATION_ANCHOR_BALL_RADIUS = 0.01f; - -//----------------------------------------------- -// constructor -//----------------------------------------------- -LLVOCloth::LLVOCloth(const LLUUID &id, const LLPCode type, LLViewerRegion *regionp) - : LLViewerObject(id, type, regionp) -{ - mAttributes.mTextureFileName = CLOTH_DEFAULT_TEXTURE_FILENAME; - mAttributes.mTextureIndex = CLOTH_DEFAULT_TEXTURE_INDEX; - mAttributes.mNumStrands = CLOTH_DEFAULT_NUM_STRANDS; - mAttributes.mNumSegments = CLOTH_DEFAULT_NUM_SEGMENTS; - mAttributes.mVisualizeStrands = CLOTH_DEFAULT_VISUALIZE_STRANDS; - mAttributes.mVisualizeAvCollisionSphere = CLOTH_DEFAULT_VISUALIZE_COLLISION_SPHERE; - mAttributes.mWidth = CLOTH_DEFAULT_WIDTH; - mAttributes.mLength = CLOTH_DEFAULT_LENGTH; - mAttributes.mPitch = CLOTH_DEFAULT_PITCH; - mAttributes.mGravity = CLOTH_DEFAULT_GRAVITY; - mAttributes.mTension = CLOTH_DEFAULT_TENSION; - mAttributes.mAirFriction = CLOTH_DEFAULT_AIR_FRICTION; - mAttributes.mWindSensitivity = CLOTH_DEFAULT_WIND_SENSITIVITY; - mAttributes.mCircleWrapAmount = CLOTH_DEFAULT_CIRCLE_WRAP_AMOUNT; - mAttributes.mUsingAvatarCollisionSphere = CLOTH_DEFAULT_USING_AVATAR_COLLISION_SPHERE; - //mAttributes.mAvatarCollisionSpherePositionOffset = CLOTH_DEFAULT_AVATAR_COLLISION_SPHERE_POSITION_OFFSET; - mAttributes.mAvatarCollisionSphereRadius = CLOTH_DEFAULT_AVATAR_COLLISION_SPHERE_RADIUS; - mAttributes.mAvatarCollisionSphereRightOffset = CLOTH_DEFAULT_AVATAR_COLLISION_SPHERE_RIGHT_OFFSET; - mAttributes.mAvatarCollisionSphereUpOffset = CLOTH_DEFAULT_AVATAR_COLLISION_SPHERE_UP_OFFSET; - mAttributes.mAvatarCollisionSphereForwardOffset = CLOTH_DEFAULT_AVATAR_COLLISION_SPHERE_FORWARD_OFFSET; - - generateStrands(); - -}//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// this method is only called when attributes of the cloth are set, -// and so it is not so important to try optimized it. -//------------------------------------------------------------------------------ -void LLVOCloth::generateStrands() -{ - LLFlexibleObjectData strandAttributes; - - bool oddNumStrands = (bool)( mAttributes.mNumStrands % 2 ); - F32 piOver180 = F_PI / 180.0f; - F32 x = 0.0f; - F32 y = 0.0f; - F32 startAngle = -mAttributes.mCircleWrapAmount * 180.0f; - F32 angleDelta = ( mAttributes.mCircleWrapAmount * 360.0f ) / (F32)( mAttributes.mNumStrands - 1 ); - F32 subWidth = mAttributes.mWidth / (F32)( mAttributes.mNumStrands - 1 ); - - F32 angle = 0.0f; - - if ( mAttributes.mNumStrands > 2 ) - { - angle = startAngle; - } - - //------------------------------------------- - // displace x and y to start the process of - // iterating through the positional offsets - //------------------------------------------- - if ( ! oddNumStrands ) - { - y += subWidth * ONE_HALF; - } - - int half = mAttributes.mNumStrands / 2; - for ( int s=0; s 2 ) - { - angle += angleDelta; - } - - F32 r = angle * piOver180; - x -= subWidth * sin(r); - y -= subWidth * cos(r); - } - - - if ( mAttributes.mNumStrands > 2 ) - { - angle = startAngle; - } - else - { - angle = 0.0f; - } - - - for ( int s=0; s 2 ) - { - angle += angleDelta; - } - - F32 r = angle * piOver180; - F32 dX = subWidth * sin(r); - F32 dY = subWidth * cos(r); - x += dX; - y += dY; - - //-------------------------------------------------- - // set anchor directions - //-------------------------------------------------- - LLVector3 perpendicular; - perpendicular.setVec( -dY, dX, 0.0f ); - perpendicular.normVec(); - - //F32 pitchRadian = mAttributes.mPitch * F_PI_BY_TWO; - - /*strandAttributes.mAnchorDirection.setVec - ( - perpendicular.mV[_X_] * cos( pitchRadian ), - perpendicular.mV[_Y_] * cos( pitchRadian ), - sin( pitchRadian ) - );*/ - - //strandAttributes.mAnchorDirection.normVec(); // just to be sure... - - /*strandAttributes.mTension = mAttributes.mTension; - strandAttributes.mSimulateLOD = mAttributes.mNumSegments; - strandAttributes.mGravity = mAttributes.mGravity; - strandAttributes.mAirFriction = mAttributes.mAirFriction; - strandAttributes.mWindSensitivity = mAttributes.mWindSensitivity; - strandAttributes.mUsingCollisionSphere = mAttributes.mUsingAvatarCollisionSphere;*/ - } - -}//------------------------------------------------------------------------------ - - - - - - -//--------------------------------------------------------------------------------- -void LLVOCloth::update() -{ - if ( mAttributes.mUsingAvatarCollisionSphere ) - { - LLVector3 offset; - offset.setVec - ( - mAttributes.mAvatarCollisionSphereForwardOffset, // in this strange world, forward is along X (I think that's kinda wierd) - mAttributes.mAvatarCollisionSphereRightOffset, - mAttributes.mAvatarCollisionSphereUpOffset - ); - - //------------------------------------------------------ - // rotate into avatar space - //------------------------------------------------------ - offset *= gAgent.getAvatarObject()->getRenderRotation(); - - mAvatarCollisionSpherePosition = gAgent.getAvatarObject()->getRenderPosition() + offset; - } - - if ( mParent ) - { - // update the attachment of the strands to their parent object, and let them flop around! - for ( int s=0; ssetParentPositionAndRotationDirectly( getRenderPosition(), getRenderRotation() ); - //mStrand[s]->update(); - - if ( mAttributes.mUsingAvatarCollisionSphere ) - { - // it's not efficient to create the exact same collision - // sphere for every strand, but it'll do for the time being - mStrand[s]->setCollisionSphere( mAvatarCollisionSpherePosition, mAttributes.mAvatarCollisionSphereRadius ); - } - } - } - -}//------------------------------------------------------------------ - - - - -//------------------------------------------------------------------ -void LLVOCloth::render() -{ - if ( mAttributes.mTextureFileName != "not_specified" ) - { - LLViewerImage* theTexture = gImageList.getImage( LLUUID( gViewerArt.getString( mAttributes.mTextureFileName ) ), MIPMAP_FALSE, TRUE); - if ( theTexture ) - { - /*if ( mAttributes.mVisualizeAvCollisionSphere ) - { - for ( int s=0; srenderCollisionSphere(); - } - }*/ - - if ( mAttributes.mVisualizeStrands ) - { - for ( int s=0; sgetAnchorPosition().mV[_X_], - mStrand[s]->getAnchorPosition().mV[_Y_], - mStrand[s]->getAnchorPosition().mV[_Z_] - ); - - glScalef - ( - STRAND_VISUALIZATION_ANCHOR_BALL_RADIUS, - STRAND_VISUALIZATION_ANCHOR_BALL_RADIUS, - STRAND_VISUALIZATION_ANCHOR_BALL_RADIUS - ); - - gSphere.render(); - glPopMatrix(); - - //-------------------------------- - // draw the strand - //-------------------------------- - //mStrand[s]->render(); - - - - - - - - //-------------------------------------------- - // draw the segments between the strands - //-------------------------------------------- - if ( s > 0 ) - { - //-------------------------------- - // draw the top edge... - //-------------------------------- - glBegin( GL_LINES ); - glVertex3fv( mStrand[s-1]->getAnchorPosition().mV ); - glVertex3fv( mStrand[s ]->getAnchorPosition().mV ); - glEnd(); - - //-------------------------------------------- - // draw the rest of the segments - //-------------------------------------------- - for ( int i=0; igetNodePosition(i).mV ); - glVertex3fv( mStrand[s ]->getNodePosition(i).mV ); - glEnd(); - } - } - } - } - - //-------------------------------------------------------- - // now, render the cape itself - //-------------------------------------------------------- - glColor4fv( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ).mV ); - - for ( int s=1; sgetAnchorPosition(); - rightBottom = mStrand[ s ]->getAnchorPosition(); - } - else - { - leftBottom = mStrand[ s-1 ]->getNodePosition( i-1 ); - rightBottom = mStrand[ s ]->getNodePosition( i-1 ); - } - - leftTop = mStrand[ s-1 ]->getNodePosition( i ); - rightTop = mStrand[ s ]->getNodePosition( i ); - - //gGLSTexture.set(); //set render state to use texture - LLViewerImage::bindTexture(theTexture); - - glBegin( GL_TRIANGLE_STRIP ); - glTexCoord2f( x0, y0 ); glVertex3fv( leftBottom.mV ); - glTexCoord2f( x1, y0 ); glVertex3fv( rightBottom.mV ); - glTexCoord2f( x0, y1 ); glVertex3fv( leftTop.mV ); - glEnd(); - glBegin( GL_TRIANGLE_STRIP ); - glTexCoord2f( x1, y0 ); glVertex3fv( rightBottom.mV ); - glTexCoord2f( x1, y1 ); glVertex3fv( rightTop.mV ); - glTexCoord2f( x0, y1 ); glVertex3fv( leftTop.mV ); - glEnd(); - - theTexture->unbindTexture(0, GL_TEXTURE_2D); - } - } - } - } - -}//------------------------------------------------------------------ - - - - -//------------------------------------------------------------------ -void LLVOCloth::setAttributes( LLClothAttributes a ) -{ - mAttributes.mTextureFileName = a.mTextureFileName; - mAttributes.mTextureIndex = a.mTextureIndex; - mAttributes.mNumSegments = a.mNumSegments; - mAttributes.mNumStrands = a.mNumStrands; - mAttributes.mVisualizeStrands = a.mVisualizeStrands; - mAttributes.mVisualizeAvCollisionSphere = a.mVisualizeAvCollisionSphere; - mAttributes.mWidth = a.mWidth; - mAttributes.mLength = a.mLength; - mAttributes.mPitch = a.mPitch; - mAttributes.mTension = a.mTension; - mAttributes.mGravity = a.mGravity; - mAttributes.mAirFriction = a.mAirFriction; - mAttributes.mWindSensitivity = a.mWindSensitivity; - mAttributes.mCircleWrapAmount = a.mCircleWrapAmount; - mAttributes.mUsingAvatarCollisionSphere = a.mUsingAvatarCollisionSphere; -//mAttributes.mAvatarCollisionSpherePositionOffset = a.mAvatarCollisionSpherePositionOffset; - mAttributes.mAvatarCollisionSphereRadius = a.mAvatarCollisionSphereRadius; - mAttributes.mAvatarCollisionSphereRightOffset = a.mAvatarCollisionSphereRightOffset; - mAttributes.mAvatarCollisionSphereUpOffset = a.mAvatarCollisionSphereUpOffset; - mAttributes.mAvatarCollisionSphereForwardOffset = a.mAvatarCollisionSphereForwardOffset; - - - if ( mAttributes.mTextureIndex < CLOTH_MIN_TEXTURE_INDEX ){ mAttributes.mTextureIndex = CLOTH_MIN_TEXTURE_INDEX; } - else if ( mAttributes.mTextureIndex > CLOTH_MAX_TEXTURE_INDEX ){ mAttributes.mTextureIndex = CLOTH_MAX_TEXTURE_INDEX; } - if ( mAttributes.mPitch < CLOTH_MIN_PITCH ){ mAttributes.mPitch = CLOTH_MIN_PITCH; } - else if ( mAttributes.mPitch > CLOTH_MAX_PITCH ){ mAttributes.mPitch = CLOTH_MAX_PITCH; } - if ( mAttributes.mWidth < CLOTH_MIN_WIDTH ){ mAttributes.mWidth = CLOTH_MIN_WIDTH; } - else if ( mAttributes.mWidth > CLOTH_MAX_WIDTH ){ mAttributes.mWidth = CLOTH_MAX_WIDTH; } - if ( mAttributes.mLength < CLOTH_MIN_LENGTH ){ mAttributes.mLength = CLOTH_MIN_LENGTH; } - else if ( mAttributes.mLength > CLOTH_MAX_LENGTH ){ mAttributes.mLength = CLOTH_MAX_LENGTH; } - if ( mAttributes.mNumSegments < CLOTH_MIN_SEGMENTS ){ mAttributes.mNumSegments = CLOTH_MIN_SEGMENTS; } - else if ( mAttributes.mNumSegments > CLOTH_MAX_SEGMENTS ){ mAttributes.mNumSegments = CLOTH_MAX_SEGMENTS; } - if ( mAttributes.mNumStrands < CLOTH_MIN_STRANDS ){ mAttributes.mNumStrands = CLOTH_MIN_STRANDS; } - else if ( mAttributes.mNumStrands > CLOTH_MAX_STRANDS ){ mAttributes.mNumStrands = CLOTH_MAX_STRANDS; } - if ( mAttributes.mTension < CLOTH_MIN_TENSION ){ mAttributes.mTension = CLOTH_MIN_TENSION; } - else if ( mAttributes.mTension > CLOTH_MAX_TENSION ){ mAttributes.mTension = CLOTH_MAX_TENSION; } - if ( mAttributes.mGravity < CLOTH_MIN_GRAVITY ){ mAttributes.mGravity = CLOTH_MIN_GRAVITY; } - else if ( mAttributes.mGravity > CLOTH_MAX_GRAVITY ){ mAttributes.mGravity = CLOTH_MAX_GRAVITY; } - if ( mAttributes.mAirFriction < CLOTH_MIN_AIR_FRICTION ){ mAttributes.mAirFriction = CLOTH_MIN_AIR_FRICTION; } - else if ( mAttributes.mAirFriction > CLOTH_MAX_AIR_FRICTION ){ mAttributes.mAirFriction = CLOTH_MAX_AIR_FRICTION; } - if ( mAttributes.mWindSensitivity < CLOTH_MIN_WIND_SENSITIVITY ){ mAttributes.mWindSensitivity = CLOTH_MIN_WIND_SENSITIVITY;} - else if ( mAttributes.mWindSensitivity > CLOTH_MAX_WIND_SENSITIVITY ){ mAttributes.mWindSensitivity = CLOTH_MAX_WIND_SENSITIVITY;} - if ( mAttributes.mCircleWrapAmount < CLOTH_MIN_CIRCLE_WRAP_AMOUNT ){ mAttributes.mCircleWrapAmount = CLOTH_MIN_CIRCLE_WRAP_AMOUNT;} - else if ( mAttributes.mCircleWrapAmount > CLOTH_MAX_CIRCLE_WRAP_AMOUNT ){ mAttributes.mCircleWrapAmount = CLOTH_MAX_CIRCLE_WRAP_AMOUNT;} - - if ( mAttributes.mAvatarCollisionSphereRadius < CLOTH_MIN_AVATAR_COLLISION_SPHERE_RADIUS ){ mAttributes.mAvatarCollisionSphereRadius = CLOTH_MIN_AVATAR_COLLISION_SPHERE_RADIUS;} - else if ( mAttributes.mAvatarCollisionSphereRadius > CLOTH_MAX_AVATAR_COLLISION_SPHERE_RADIUS ){ mAttributes.mAvatarCollisionSphereRadius = CLOTH_MAX_AVATAR_COLLISION_SPHERE_RADIUS;} - if ( mAttributes.mAvatarCollisionSphereRightOffset < CLOTH_MIN_AVATAR_COLLISION_SPHERE_RIGHT_OFFSET ){ mAttributes.mAvatarCollisionSphereRightOffset = CLOTH_MIN_AVATAR_COLLISION_SPHERE_RIGHT_OFFSET;} - else if ( mAttributes.mAvatarCollisionSphereRightOffset > CLOTH_MAX_AVATAR_COLLISION_SPHERE_RIGHT_OFFSET ){ mAttributes.mAvatarCollisionSphereRightOffset = CLOTH_MAX_AVATAR_COLLISION_SPHERE_RIGHT_OFFSET;} - if ( mAttributes.mAvatarCollisionSphereUpOffset < CLOTH_MIN_AVATAR_COLLISION_SPHERE_UP_OFFSET ){ mAttributes.mAvatarCollisionSphereUpOffset = CLOTH_MIN_AVATAR_COLLISION_SPHERE_UP_OFFSET;} - else if ( mAttributes.mAvatarCollisionSphereUpOffset > CLOTH_MAX_AVATAR_COLLISION_SPHERE_UP_OFFSET ){ mAttributes.mAvatarCollisionSphereUpOffset = CLOTH_MAX_AVATAR_COLLISION_SPHERE_UP_OFFSET;} - if ( mAttributes.mAvatarCollisionSphereForwardOffset < CLOTH_MIN_AVATAR_COLLISION_SPHERE_FORWARD_OFFSET ){ mAttributes.mAvatarCollisionSphereForwardOffset = CLOTH_MIN_AVATAR_COLLISION_SPHERE_FORWARD_OFFSET;} - else if ( mAttributes.mAvatarCollisionSphereForwardOffset > CLOTH_MAX_AVATAR_COLLISION_SPHERE_FORWARD_OFFSET ){ mAttributes.mAvatarCollisionSphereForwardOffset = CLOTH_MAX_AVATAR_COLLISION_SPHERE_FORWARD_OFFSET;} - - //----------------------------------------------------------------------------------- - // based on the above attributes, the strands (flexible objects) are generated - //----------------------------------------------------------------------------------- - generateStrands(); - -}//------------------------------------------------------------------ - - - - - -//------------------------------------------------------------------ -// set methods -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -void LLVOCloth::setNumStrands( int num ) -{ - mAttributes.mNumStrands = num; - generateStrands(); -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setNumSegments( int num ) -{ - mAttributes.mNumSegments = num; - generateStrands(); -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setLength( F32 le ) -{ - mAttributes.mLength = le; - generateStrands(); -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setCircleWrapAmount( F32 n ) -{ - mAttributes.mCircleWrapAmount = n; - generateStrands(); -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setGravity( F32 g ) -{ - mAttributes.mGravity = g; - generateStrands(); -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setPitch( F32 p ) -{ - mAttributes.mPitch = p; - generateStrands(); -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setAirFriction( F32 a ) -{ - mAttributes.mAirFriction = a; - generateStrands(); -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setWindSensitivity( F32 w ) -{ - mAttributes.mWindSensitivity = w; - generateStrands(); -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setTension( F32 t ) -{ - mAttributes.mTension = t; - generateStrands(); -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setWidth( F32 n ) -{ - mAttributes.mWidth = n; - generateStrands(); -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setVisualizingStrands( bool v ) -{ - mAttributes.mVisualizeStrands = v; -}//------------------------------------------------------------------//------------------------------------------------------------------ -void LLVOCloth::setVisualizingAvCollisionSphere( bool v ) -{ - mAttributes.mVisualizeAvCollisionSphere = v; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setAvatarCollisionSphereRadius( F32 r ) -{ - mAttributes.mAvatarCollisionSphereRadius = r; - -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setAvatarCollisionSphereRight( F32 r ) -{ - mAttributes.mAvatarCollisionSphereRightOffset = r; - -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setAvatarCollisionSphereUp( F32 u ) -{ - mAttributes.mAvatarCollisionSphereUpOffset = u; - -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -void LLVOCloth::setAvatarCollisionSphereForward( F32 f ) -{ - mAttributes.mAvatarCollisionSphereForwardOffset = f; - -}//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -// get methods -//------------------------------------------------------------------ - -//------------------------------------------------------------------ -int LLVOCloth::getNumStrands() -{ - return mAttributes.mNumStrands; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -int LLVOCloth::getNumSegments() -{ - return mAttributes.mNumSegments; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -F32 LLVOCloth::getLength() -{ - return mAttributes.mLength; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -F32 LLVOCloth::getWidth() -{ - return mAttributes.mWidth; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -F32 LLVOCloth::getCircleWrapAmount() -{ - return mAttributes.mCircleWrapAmount; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -F32 LLVOCloth::getPitch() -{ - return mAttributes.mPitch; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -F32 LLVOCloth::getTension() -{ - return mAttributes.mTension; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -F32 LLVOCloth::getGravity() -{ - return mAttributes.mGravity; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -F32 LLVOCloth::getAirFriction() -{ - return mAttributes.mAirFriction; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -F32 LLVOCloth::getWindSensitivity() -{ - return mAttributes.mWindSensitivity; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -bool LLVOCloth::getVisualizingStrands() const -{ - return mAttributes.mVisualizeStrands; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -bool LLVOCloth::getVisualizingAvCollisionSphere() const -{ - return mAttributes.mVisualizeAvCollisionSphere; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -F32 LLVOCloth::getAvatarCollisionSphereRadius() -{ - return mAttributes.mAvatarCollisionSphereRadius; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -F32 LLVOCloth::getAvatarCollisionSphereRight() -{ - return mAttributes.mAvatarCollisionSphereRightOffset; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -F32 LLVOCloth::getAvatarCollisionSphereUp() -{ - return mAttributes.mAvatarCollisionSphereUpOffset; -}//------------------------------------------------------------------ -//------------------------------------------------------------------ -F32 LLVOCloth::getAvatarCollisionSphereForward() -{ - return mAttributes.mAvatarCollisionSphereForwardOffset; -}//------------------------------------------------------------------ - - - -//------------------------------------------------------------------ -void LLVOCloth::markAsDead() -{ - mDead = TRUE; - -}//------------------------------------------------------------------ - - - - - - - - diff --git a/linden/indra/newview/llcape.h b/linden/indra/newview/llcape.h deleted file mode 100644 index 52741f4..0000000 --- a/linden/indra/newview/llcape.h +++ /dev/null @@ -1,231 +0,0 @@ -/** - * @file llcape.h - * @brief LLVOCloth class definition - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LLCAPE_H -#define LLCAPE_H - -#include "llviewerobject.h" - -class LLVolumeImplFlexible; - -//----------------------------------------------------------------------------------- -// Default setting for the attributes of a cloth object... -//----------------------------------------------------------------------------------- -const F32 CLOTH_MIN_LENGTH = 0.2f; -const F32 CLOTH_DEFAULT_LENGTH = 1.5f; -const F32 CLOTH_MAX_LENGTH = 2.0f; - -const F32 CLOTH_MIN_TENSION = 0.0f; -const F32 CLOTH_DEFAULT_TENSION = 1.0f; -const F32 CLOTH_MAX_TENSION = 10.0f; - -const F32 CLOTH_MIN_GRAVITY = FLEXIBLE_OBJECT_MIN_GRAVITY; -const F32 CLOTH_DEFAULT_GRAVITY = 0.3f; -const F32 CLOTH_MAX_GRAVITY = FLEXIBLE_OBJECT_MAX_GRAVITY; - -const F32 CLOTH_MIN_PITCH = -1.0f; -const F32 CLOTH_DEFAULT_PITCH = 0.1f; -const F32 CLOTH_MAX_PITCH = 1.0f; - -const F32 CLOTH_MIN_AIR_FRICTION = FLEXIBLE_OBJECT_MIN_AIR_FRICTION; -const F32 CLOTH_DEFAULT_AIR_FRICTION = 6.0f; -const F32 CLOTH_MAX_AIR_FRICTION = FLEXIBLE_OBJECT_MAX_AIR_FRICTION; - -const F32 CLOTH_MIN_WIND_SENSITIVITY = FLEXIBLE_OBJECT_MIN_WIND_SENSITIVITY; -const F32 CLOTH_DEFAULT_WIND_SENSITIVITY = 0.0f; -const F32 CLOTH_MAX_WIND_SENSITIVITY = FLEXIBLE_OBJECT_MAX_WIND_SENSITIVITY; - -const F32 CLOTH_MIN_CIRCLE_WRAP_AMOUNT = 0.0f; -const F32 CLOTH_DEFAULT_CIRCLE_WRAP_AMOUNT= 0.5f; -const F32 CLOTH_MAX_CIRCLE_WRAP_AMOUNT = 1.0f; - -const F32 CLOTH_MIN_WIDTH = 0.01f; -const F32 CLOTH_DEFAULT_WIDTH = 0.4f; -const F32 CLOTH_MAX_WIDTH = 1.0f; - -const int CLOTH_MIN_STRANDS = 2; -const int CLOTH_DEFAULT_NUM_STRANDS = 4; -const int CLOTH_MAX_STRANDS = 8; - -const int CLOTH_MIN_SEGMENTS = 1; -const int CLOTH_DEFAULT_NUM_SEGMENTS = 4; -const int CLOTH_MAX_SEGMENTS = 8; - -const int CLOTH_MIN_TEXTURE_INDEX = 1; -const int CLOTH_DEFAULT_TEXTURE_INDEX = 1; -const int CLOTH_MAX_TEXTURE_INDEX = 7; - -const F32 CLOTH_MIN_AVATAR_COLLISION_SPHERE_RADIUS = 0.0f; -const F32 CLOTH_DEFAULT_AVATAR_COLLISION_SPHERE_RADIUS= 0.1f; -const F32 CLOTH_MAX_AVATAR_COLLISION_SPHERE_RADIUS = 3.0f; - -const F32 CLOTH_MIN_AVATAR_COLLISION_SPHERE_RIGHT_OFFSET = -2.0f; -const F32 CLOTH_DEFAULT_AVATAR_COLLISION_SPHERE_RIGHT_OFFSET = 0.0f; -const F32 CLOTH_MAX_AVATAR_COLLISION_SPHERE_RIGHT_OFFSET = 2.0f; - -const F32 CLOTH_MIN_AVATAR_COLLISION_SPHERE_UP_OFFSET = -2.0f; -const F32 CLOTH_DEFAULT_AVATAR_COLLISION_SPHERE_UP_OFFSET = 0.0f; -const F32 CLOTH_MAX_AVATAR_COLLISION_SPHERE_UP_OFFSET = 2.0f; - -const F32 CLOTH_MIN_AVATAR_COLLISION_SPHERE_FORWARD_OFFSET = -2.0f; -const F32 CLOTH_DEFAULT_AVATAR_COLLISION_SPHERE_FORWARD_OFFSET = 0.0f; -const F32 CLOTH_MAX_AVATAR_COLLISION_SPHERE_FORWARD_OFFSET = 2.0f; - -const LLString CLOTH_DEFAULT_TEXTURE_FILENAME = "not_specified"; -const bool CLOTH_DEFAULT_VISUALIZE_STRANDS = false; -const bool CLOTH_DEFAULT_VISUALIZE_COLLISION_SPHERE = false; - -const bool CLOTH_DEFAULT_USING_AVATAR_COLLISION_SPHERE = false; -const LLVector3 CLOTH_DEFAULT_AVATAR_COLLISION_SPHERE_POSITION_OFFSET = LLVector3::zero; - - -//------------------------------------------------- -// This structure is also used in the part of the -// code that creates new cloth objects. -//------------------------------------------------- -struct LLClothAttributes -{ - int mTextureIndex; - LLString mTextureFileName; - bool mVisualizeStrands; - bool mVisualizeAvCollisionSphere; - int mNumStrands; - int mNumSegments; - F32 mWidth; - F32 mPitch; - F32 mLength; - F32 mTension; - F32 mGravity; - F32 mAirFriction; - F32 mWindSensitivity; - F32 mCircleWrapAmount; - bool mUsingAvatarCollisionSphere; - F32 mAvatarCollisionSphereRightOffset; - F32 mAvatarCollisionSphereUpOffset; - F32 mAvatarCollisionSphereForwardOffset; - F32 mAvatarCollisionSphereRadius; - - - - //------ the constructor for the structure ------------ - LLClothAttributes() - { - mTextureFileName = CLOTH_DEFAULT_TEXTURE_FILENAME; - mVisualizeStrands = CLOTH_DEFAULT_VISUALIZE_STRANDS; - mNumStrands = CLOTH_DEFAULT_NUM_STRANDS; - mNumSegments = CLOTH_DEFAULT_NUM_SEGMENTS; - mWidth = CLOTH_DEFAULT_WIDTH; - mLength = CLOTH_DEFAULT_LENGTH; - mPitch = CLOTH_DEFAULT_PITCH; - mTension = CLOTH_DEFAULT_TENSION; - mGravity = CLOTH_DEFAULT_GRAVITY; - mAirFriction = CLOTH_DEFAULT_AIR_FRICTION; - mWindSensitivity = CLOTH_DEFAULT_WIND_SENSITIVITY; - mCircleWrapAmount = CLOTH_DEFAULT_CIRCLE_WRAP_AMOUNT; - mTextureIndex = CLOTH_DEFAULT_TEXTURE_INDEX; - } -};// end of attributes structure - - - -//--------------------------------------------------------- -// The LLVOCloth class -//--------------------------------------------------------- -class LLVOCloth : public LLViewerObject -{ - public: - LLVOCloth(const LLUUID &id, const LLPCode type, LLViewerRegion *regionp); - void update(); - void render(); - void markAsDead(); - - //---------------------------------------------- - // set stuff - //---------------------------------------------- - void setAttributes( LLClothAttributes ); - void setNumStrands( int num ); - void setNumSegments( int num ); - void setLength( F32 length ); - void setTension( F32 t ); - void setGravity( F32 g ); - void setCircleWrapAmount( F32 n ); - void setAirFriction( F32 a ); - void setWindSensitivity( F32 w ); - void setPitch( F32 p ); - void setWidth( F32 n ); - void setVisualizingStrands( bool v ); - void setVisualizingAvCollisionSphere( bool v ); - void setAvatarCollisionSphereRadius( F32 r ); - void setAvatarCollisionSphereRight( F32 r ); - void setAvatarCollisionSphereUp( F32 u ); - void setAvatarCollisionSphereForward( F32 f); - - //---------------------------------------------- - // get stuff - //---------------------------------------------- - bool getVisualizingStrands() const; - bool getVisualizingAvCollisionSphere() const; - int getNumStrands(); - int getNumSegments(); - F32 getLength(); - F32 getWidth(); - F32 getCircleWrapAmount(); - F32 getPitch(); - F32 getTension(); - F32 getGravity(); - F32 getAirFriction(); - F32 getWindSensitivity(); - F32 getAvatarCollisionSphereRadius(); - F32 getAvatarCollisionSphereRight(); - F32 getAvatarCollisionSphereUp(); - F32 getAvatarCollisionSphereForward(); - - private: - //-------------------------------------- - // private members - //-------------------------------------- - LLClothAttributes mAttributes; // these determine the characteristics of the cloth - LLVector3 mAvatarCollisionSpherePosition; // derived from the avatar - // Backlink only; don't make this an LLPointer. - LLViewerObject* mDummyVO [ CLOTH_MAX_STRANDS ]; - LLVolumeImplFlexible* mStrand [ CLOTH_MAX_STRANDS ]; // the array of strands that make up the cloth - - - //-------------------------------------- - // private methods - //-------------------------------------- - void updateVirtualServer(); - void generateStrands(); - -};// end of class definition - - -#endif // LL_CLOTH_H diff --git a/linden/indra/newview/llchatbar.cpp b/linden/indra/newview/llchatbar.cpp index 292ff8f..b47e468 100644 --- a/linden/indra/newview/llchatbar.cpp +++ b/linden/indra/newview/llchatbar.cpp @@ -125,6 +125,12 @@ BOOL LLChatBar::postBuild() // attempt to bind to an existing combo box named gesture setGestureCombo(LLUICtrlFactory::getComboBoxByName(this, "Gesture")); + LLButton * sayp = getChild("Say"); + if(sayp) + { + setDefaultBtn(sayp); + } + mInputEditor = LLUICtrlFactory::getLineEditorByName(this, "Chat Editor"); if (mInputEditor) { diff --git a/linden/indra/newview/llclassifiedstatsresponder.cpp b/linden/indra/newview/llclassifiedstatsresponder.cpp index 37b0c91..48aef45 100644 --- a/linden/indra/newview/llclassifiedstatsresponder.cpp +++ b/linden/indra/newview/llclassifiedstatsresponder.cpp @@ -43,7 +43,7 @@ #include "llview.h" #include "message.h" -LLClassifiedStatsResponder::LLClassifiedStatsResponder(LLViewHandle classified_panel_handle, LLUUID classified_id) +LLClassifiedStatsResponder::LLClassifiedStatsResponder(LLHandle classified_panel_handle, LLUUID classified_id) : mClassifiedPanelHandle(classified_panel_handle), mClassifiedID(classified_id) { @@ -58,7 +58,7 @@ void LLClassifiedStatsResponder::result(const LLSD& content) S32 search_map = content["search_map_clicks"].asInteger(); S32 search_profile = content["search_profile_clicks"].asInteger(); - LLPanelClassified* classified_panelp = (LLPanelClassified*)LLPanel::getPanelByHandle(mClassifiedPanelHandle); + LLPanelClassified* classified_panelp = (LLPanelClassified*)mClassifiedPanelHandle.get(); if(classified_panelp) { diff --git a/linden/indra/newview/llclassifiedstatsresponder.h b/linden/indra/newview/llclassifiedstatsresponder.h index ab219b7..cedd481 100644 --- a/linden/indra/newview/llclassifiedstatsresponder.h +++ b/linden/indra/newview/llclassifiedstatsresponder.h @@ -39,14 +39,14 @@ class LLClassifiedStatsResponder : public LLHTTPClient::Responder { public: - LLClassifiedStatsResponder(LLViewHandle classified_panel_handle, LLUUID classified_id); + LLClassifiedStatsResponder(LLHandle classified_panel_handle, LLUUID classified_id); //If we get back a normal response, handle it here virtual void result(const LLSD& content); //If we get back an error (not found, etc...), handle it here virtual void error(U32 status, const std::string& reason); protected: - LLViewHandle mClassifiedPanelHandle; + LLHandle mClassifiedPanelHandle; LLUUID mClassifiedID; }; diff --git a/linden/indra/newview/llcloud.cpp b/linden/indra/newview/llcloud.cpp index cf9574a..3b8e466 100644 --- a/linden/indra/newview/llcloud.cpp +++ b/linden/indra/newview/llcloud.cpp @@ -425,41 +425,6 @@ F32 LLCloudLayer::getDensityRegion(const LLVector3 &pos_region) return density; } -// a debug method that may yet be useful -void LLCloudLayer::renderDensityField() -{ -// F32 x, y, z; -// U32 i, j, k; -// LLGLSNoTexture gls_ui_no_texture; -// // Render a bunch of triangles to represent the cloud density field -// glBegin(GL_TRIANGLES); -// for(j=0; jsetFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); addChild( mCaption ); // Scalable UI made this off-by-one, I don't know why. JC - LLRect border_rect(0, mRect.getHeight()-1, mRect.getWidth()-1, 0); + LLRect border_rect(0, getRect().getHeight()-1, getRect().getWidth()-1, 0); border_rect.mBottom += BTN_HEIGHT_SMALL; mBorder = new LLViewBorder("border", border_rect, LLViewBorder::BEVEL_IN); addChild(mBorder); @@ -89,14 +90,14 @@ LLColorSwatchCtrl::LLColorSwatchCtrl(const std::string& name, const LLRect& rect mOnSelectCallback(NULL) { mCaption = new LLTextBox( label, - LLRect( 0, BTN_HEIGHT_SMALL, mRect.getWidth(), 0 ), - LLString::null, + LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ), + label, LLFontGL::sSansSerifSmall ); mCaption->setFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); addChild( mCaption ); // Scalable UI made this off-by-one, I don't know why. JC - LLRect border_rect(0, mRect.getHeight()-1, mRect.getWidth()-1, 0); + LLRect border_rect(0, getRect().getHeight()-1, getRect().getWidth()-1, 0); border_rect.mBottom += BTN_HEIGHT_SMALL; mBorder = new LLViewBorder("border", border_rect, LLViewBorder::BEVEL_IN); addChild(mBorder); @@ -108,7 +109,7 @@ LLColorSwatchCtrl::LLColorSwatchCtrl(const std::string& name, const LLRect& rect LLColorSwatchCtrl::~LLColorSwatchCtrl () { // parent dialog is destroyed so we are too and we need to cancel selection - LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get(); if (pickerp) { pickerp->cancelSelection(); @@ -130,7 +131,7 @@ BOOL LLColorSwatchCtrl::handleHover(S32 x, S32 y, MASK mask) BOOL LLColorSwatchCtrl::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) { - if( getVisible() && mEnabled && !called_from_parent && ' ' == uni_char ) + if( getVisible() && getEnabled() && !called_from_parent && ' ' == uni_char ) { showPicker(TRUE); } @@ -141,7 +142,7 @@ BOOL LLColorSwatchCtrl::handleUnicodeCharHere(llwchar uni_char, BOOL called_from void LLColorSwatchCtrl::setOriginal(const LLColor4& color) { mColor = color; - LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get(); if (pickerp) { pickerp->setOrigRgb(mColor.mV[VRED], mColor.mV[VGREEN], mColor.mV[VBLUE]); @@ -151,7 +152,7 @@ void LLColorSwatchCtrl::setOriginal(const LLColor4& color) void LLColorSwatchCtrl::set(const LLColor4& color, BOOL update_picker, BOOL from_event) { mColor = color; - LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get(); if (pickerp && update_picker) { pickerp->setCurRgb(mColor.mV[VRED], mColor.mV[VGREEN], mColor.mV[VBLUE]); @@ -188,7 +189,7 @@ BOOL LLColorSwatchCtrl::handleMouseUp(S32 x, S32 y, MASK mask) // If mouseup in the widget, it's been clicked if ( pointInView(x, y) ) { - llassert(mEnabled); + llassert(getEnabled()); llassert(getVisible()); showPicker(FALSE); @@ -206,7 +207,7 @@ void LLColorSwatchCtrl::draw() { mBorder->setKeyboardFocusHighlight(hasFocus()); // Draw border - LLRect border( 0, mRect.getHeight(), mRect.getWidth(), BTN_HEIGHT_SMALL ); + LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL ); gl_rect_2d( border, mBorderColor, FALSE ); LLRect interior = border; @@ -215,23 +216,21 @@ void LLColorSwatchCtrl::draw() // Check state if ( mValid ) { - LLGLSTexture gls_texture; - // Draw the color swatch gl_rect_2d_checkerboard( interior ); gl_rect_2d(interior, mColor, TRUE); LLColor4 opaque_color = mColor; opaque_color.mV[VALPHA] = 1.f; - glColor4fv(opaque_color.mV); + gGL.color4fv(opaque_color.mV); if (mAlphaGradientImage.notNull()) { - glPushMatrix(); + gGL.pushMatrix(); { - glTranslatef((F32)interior.mLeft, (F32)interior.mBottom, 0.f); + gGL.translatef((F32)interior.mLeft, (F32)interior.mBottom, 0.f); LLViewerImage::bindTexture(mAlphaGradientImage); gl_rect_2d_simple_tex(interior.getWidth(), interior.getHeight()); } - glPopMatrix(); + gGL.popMatrix(); } } else @@ -253,7 +252,7 @@ void LLColorSwatchCtrl::setEnabled( BOOL enabled ) if (!enabled) { - LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get(); if (pickerp) { pickerp->cancelSelection(); @@ -275,7 +274,7 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op ) LLColorSwatchCtrl* subject = ( LLColorSwatchCtrl* )data; if ( subject ) { - LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(subject->mPickerHandle); + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)subject->mPickerHandle.get(); if (pickerp) { // move color across from selector to internal widget storage @@ -300,14 +299,14 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op ) subject->onCommit (); } } - }; + } } void LLColorSwatchCtrl::setValid(BOOL valid ) { mValid = valid; - LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get(); if (pickerp) { pickerp->setActive(valid); @@ -316,7 +315,7 @@ void LLColorSwatchCtrl::setValid(BOOL valid ) void LLColorSwatchCtrl::showPicker(BOOL take_focus) { - LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)LLFloater::getFloaterByHandle(mPickerHandle); + LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get(); if (!pickerp) { pickerp = new LLFloaterColorPicker(this, mCanApplyImmediately); @@ -324,7 +323,7 @@ void LLColorSwatchCtrl::showPicker(BOOL take_focus) mPickerHandle = pickerp->getHandle(); } - // initialize picker singleton with current color + // initialize picker with current color pickerp->initUI ( mColor.mV [ VRED ], mColor.mV [ VGREEN ], mColor.mV [ VBLUE ] ); // display it diff --git a/linden/indra/newview/llcolorswatch.h b/linden/indra/newview/llcolorswatch.h index e1bf275..1c3a08b 100644 --- a/linden/indra/newview/llcolorswatch.h +++ b/linden/indra/newview/llcolorswatch.h @@ -98,7 +98,7 @@ protected: LLColor4 mColor; LLColor4 mBorderColor; LLTextBox* mCaption; - LLViewHandle mPickerHandle; + LLHandle mPickerHandle; LLViewBorder* mBorder; BOOL mCanApplyImmediately; LLUICtrlCallback mOnCancelCallback; diff --git a/linden/indra/newview/llcompass.cpp b/linden/indra/newview/llcompass.cpp index 1f39705..f4dbbb8 100644 --- a/linden/indra/newview/llcompass.cpp +++ b/linden/indra/newview/llcompass.cpp @@ -31,7 +31,6 @@ #include "llviewerprecompiledheaders.h" -#include "linked_lists.h" #include "llmath.h" // clampf() #include "llmath.h" #include "llgl.h" diff --git a/linden/indra/newview/llcompilequeue.cpp b/linden/indra/newview/llcompilequeue.cpp index 93c2737..8e1ba81 100644 --- a/linden/indra/newview/llcompilequeue.cpp +++ b/linden/indra/newview/llcompilequeue.cpp @@ -44,7 +44,6 @@ #include "llagent.h" #include "llchat.h" #include "llviewerwindow.h" -#include "llcallbacklist.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" diff --git a/linden/indra/newview/llconsole.cpp b/linden/indra/newview/llconsole.cpp index 3a8765c..79ab8cc 100644 --- a/linden/indra/newview/llconsole.cpp +++ b/linden/indra/newview/llconsole.cpp @@ -94,8 +94,8 @@ void LLConsole::setLinePersistTime(F32 seconds) void LLConsole::reshape(S32 width, S32 height, BOOL called_from_parent) { - S32 new_width = llmax(50, llmin(mRect.getWidth(), gViewerWindow->getWindowWidth())); - S32 new_height = llmax(llfloor(mFont->getLineHeight()) + 15, llmin(mRect.getHeight(), gViewerWindow->getWindowHeight())); + S32 new_width = llmax(50, llmin(getRect().getWidth(), gViewerWindow->getWindowWidth())); + S32 new_height = llmax(llfloor(mFont->getLineHeight()) + 15, llmin(getRect().getHeight(), gViewerWindow->getWindowHeight())); LLView::reshape(new_width, new_height, called_from_parent); } @@ -289,7 +289,7 @@ void LLConsole::addQueuedLines() line_end = wline.size(); skip_chars = 0; } - U32 drawable = mFont->maxDrawableChars(wline.c_str()+offset, (F32)mRect.getWidth(), line_end-offset, TRUE); + U32 drawable = mFont->maxDrawableChars(wline.c_str()+offset, (F32)getRect().getWidth(), line_end-offset, TRUE); if (drawable != 0) { LLFixedBuffer::addLine(wline.substr(offset, drawable)); diff --git a/linden/indra/newview/llcontainerview.cpp b/linden/indra/newview/llcontainerview.cpp index 497b794..53c8e92 100644 --- a/linden/indra/newview/llcontainerview.cpp +++ b/linden/indra/newview/llcontainerview.cpp @@ -71,10 +71,10 @@ BOOL LLContainerView::handleMouseDown(S32 x, S32 y, MASK mask) } if (!handled) { - if( mCollapsible && (y >= mRect.getHeight() - 10) ) + if( mCollapsible && (y >= getRect().getHeight() - 10) ) { setDisplayChildren(!mDisplayChildren); - reshape(mRect.getWidth(), mRect.getHeight(), FALSE); + reshape(getRect().getWidth(), getRect().getHeight(), FALSE); } } return TRUE; @@ -99,11 +99,11 @@ void LLContainerView::draw() { LLGLSNoTexture gls_no_texture; - gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); } // Draw the label. - gResMgr->getRes( LLFONT_OCRA )->renderUTF8(mLabel, 0, 2, mRect.getHeight() - 2, LLColor4(1,1,1,1), LLFontGL::LEFT, LLFontGL::TOP); + gResMgr->getRes( LLFONT_OCRA )->renderUTF8(mLabel, 0, 2, getRect().getHeight() - 2, LLColor4(1,1,1,1), LLFontGL::LEFT, LLFontGL::TOP); LLView::draw(); } @@ -117,8 +117,8 @@ void LLContainerView::reshape(S32 width, S32 height, BOOL called_from_parent) // These will be used for the children left = 4; - top = mRect.getHeight() - 4; - right = mRect.getWidth() - 2; + top = getRect().getHeight() - 4; + right = getRect().getWidth() - 2; bottom = top; // Leave some space for the top label/grab handle @@ -146,13 +146,16 @@ void LLContainerView::reshape(S32 width, S32 height, BOOL called_from_parent) if (followsTop()) { - mRect.mBottom = mRect.mTop - total_height; + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast(getRect()).mBottom = getRect().mTop - total_height; } else { - mRect.mTop = mRect.mBottom + total_height; + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast(getRect()).mTop = getRect().mBottom + total_height; } - mRect.mRight = mRect.mLeft + width; + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast(getRect()).mRight = getRect().mLeft + width; top = total_height - 20; bottom = top; diff --git a/linden/indra/newview/llcontroldef.cpp b/linden/indra/newview/llcontroldef.cpp index 124361b..22c5fac 100644 --- a/linden/indra/newview/llcontroldef.cpp +++ b/linden/indra/newview/llcontroldef.cpp @@ -54,7 +54,6 @@ #include "llflexibleobject.h" #include "llfeaturemanager.h" #include "llglslshader.h" -#include "llmediaengine.h" #include "llpanelgeneral.h" #include "llpanelinput.h" #include "llsky.h" @@ -63,7 +62,9 @@ #include "llviewerthrottle.h" #include "llviewerwindow.h" #include "llvoavatar.h" +#include "llvosurfacepatch.h" #include "llvosky.h" +#include "llvowlsky.h" #include "llvotree.h" #include "llvovolume.h" #include "llworld.h" @@ -73,6 +74,9 @@ #include "llparcel.h" #include "llnotify.h" #include "llkeyboard.h" +#include "llglimmediate.h" + +extern BOOL gResizeScreenTexture; void declare_settings() { @@ -389,7 +393,7 @@ void declare_settings() gSavedSettings.declareRect("BasicHelpRect", LLRect(0, 404, 467, 0), "Rectangle for help window" ); // Only width and height are used gSavedSettings.declareS32("LastPrefTab", 0, "Last selected tab in preferences window"); - + gSavedSettings.declareString("LSLHelpURL", "https://wiki.secondlife.com/wiki/[LSL_STRING]", "URL that points to LSL help files, with [LSL_STRING] corresponding to the referenced LSL function or keyword"); // link for editable wiki (https doesn't seem to work right now with our embedded browser) //gSavedSettings.declareString("LSLHelpURL", "https://wiki.secondlife.com/wiki/[LSL_STRING]", "URL that points to LSL help files, with [LSL_STRING] corresponding to the referenced LSL function or keyword"); @@ -699,8 +703,6 @@ void declare_settings() gSavedSettings.declareBOOL("ShowCameraControls", FALSE, "Display camera controls on login"); gSavedSettings.declareBOOL("ShowMovementControls", FALSE, "Display movement controls on login"); - gSavedSettings.declareBOOL("ShowWebBrowser", FALSE, "Show in-world web browser"); - gSavedSettings.declareBOOL("ShowLeaders", FALSE, "", NO_PERSIST); gSavedSettings.declareBOOL("ShowDirectory", FALSE, "", NO_PERSIST); @@ -748,6 +750,7 @@ void declare_settings() LLFirstUse::addConfigVariable("FirstStreamingVideo"); LLFirstUse::addConfigVariable("FirstSculptedPrim"); LLFirstUse::addConfigVariable("FirstVoice"); + LLFirstUse::addConfigVariable("FirstMedia"); gSavedSettings.declareBOOL("ShowDebugConsole", FALSE, "Show log in SL window"); gSavedSettings.declareBOOL("ShowDebugStats", FALSE, "Show performance stats display"); @@ -760,6 +763,7 @@ void declare_settings() gSavedSettings.declareBOOL("DebugShowTime", FALSE, "Show depth buffer contents"); gSavedSettings.declareBOOL("DebugShowRenderInfo", FALSE, "Show depth buffer contents"); + gSavedSettings.declareBOOL("DebugShowColor", FALSE, "Show color under cursor"); // gSavedSettings.declareBOOL("ShowHUD", TRUE); //gSavedSettings.declareBOOL("ShowHUDText", TRUE, "[NOT USED]"); @@ -789,43 +793,78 @@ void declare_settings() gSavedSettings.declareF32("PrecachingDelay", 6.f, "Delay when logging in to load world before showing it (seconds)"); // seconds // Rendering stuff + gSavedSettings.declareBOOL("RenderCubeMap", TRUE, "Whether we can render the cube map or not"); gSavedSettings.declareF32("RenderGamma", 0.f, "Sets gamma exponent for renderer"); - gSavedSettings.declareF32( "RenderNightBrightness", 1.0f, "Brightness multiplier for moon during nighttime" ); gSavedSettings.declareBOOL("RenderWater", TRUE, "Display water" ); gSavedSettings.declareF32( "RenderFarClip", 256.f, "Distance of far clip plane from camera (meters)" ); - gSavedSettings.declareF32( "RenderFogRatio", 2.0f, "Distance from camera where fog reaches maximum density (fraction or multiple of far clip distance)"); + gSavedSettings.declareBOOL( "RenderUseFarClip", TRUE, "If false, frustum culling will ignore far clip plane."); + gSavedSettings.declareF32( "RenderFogRatio", 4.0f, "Distance from camera where fog reaches maximum density (fraction or multiple of far clip distance)"); gSavedSettings.declareBOOL("RenderAnisotropic", FALSE, "Render textures using anisotropic filtering" ); gSavedSettings.declareBOOL("ShowXUINames", FALSE, "Display XUI Names as Tooltips" ); gSavedSettings.declareS32("RenderLightingDetail", 1, "Amount of detail for lighting objects/avatars/terrain (0=sun/moon only, 1=enable local lights)" ); gSavedSettings.declareS32("RenderTerrainDetail", 2, "Detail applied to terrain texturing (0 = none, 1 or 2 = full)" ); + gSavedSettings.declareBOOL("RenderDynamicLOD", TRUE, "Dynamically adjust level of detail."); gSavedSettings.declareF32( "RenderVolumeLODFactor", 1.f, "Controls level of detail of primitives (multiplier for current screen area when calculated level of detail)" ); gSavedSettings.declareF32( "RenderFlexTimeFactor", 1.f, "Controls level of detail of flexible objects (multiplier for amount of time spent processing flex objects)" ); - gSavedSettings.declareF32( "RenderTreeLODFactor", 0.5f, "Controls level of detail of vegetatopm (multiplier for current screen area when calculated level of detail)" ); + gSavedSettings.declareF32( "RenderTreeLODFactor", 0.5f, "Controls level of detail of vegetation (multiplier for current screen area when calculated level of detail)" ); gSavedSettings.declareF32( "RenderAvatarLODFactor", 0.5f, "Controls level of detail of avatars (multiplier for current screen area when calculated level of detail)" ); + gSavedSettings.declareF32( "RenderTerrainLODFactor", 1.0f, "Controls level of detail of terrain (multiplier for current screen area when calculated level of detail)" ); gSavedSettings.declareF32( "RenderBumpmapMinDistanceSquared", 100.f, "Maximum distance at which to render bumpmapped primitives (distance in meters, squared)" ); gSavedSettings.declareS32( "RenderMaxPartCount", 4096, "Maximum number of particles to display on screen"); gSavedSettings.declareBOOL("RenderVBOEnable", TRUE, "Use GL Vertex Buffer Objects" ); + gSavedSettings.declareS32("RenderMaxVBOSize", 32, "Maximum size of a vertex buffer (in KB)."); gSavedSettings.declareS32("RenderReflectionRes", 64, "Reflection map resolution."); //gSavedSettings.declareBOOL("RenderUseTriStrips", FALSE, "[NOT USED]"); //gSavedSettings.declareBOOL("RenderCullBySize", FALSE, "[NOT USED]" ); gSavedSettings.declareF32("RenderTerrainScale", 12.f, "Terrain detail texture scale"); gSavedSettings.declareBOOL("VertexShaderEnable", FALSE, "Enable/disable all GLSL shaders (debug)"); gSavedSettings.declareBOOL("RenderInitError", FALSE, "Error occured while initializing GL"); - gSavedSettings.declareBOOL("RenderRippleWater", FALSE, "Display more realistic water, with refraction (requires pixel shader support on your video card)"); + + gSavedSettings.declareBOOL("RenderWaterMipNormal", TRUE, "Use mip maps for water normal map."); gSavedSettings.declareBOOL("RenderDynamicReflections", FALSE, "Generate a dynamic cube map for reflections (objects reflect their environment, experimental)."); - gSavedSettings.declareBOOL("RenderGlow", FALSE, "Make light sources glow."); - gSavedSettings.declareF32("RenderGlowStrength", 1.25f, "Strength of glow"); - gSavedSettings.declareS32("RenderGlowSize", 5, "Size of glow (in pixels)"); - gSavedSettings.declareS32("RenderGlowResolution", 256, "Glow map resolution."); + gSavedSettings.declareBOOL("RenderWaterReflections", FALSE, "Reflect the environment in the water."); + gSavedSettings.declareS32("RenderReflectionDetail", 2, "Detail of reflection render pass."); + gSavedSettings.declareBOOL("RenderGammaFull", TRUE, "Use fully controllable gamma correction, instead of faster, hard-coded gamma correction of 2."); + + gSavedSettings.declareBOOL("RenderGlow", TRUE, "Render bloom post effect."); + gSavedSettings.declareF32("RenderGlowStrength", 0.35f, "Additive strength of glow"); + gSavedSettings.declareF32("RenderGlowWidth", 1.3f, "Glow sample size (higher = wider and softer but eventually more pixelated"); + gSavedSettings.declareS32("RenderGlowIterations", 2, "Number of times to iterate the glow (higher = wider and smoother but slower)"); + gSavedSettings.declareS32("RenderGlowResolutionPow", 9, "Glow map resolution power of two."); + gSavedSettings.declareF32("RenderGlowMinLuminance", 1.0f, "Min luminance intensity necessary to consider an object bright enough to automatically glow. (Gets clamped to 0 - 1.0 range)"); + gSavedSettings.declareF32("RenderGlowMaxExtractAlpha", 0.065f, "Max glow alpha value for brightness extraction to auto-glow."); + + gSavedSettings.declareVec3("RenderGlowLumWeights", LLVector3(0.299f, 0.587f, 0.114f), "Weights for each color channel to be used in calculating luminance (should add up to 1.0)"); + + gSavedSettings.declareVec3("RenderGlowWarmthWeights", LLVector3(1.0f, 0.5f, 0.7f), "Weight of each color channel used before finding the max warmth"); + + gSavedSettings.declareF32("RenderGlowWarmthAmount", 0.f, "Amount of warmth extraction to use (versus luminance extraction). 0 = lum, 1.0 = warmth"); + + gSavedSettings.declareS32("RenderWaterRefResolution", 512, "Water planar reflection resolution."); gSavedSettings.declareBOOL("RenderObjectBump", TRUE, "Show bumpmapping on primitives"); - gSavedSettings.declareS32("RenderAvatarMode", 1, "Controls how avatars are rendered (0 = normal, 1 = bump mapped, 2 = bump mapped and wavy cloth)"); + gSavedSettings.declareBOOL("RenderAvatarCloth", 1, "Controls if avatars use wavy cloth"); gSavedSettings.declareBOOL("RenderAvatarVP", TRUE, "Use vertex programs to perform hardware skinning of avatar"); gSavedSettings.declareS32("RenderAvatarMaxVisible", 35, "Maximum number of avatars to display at any one time"); //gSavedSettings.declareBOOL("RenderForceGetTexImage", FALSE, "[NOT USED]"); - gSavedSettings.declareBOOL("RenderFastUI", FALSE, "[NOT USED]"); - gSavedSettings.declareBOOL("RenderUseSharedDrawables", TRUE, "Collapse transforms on moving linked objects for faster updates"); + gSavedSettings.declareBOOL("RenderFastUI", FALSE, "[NOT USED]"); gSavedSettings.declareS32("DebugBeaconLineWidth", 1, "Size of lines for Debug Beacons"); + gSavedSettings.declareBOOL("RenderCustomSettings", 0, "Do you want to set the graphics settings yourself"); + gSavedSettings.declareU32("RenderQualityPerformance", 1, "Which graphics settings you've chosen"); + + gSavedSettings.declareBOOL("RenderUseShaderLOD", TRUE, "Whether we want to have different shaders for LOD" ); + gSavedSettings.declareF32("RenderShaderLODThreshold", 1.0f, "Fraction of draw distance defining the switch to a different shader LOD"); + gSavedSettings.declareBOOL("RenderUseShaderNearParticles", FALSE, "Whether we want to use shaders on near particles" ); + gSavedSettings.declareF32("RenderShaderParticleThreshold", 0.25f, "Fraction of draw distance to not use shader on particles"); + gSavedSettings.declareBOOL("RenderUseFBO", FALSE, "Whether we want to use GL_EXT_framebuffer_objects."); + gSavedSettings.declareBOOL("RenderUseImpostors", TRUE, "Whether we want to use impostors for far away avatars."); + gSavedSettings.declareBOOL("RenderAppleUseMultGL", FALSE, "Whether we want to use multi-threaded OpenGL on Apple hardware (requires restart of SL)."); + gSavedSettings.declareF32("RenderSunDynamicRange", 1.0f, "Defines what percent brighter the sun is than local point lights (1.0 = 100% brighter. Value should not be less than 0. )."); + gSavedSettings.declareBOOL("RenderUseCleverUI", FALSE, "Turns on the \"clever\" UI rendering optimization. It's a known performace gain (and enabled by default) on apple."); + + //debug render stuff + gSavedSettings.declareBOOL("RenderDebugTextureBind", FALSE, "Enable texture bind performance test."); + // Snapshot params gSavedSettings.declareBOOL("RenderUIInSnapshot", FALSE, "Display user interface in snapshot" ); gSavedSettings.declareBOOL("RenderHUDInSnapshot", FALSE, "Display HUD attachments in snapshot" ); @@ -834,8 +873,9 @@ void declare_settings() gSavedSettings.declareBOOL("FreezeTime", FALSE, "", FALSE ); gSavedSettings.declareBOOL("UseFreezeFrame", FALSE, "Freeze time when taking snapshots."); gSavedSettings.declareBOOL("CloseSnapshotOnKeep", TRUE, "Close snapshot window after saving snapshot" ); - gSavedSettings.declareBOOL("KeepAspectForSnapshot", FALSE, "Use full window when taking snapshot, regardless of requested image size" ); - gSavedSettings.declareBOOL("AutoSnapshot", TRUE, "Update snapshot when camera stops moving, or any parameter changes" ); + gSavedSettings.declareBOOL("KeepAspectForSnapshot", TRUE, "Use full window when taking snapshot, regardless of requested image size" ); + gSavedSettings.declareBOOL("AutoSnapshot", FALSE, "Update snapshot when camera stops moving, or any parameter changes" ); + gSavedSettings.declareBOOL("AdvanceSnapshot", FALSE, "Display advanced parameter settings in snaphot interface" ); gSavedSettings.declareS32("LastSnapshotType", 0, "Select this as next type of snapshot to take (0 = postcard, 1 = texture, 2 = local image)" ); gSavedSettings.declareS32("LastSnapshotWidth", 1024, "The width of the last snapshot, in px" ); gSavedSettings.declareS32("LastSnapshotHeight", 768, "The height of the last snapshot, in px" ); @@ -858,7 +898,7 @@ void declare_settings() gSavedSettings.declareString("StatsFile", "fs.txt", "Filename for stats logging output"); // Image pipeline stuff - gSavedSettings.declareS32("GraphicsCardMemorySetting", -1, "Amount of memory on your video card (-1 = autodetect, 0 = 16MB, 1 = 32MB, 2 = 64MB, 3 = 128MB, 4 = 256MB, 5 = 512MB)"); // default to auto-detect + gSavedSettings.declareS32("TextureMemory", 0, "Amount of memory to use for textures in MB (0 = autodetect)"); // default to auto-detect //gSavedSettings.declareS32("ImageRadioTexMem", 0, "Texture memory allocation (0 = <512 megabytes system RAM, 1 = >512 megabytes system RAM)"); //gSavedSettings.declareS32("ImageRadioVidCardMem", 1, "Video card onboard memory (0 = 16MB, 1 = 32MB, 2 = 64MB, 3 = 128MB, 4 = 256MB, 5 = 512MB)"); //gSavedSettings.declareU32("LastRAMDetected", 0, "[DO NOT MODIFY] Detected system memory (bytes)"); // used to detect RAM changes @@ -928,7 +968,7 @@ void declare_settings() gSavedSettings.declareRect("FloaterJoystickRect", LLRect(0,0,0,0), "Rectangle for joystick controls window."); // Map floater - gSavedSettings.declareRect("FloaterMapRect", LLRect(0, 225, 200, 0), "Rectangle for world map"); + gSavedSettings.declareRect("FloaterMiniMapRect", LLRect(0, 225, 200, 0), "Rectangle for world map"); //Lag-o-Meter floater gSavedSettings.declareRect("FloaterLagMeter", LLRect(0, 142, 350, 0), "Rectangle for lag meter"); @@ -1028,6 +1068,9 @@ void declare_settings() gSavedSettings.declareRect("FloaterOpenObjectRect", LLRect(0, 350, 300, 0), "Rectangle for Open Object window"); // the about box + gSavedSettings.declareRect("FloaterMediaRect", LLRect(0, 400, 400, 0), "Rectangle for media browser window"); + + // the about box gSavedSettings.declareRect("FloaterAboutRect", LLRect(0, 440, 470, 0), "Rectangle for About window"); // the mean box @@ -1036,8 +1079,8 @@ void declare_settings() // the inspect box gSavedSettings.declareRect("FloaterInspectRect", LLRect(0, 400, 400, 0), "Rectangle for Object Inspect window"); - // World map. If 0,0,0,0, will attempt to size to fullscreen. - gSavedSettings.declareRect("FloaterWorldMapRect", + // World map. If 0,0,0,0, will attempt to size to 80% of fullscreen. + gSavedSettings.declareRect("FloaterWorldMapRect2", LLRect(0,0,0,0), "Rectangle for world map window"); // Find dialog. @@ -1101,6 +1144,9 @@ void declare_settings() gSavedSettings.declareF32("FullScreenAspectRatio", 1.3333f, "Aspect ratio of fullscreen display (width / height)"); gSavedSettings.declareBOOL("FullScreenAutoDetectAspectRatio", TRUE, "Automatically detect proper aspect ratio for fullscreen display"); + //resolution divisor + gSavedSettings.declareU32("RenderResolutionDivisor", 1, "Divisor for rendering 3D scene at reduced resolution."); + // UI general settigns gSavedSettings.declareBOOL("TabToTextFieldsOnly", FALSE, "TAB key takes you to next text entry field, instead of next widget"); gSavedSettings.declareF32("UIScaleFactor", 1.f, "Size of UI relative to default layout on 1024x768 screen"); @@ -1159,7 +1205,7 @@ void declare_settings() gSavedSettings.declareF32("AudioLevelAmbient",0.5f, "Audio level of environment sounds"); gSavedSettings.declareF32("AudioLevelUI", 0.5f, "Audio level of UI sound effects"); gSavedSettings.declareF32("AudioLevelMusic", 1.0f, "Audio level of streaming music"); - gSavedSettings.declareF32("AudioLevelVoice", 1.0f, "Audio level of voice chat"); + gSavedSettings.declareF32("AudioLevelVoice", 0.5f, "Audio level of voice chat"); gSavedSettings.declareF32("AudioLevelMedia", 1.0f, "Audio level of Quicktime movies"); gSavedSettings.declareF32("AudioLevelMic", 1.0f, "Audio level of microphone input"); @@ -1171,6 +1217,10 @@ void declare_settings() gSavedSettings.declareBOOL("AudioStreamingMusic", FALSE, "Enable streaming audio"); gSavedSettings.declareBOOL("AudioStreamingVideo", FALSE, "Enable streaming video"); + gSavedSettings.declareBOOL("AutoMimeDiscovery", FALSE, "Enable viewer mime type discovery of media URLs"); + + // Media + gSavedSettings.declareBOOL("ParcelMediaAutoPlayEnable", FALSE, "Auto play parcel media when available"); //UI Sounds @@ -1230,6 +1280,27 @@ void declare_settings() gSavedSettings.declareF32("SkyAmbientScale", 0.3f, "Controls strength of ambient, or non-directional light from the sun and moon (fraction or multiple of default ambient level)"); gSavedSettings.declareColor3("SkyNightColorShift", LLColor3(0.7f, 0.7f, 1.0f), "Controls moonlight color (base color applied to moon as light source)"); gSavedSettings.declareBOOL("FixedWeather", FALSE, "Weather effects do not change over time"); + gSavedSettings.declareU32("WLSkyDetail", 64, "Controls vertex detail on the WindLight sky. Lower numbers will give better performance and uglier skies."); + gSavedSettings.declareBOOL("SkyUseClassicClouds", TRUE, "Whether to use the old Second Life particle clouds or not"); + gSavedSettings.declareBOOL("WindLightUseAtmosShaders", TRUE, "Whether to enable or disable WindLight atmospheric shaders."); + gSavedSettings.declareBOOL("SkyEditPresets", FALSE, "Whether to be able to edit the sky defaults or not"); + + // Water params + gSavedSettings.declareF32("WaterGLFogDepthFloor", 0.25f, "Controls how dark water gl fog can get"); + gSavedSettings.declareF32("WaterGLFogDepthScale", 50.0f, "Controls how quickly gl fog gets dark under water"); + gSavedSettings.declareF32("WaterGLFogDensityScale", 0.02f, "Maps shader water fog density to gl fog density"); + gSavedSettings.declareBOOL("EnableRippleWater", TRUE, "Whether to use ripple water shader or not"); + gSavedSettings.declareBOOL("WaterEditPresets", FALSE, "Whether to be able to edit the water defaults or not"); + + // Windlight window params + gSavedSettings.declareRect("FloaterEnvRect", LLRect(50, 150, 650, 0), "Rectangle for Environment Editor" ); + gSavedSettings.declareRect("FloaterAdvancedSkyRect", LLRect(50, 220, 450, 0), "Rectangle for Advanced Sky Editor" ); + gSavedSettings.declareRect("FloaterDayCycleRect", LLRect(50, 450, 300, 0), "Rectangle for Day Cycle Editor" ); + gSavedSettings.declareRect("FloaterAdvancedWaterRect", LLRect(50, 220, 450, 0), "Rectangle for Advanced Water Editor" ); + + // Tweaked draw distance default settings + gSavedSettings.declareBOOL("Disregard128DefaultDrawDistance", TRUE, "Whether to use the auto default to 128 draw distance"); + gSavedSettings.declareBOOL("Disregard96DefaultDrawDistance", TRUE, "Whether to use the auto default to 96 draw distance"); // Cache Stuff gSavedSettings.declareU32("VFSSalt", 1, "[DO NOT MODIFY] Controls local file caching behavior"); @@ -1403,6 +1474,9 @@ void declare_settings() "m=[MATURE]&t=[TEEN]®ion=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]", "Parameters added to end of search queries"); + // Hide/Show search bar + gSavedSettings.declareBOOL("ShowSearchBar", TRUE, "Show the Search Bar in the Status Overlay"); + // Arrow keys move avatar while in chat? gSavedSettings.declareBOOL("ArrowKeysMoveAvatar", TRUE, "While cursor is in chat entry box, arrow keys still control your avatar"); gSavedSettings.declareBOOL("ChatBarStealsFocus", TRUE, "Whenever keyboard focus is removed from the UI, and the chat bar is visible, the chat bar takes focus"); @@ -1413,6 +1487,9 @@ void declare_settings() // Use DX9 to probe hardware on startup. Only do this once, // because it's slow. gSavedSettings.declareBOOL("ProbeHardwareOnStartup", TRUE, "Query current hardware configuration on application startup"); + + // have we told the user his hardware sucks? Let him know just once + gSavedSettings.declareBOOL("AlertedUnsupportedHardware", FALSE, "Toggle that lets us tell the user he's on old hardware only once"); // enable/disable system color picker gSavedSettings.declareBOOL("UseDefaultColorPicker", FALSE, "Use color picker supplied by operating system"); @@ -1429,9 +1506,7 @@ void declare_settings() gSavedSettings.declareBOOL("ShowAllObjectHoverTip", FALSE, "Show descriptive tooltip when mouse hovers over non-interactive and interactive objects."); // Use an external web browser (Firefox, Internet Explorer) - // CP: making this TRUE by default since there is no internal Web browser - // now and other components may interrogate this setting - gSavedSettings.declareBOOL("UseExternalBrowser", TRUE, "[NOT USED]"); + gSavedSettings.declareBOOL("UseExternalBrowser", FALSE, "Use default browser when opening web pages instead of in-world browser."); gSavedSettings.declareBOOL("CookiesEnabled", TRUE, "Accept cookies from Web sites?"); // browser home page @@ -1449,6 +1524,7 @@ void declare_settings() // use object-object occlusion culling gSavedSettings.declareBOOL("UseOcclusion", TRUE, "Enable object culling based on occlusion (coverage) by other objects"); + gSavedSettings.declareBOOL("RenderFastAlpha", TRUE, "Use lossy alpha rendering optimization (opaque/nonexistent small alpha faces)."); gSavedSettings.declareBOOL("DoubleClickAutoPilot", FALSE, "Enable double-click auto pilot"); @@ -1634,8 +1710,11 @@ class LLReleaseGLBufferListener: public LLSimpleListener { bool handleEvent(LLPointer event, const LLSD& userdata) { - gPipeline.releaseGLBuffers(); - LLShaderMgr::setShaders(); + if (gPipeline.isInit()) + { + gPipeline.releaseGLBuffers(); + gPipeline.createGLBuffers(); + } return true; } }; @@ -1662,6 +1741,20 @@ class LLAvatarLODListener: public LLSimpleListener }; static LLAvatarLODListener avatar_lod_listener; +class LLTerrainLODListener: public LLSimpleListener +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLVOSurfacePatch::sLODFactor = (F32) event->getValue().asReal(); + //sqaure lod factor to get exponential range of [0,4] and keep + //a value of 1 in the middle of the detail slider for consistency + //with other detail sliders (see panel_preferences_graphics1.xml) + LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; + return true; + } +}; +static LLTerrainLODListener terrain_lod_listener; + class LLTreeLODListener: public LLSimpleListener { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -1691,7 +1784,7 @@ class LLGammaListener: public LLSimpleListener { gamma = 1.0f; // restore normal gamma } - if (gamma != gViewerWindow->getWindow()->getGamma()) + if (gViewerWindow && gViewerWindow->getWindow() && gamma != gViewerWindow->getWindow()->getGamma()) { // Only save it if it's changed if (!gViewerWindow->getWindow()->setGamma(gamma)) @@ -1705,17 +1798,7 @@ class LLGammaListener: public LLSimpleListener }; static LLGammaListener gamma_listener; -class LLNightBrightnessListener: public LLSimpleListener -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLVOSky::sNighttimeBrightness = (F32) event->getValue().asReal(); - return true; - } -}; -static LLNightBrightnessListener night_brightness_listener; - -const F32 MAX_USER_FOG_RATIO = 4.f; +const F32 MAX_USER_FOG_RATIO = 10.f; const F32 MIN_USER_FOG_RATIO = 0.5f; class LLFogRatioListener: public LLSimpleListener @@ -1828,8 +1911,7 @@ class LLJoystickListener : public LLSimpleListener }; static LLJoystickListener joystick_listener; -void stop_video(); -void prepare_video(const LLParcel *parcel); + class LLAudioStreamMusicListener: public LLSimpleListener { @@ -1864,92 +1946,137 @@ static LLAudioStreamMusicListener audio_stream_music_listener; -class LLAudioStreamMediaListener: public LLSimpleListener +class LLUseOcclusionListener: public LLSimpleListener +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLPipeline::sUseOcclusion = (event->getValue().asBoolean() && gGLManager.mHasOcclusionQuery + && gFeatureManagerp->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0; + return true; + } +}; +static LLUseOcclusionListener use_occlusion_listener; + +class LLNumpadControlListener: public LLSimpleListener { bool handleEvent(LLPointer event, const LLSD& userdata) { - if (LLMediaEngine::getInstance() && LLMediaEngine::getInstance()->isAvailable()) + if (gKeyboard) { - if (event->getValue().asBoolean()) - { - gMessageSystem->setHandlerFunc ( "ParcelMediaCommandMessage", LLMediaEngine::process_parcel_media ); - gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", LLMediaEngine::process_parcel_media_update ); - if ( ( gParcelMgr ) && - ( gParcelMgr->getAgentParcel () ) && - ( !gParcelMgr->getAgentParcel()->getMediaURL().empty() ) ) - { - prepare_video ( gParcelMgr->getAgentParcel () ); - } - } - else - { - gMessageSystem->setHandlerFunc("ParcelMediaCommandMessage", null_message_callback); - gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", null_message_callback ); - stop_video(); - } + gKeyboard->setNumpadDistinct(static_cast(event->getValue().asInteger())); } - else - { - if (gSavedSettings.getWarning("QuickTimeInstalled")) - { - gSavedSettings.setWarning("QuickTimeInstalled", FALSE); + return true; + } +}; - LLNotifyBox::showXml("NoQuickTime" ); - } +static LLNumpadControlListener numpad_control_listener; + +class LLRenderUseVBOListener: public LLSimpleListener +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + if (gPipeline.isInit()) + { + gPipeline.setUseVBO(event->getValue().asBoolean()); } + return true; + } +}; +static LLRenderUseVBOListener render_use_vbo_listener; +class LLWLSkyDetailListener: public LLSimpleListener +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + if (gSky.mVOWLSkyp.notNull()) + { + gSky.mVOWLSkyp->updateGeometry(gSky.mVOWLSkyp->mDrawable); + } return true; } }; +static LLWLSkyDetailListener wl_sky_detail_listener; -static LLAudioStreamMediaListener audio_stream_media_listener; +class LLRenderLightingDetailListener: public LLSimpleListener +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + if (gPipeline.isInit()) + { + gPipeline.setLightingDetail(event->getValue().asInteger()); + } + return true; + } +}; +static LLRenderLightingDetailListener render_lighting_detail_listener; +class LLResetVertexBuffersListener: public LLSimpleListener +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + if (gPipeline.isInit()) + { + gPipeline.resetVertexBuffers(); + } + return true; + } +}; +static LLResetVertexBuffersListener reset_vbo_listener; -class LLUseOcclusionListener: public LLSimpleListener +class LLRenderDynamicLODListener: public LLSimpleListener { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLPipeline::sUseOcclusion = (event->getValue().asBoolean() && gGLManager.mHasOcclusionQuery - && gFeatureManagerp->isFeatureAvailable("UseOcclusion") && !gUseWireframe); + LLPipeline::sDynamicLOD = event->getValue().asBoolean(); return true; } }; -static LLUseOcclusionListener use_occlusion_listener; +static LLRenderDynamicLODListener render_dynamic_lod_listener; -class LLNumpadControlListener: public LLSimpleListener +class LLRenderUseFBOListener: public LLSimpleListener { bool handleEvent(LLPointer event, const LLSD& userdata) { - if (gKeyboard) + LLRenderTarget::sUseFBO = event->getValue().asBoolean(); + if (gPipeline.isInit()) { - gKeyboard->setNumpadDistinct(static_cast(event->getValue().asInteger())); + gPipeline.releaseGLBuffers(); + gPipeline.createGLBuffers(); } return true; } }; +static LLRenderUseFBOListener render_use_fbo_listener; -static LLNumpadControlListener numpad_control_listener; - -class LLRenderUseVBOListener: public LLSimpleListener +class LLRenderUseImpostorsListener : public LLSimpleListener { bool handleEvent(LLPointer event, const LLSD& userdata) { - gPipeline.setUseVBO(event->getValue().asBoolean()); + LLVOAvatar::sUseImpostors = event->getValue().asBoolean(); return true; } }; -static LLRenderUseVBOListener render_use_vbo_listener; +static LLRenderUseImpostorsListener render_use_impostors_listener; -class LLRenderLightingDetailListener: public LLSimpleListener +class LLRenderUseCleverUIListener : public LLSimpleListener { bool handleEvent(LLPointer event, const LLSD& userdata) { - gPipeline.setLightingDetail(event->getValue().asInteger()); + gGL.setClever(event->getValue().asBoolean()); return true; } }; -static LLRenderLightingDetailListener render_lighting_detail_listener; +static LLRenderUseCleverUIListener render_use_clever_ui_listener; +class LLRenderResolutionDivisorListener : public LLSimpleListener +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + gResizeScreenTexture = TRUE; + return true; + } +}; +static LLRenderResolutionDivisorListener render_resolution_divisor_listener; //////////////////////////////////////////////////////////////////////////// void settings_setup_listeners() @@ -1960,24 +2087,36 @@ void settings_setup_listeners() gSavedSettings.getControl("AFKTimeout")->addListener(&afk_timeout_listener); gSavedSettings.getControl("RenderFarClip")->addListener(&render_far_clip_listener); gSavedSettings.getControl("RenderTerrainDetail")->addListener(&terrain_detail_listener); - gSavedSettings.getControl("RenderRippleWater")->addListener(&set_shader_listener); gSavedSettings.getControl("RenderAvatarVP")->addListener(&set_shader_listener); gSavedSettings.getControl("VertexShaderEnable")->addListener(&set_shader_listener); gSavedSettings.getControl("RenderDynamicReflections")->addListener(&set_shader_listener); gSavedSettings.getControl("RenderGlow")->addListener(&release_gl_buffer_listener); - gSavedSettings.getControl("RenderGlowResolution")->addListener(&release_gl_buffer_listener); - gSavedSettings.getControl("RenderAvatarMode")->addListener(&set_shader_listener); + gSavedSettings.getControl("RenderGlow")->addListener(&set_shader_listener); + gSavedSettings.getControl("EnableRippleWater")->addListener(&set_shader_listener); + gSavedSettings.getControl("RenderGlowResolutionPow")->addListener(&release_gl_buffer_listener); + gSavedSettings.getControl("RenderAvatarCloth")->addListener(&set_shader_listener); + gSavedSettings.getControl("WindLightUseAtmosShaders")->addListener(&set_shader_listener); + gSavedSettings.getControl("RenderGammaFull")->addListener(&set_shader_listener); gSavedSettings.getControl("RenderVolumeLODFactor")->addListener(&volume_lod_listener); gSavedSettings.getControl("RenderAvatarLODFactor")->addListener(&avatar_lod_listener); + gSavedSettings.getControl("RenderTerrainLODFactor")->addListener(&terrain_lod_listener); gSavedSettings.getControl("RenderTreeLODFactor")->addListener(&tree_lod_listener); gSavedSettings.getControl("RenderFlexTimeFactor")->addListener(&flex_lod_listener); gSavedSettings.getControl("ThrottleBandwidthKBPS")->addListener(&bandwidth_listener); gSavedSettings.getControl("RenderGamma")->addListener(&gamma_listener); - gSavedSettings.getControl("RenderNightBrightness")->addListener(&night_brightness_listener); gSavedSettings.getControl("RenderFogRatio")->addListener(&fog_ratio_listener); gSavedSettings.getControl("RenderMaxPartCount")->addListener(&max_partCount_listener); + gSavedSettings.getControl("RenderDynamicLOD")->addListener(&render_dynamic_lod_listener); + gSavedSettings.getControl("RenderDebugTextureBind")->addListener(&reset_vbo_listener); + gSavedSettings.getControl("RenderFastAlpha")->addListener(&reset_vbo_listener); + gSavedSettings.getControl("RenderObjectBump")->addListener(&reset_vbo_listener); + gSavedSettings.getControl("RenderMaxVBOSize")->addListener(&reset_vbo_listener); + gSavedSettings.getControl("RenderUseFBO")->addListener(&render_use_fbo_listener); + gSavedSettings.getControl("RenderUseImpostors")->addListener(&render_use_impostors_listener); + gSavedSettings.getControl("RenderUseCleverUI")->addListener(&render_use_clever_ui_listener); + gSavedSettings.getControl("RenderResolutionDivisor")->addListener(&render_resolution_divisor_listener); gSavedSettings.getControl("AvatarCompositeLimit")->addListener(&composite_limit_listener); - gSavedSettings.getControl("GraphicsCardMemorySetting")->addListener(&video_memory_listener); + gSavedSettings.getControl("TextureMemory")->addListener(&video_memory_listener); gSavedSettings.getControl("ChatFontSize")->addListener(&chat_font_size_listener); gSavedSettings.getControl("ChatPersistTime")->addListener(&chat_persist_time_listener); gSavedSettings.getControl("ConsoleMaxLines")->addListener(&console_max_lines_listener); @@ -1993,7 +2132,7 @@ void settings_setup_listeners() gSavedSettings.getControl("AudioLevelDoppler")->addListener(&audio_listener); gSavedSettings.getControl("AudioLevelRolloff")->addListener(&audio_listener); gSavedSettings.getControl("AudioStreamingMusic")->addListener(&audio_stream_music_listener); - gSavedSettings.getControl("AudioStreamingVideo")->addListener(&audio_stream_media_listener); + // AudioStreamingVideo initialized in llviewermedia.cpp gSavedSettings.getControl("MuteAudio")->addListener(&audio_listener); gSavedSettings.getControl("MuteMusic")->addListener(&audio_listener); gSavedSettings.getControl("MuteMedia")->addListener(&audio_listener); @@ -2001,6 +2140,7 @@ void settings_setup_listeners() gSavedSettings.getControl("MuteAmbient")->addListener(&audio_listener); gSavedSettings.getControl("MuteUI")->addListener(&audio_listener); gSavedSettings.getControl("RenderVBOEnable")->addListener(&render_use_vbo_listener); + gSavedSettings.getControl("WLSkyDetail")->addListener(&wl_sky_detail_listener); gSavedSettings.getControl("RenderLightingDetail")->addListener(&render_lighting_detail_listener); gSavedSettings.getControl("NumpadControl")->addListener(&numpad_control_listener); gSavedSettings.getControl("FlycamAxis0")->addListener(&joystick_listener); diff --git a/linden/indra/newview/llcubemap.cpp b/linden/indra/newview/llcubemap.cpp index c8e0d50..baa33ac 100644 --- a/linden/indra/newview/llcubemap.cpp +++ b/linden/indra/newview/llcubemap.cpp @@ -57,6 +57,7 @@ const BOOL use_cube_mipmaps = FALSE; //current build works best without cube mi LLCubeMap::LLCubeMap() : mTextureStage(0), + mTextureCoordStage(0), mMatrixStage(0) { } @@ -184,6 +185,7 @@ void LLCubeMap::bind() ) { // We assume that if they have cube mapping, they have multitexturing. + glActiveTextureARB(GL_TEXTURE0_ARB + mTextureStage); glEnable(GL_TEXTURE_CUBE_MAP_ARB); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mImages[0]->getTexName()); @@ -198,6 +200,12 @@ void LLCubeMap::bind() void LLCubeMap::enable(S32 stage) { + enableTexture(stage); + enableTextureCoords(stage); +} + +void LLCubeMap::enableTexture(S32 stage) +{ mTextureStage = stage; if (gGLManager.mHasCubeMap && stage >= 0 @@ -207,6 +215,16 @@ void LLCubeMap::enable(S32 stage) glActiveTextureARB(GL_TEXTURE0_ARB + stage); // NOTE: leaves texture stage set glEnable(GL_TEXTURE_CUBE_MAP_ARB); + } +} + +void LLCubeMap::enableTextureCoords(S32 stage) +{ + mTextureCoordStage = stage; + if (gGLManager.mHasCubeMap && stage >= 0) + { + glActiveTextureARB(GL_TEXTURE0_ARB + stage); // NOTE: leaves texture stage set + glEnable(GL_TEXTURE_GEN_R); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); @@ -214,10 +232,18 @@ void LLCubeMap::enable(S32 stage) glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + + glActiveTextureARB(GL_TEXTURE0_ARB); } } -void LLCubeMap::disable() +void LLCubeMap::disable(void) +{ + disableTexture(); + disableTextureCoords(); +} + +void LLCubeMap::disableTexture(void) { if (gGLManager.mHasCubeMap && mTextureStage >= 0 //&& gFeatureManagerp->isFeatureAvailable("RenderCubeMap") @@ -225,10 +251,18 @@ void LLCubeMap::disable() { glActiveTextureARB(GL_TEXTURE0_ARB + mTextureStage); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0); + glDisable(GL_TEXTURE_CUBE_MAP_ARB); + } +} + +void LLCubeMap::disableTextureCoords(void) +{ + if (gGLManager.mHasCubeMap && mTextureCoordStage >= 0) + { + glActiveTextureARB(GL_TEXTURE0_ARB + mTextureCoordStage); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); - glDisable(GL_TEXTURE_CUBE_MAP_ARB); } } @@ -250,6 +284,7 @@ void LLCubeMap::setMatrix(S32 stage) glPushMatrix(); glLoadMatrixf((F32 *)trans.mMatrix); glMatrixMode(GL_MODELVIEW); + glActiveTextureARB(GL_TEXTURE0_ARB); } void LLCubeMap::restoreMatrix() @@ -258,6 +293,7 @@ void LLCubeMap::restoreMatrix() glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(GL_MODELVIEW); + glActiveTextureARB(GL_TEXTURE0_ARB); } LLVector3 LLCubeMap::map(U8 side, U16 v_val, U16 h_val) const diff --git a/linden/indra/newview/llcubemap.h b/linden/indra/newview/llcubemap.h index 7a59bb3..a4d9106 100644 --- a/linden/indra/newview/llcubemap.h +++ b/linden/indra/newview/llcubemap.h @@ -51,7 +51,13 @@ public: void bind(); void enable(S32 stage); - void disable(); + + void enableTexture(S32 stage); + void enableTextureCoords(S32 stage); + + void disable(void); + void disableTexture(void); + void disableTextureCoords(void); void setMatrix(S32 stage); void restoreMatrix(); @@ -73,6 +79,7 @@ protected: LLPointer mImages[6]; LLPointer mRawImages[6]; S32 mTextureStage; + S32 mTextureCoordStage; S32 mMatrixStage; }; diff --git a/linden/indra/newview/lldebugmessagebox.cpp b/linden/indra/newview/lldebugmessagebox.cpp index 4afbde3..8d516d8 100644 --- a/linden/indra/newview/lldebugmessagebox.cpp +++ b/linden/indra/newview/lldebugmessagebox.cpp @@ -39,7 +39,6 @@ #include "llsliderctrl.h" #include "llcheckboxctrl.h" #include "lltextbox.h" -#include "llcallbacklist.h" #include "lllineeditor.h" #include "llfocusmgr.h" diff --git a/linden/indra/newview/lldrawable.cpp b/linden/indra/newview/lldrawable.cpp index a86fc07..4b6bd7c 100644 --- a/linden/indra/newview/lldrawable.cpp +++ b/linden/indra/newview/lldrawable.cpp @@ -94,11 +94,7 @@ void LLDrawable::init() mRenderType = 0; mCurrentScale = LLVector3(1,1,1); mDistanceWRTCamera = 0.0f; - // mUVRect - mUVZ = 0.f; - // mLightSet - // mBlockSet - // mSavePos + mQuietCount = 0; mState = 0; @@ -107,7 +103,6 @@ void LLDrawable::init() mSpatialGroupp = NULL; mVisible = 0; mRadius = 0.f; - mSunShadowFactor = 1.f; mGeneration = -1; mBinRadius = 1.f; @@ -185,21 +180,6 @@ BOOL LLDrawable::isLight() const } } -void LLDrawable::clearLightSet() -{ - // Remove this object from any object which has it as a light - for (drawable_set_t::iterator iter = mLightSet.begin(); iter != mLightSet.end(); iter++) - { - LLDrawable *targetp = *iter; - if (targetp != this && !targetp->isDead()) - { - targetp->mLightSet.erase(this); - gPipeline.markRelight(targetp); - } - } - mLightSet.clear(); -} - void LLDrawable::cleanupReferences() { LLFastTimer t(LLFastTimer::FTM_PIPELINE); @@ -207,12 +187,8 @@ void LLDrawable::cleanupReferences() std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); mFaces.clear(); - clearLightSet(); - gObjectList.removeDrawable(this); - mBlockSet.clear(); - gPipeline.unlinkDrawable(this); // Cleanup references to other objects @@ -239,16 +215,6 @@ void LLDrawable::cleanupDeadDrawables() S32 LLDrawable::findReferences(LLDrawable *drawablep) { S32 count = 0; - if (mLightSet.count(drawablep) > 0) - { - llinfos << this << ": lightset reference" << llendl; - count++; - } - if (mBlockSet.count(drawablep) > 0) - { - llinfos << this << ": blockset reference" << llendl; - count++; - } if (mParent == drawablep) { llinfos << this << ": parent reference" << llendl; @@ -257,20 +223,6 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep) return count; } -#if 0 -// SJB: This is SLOW, so we don't want to allow it (we don't currently use it) -void LLDrawable::removeFace(const S32 i) -{ - LLFace *face= mFaces[i]; - - if (face) - { - mFaces.erase(mFaces.begin() + i); - delete face; - } -} -#endif - LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep) { LLMemType mt(LLMemType::MTYPE_DRAWABLE); @@ -299,11 +251,13 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerImage *texturep) { LLMemType mt(LLMemType::MTYPE_DRAWABLE); - LLFace *face = new LLFace(this, mVObjp); + LLFace *face; + face = new LLFace(this, mVObjp); face->setTEOffset(mFaces.size()); face->setTexture(texturep); face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep)); + mFaces.push_back(face); if (isState(UNLIT)) @@ -399,7 +353,6 @@ void LLDrawable::makeActive() pcode == LLViewerObject::LL_VO_SURFACE_PATCH || pcode == LLViewerObject::LL_VO_PART_GROUP || pcode == LLViewerObject::LL_VO_CLOUDS || - pcode == LLViewerObject::LL_VO_STARS || pcode == LLViewerObject::LL_VO_GROUND || pcode == LLViewerObject::LL_VO_SKY) { @@ -429,22 +382,22 @@ void LLDrawable::makeActive() drawable->makeActive(); } } - + if (mVObjp->getPCode() == LL_PCODE_VOLUME) { - if (mVObjp->getVolume()->getPathType() == LL_PCODE_PATH_FLEXIBLE) + if (mVObjp->isFlexible()) { return; } } - clearState(LLDrawable::LIGHTING_BUILT); if (mVObjp->getPCode() == LL_PCODE_VOLUME) { gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE); } + updatePartition(); } - updatePartition(); + if (isRoot()) { mQuietCount = 0; @@ -482,7 +435,6 @@ void LLDrawable::makeStatic() } } - gPipeline.markRelight(this); if (mVObjp->getPCode() == LL_PCODE_VOLUME) { gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE); @@ -526,8 +478,8 @@ F32 LLDrawable::updateXform(BOOL undamped) // Damping F32 dist_squared = 0.f; - F32 scaled = 0.f; - + F32 camdist2 = (mDistanceWRTCamera * mDistanceWRTCamera); + if (damped && mDistanceWRTCamera > 0.0f) { F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f); @@ -538,10 +490,8 @@ F32 LLDrawable::updateXform(BOOL undamped) dist_squared += (1.f - dot(new_rot, target_rot)) * 10.f; LLVector3 new_scale = lerp(old_scale, target_scale, lerp_amt); - scaled = dist_vec_squared(new_scale, target_scale); + dist_squared += dist_vec_squared(new_scale, target_scale); - dist_squared += scaled; - F32 camdist2 = (mDistanceWRTCamera * mDistanceWRTCamera); if ((dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED * camdist2) && (dist_squared <= MAX_INTERPOLATE_DISTANCE_SQUARED)) { @@ -549,12 +499,6 @@ F32 LLDrawable::updateXform(BOOL undamped) target_pos = new_pos; target_rot = new_rot; target_scale = new_scale; - - if (scaled >= MIN_INTERPOLATE_DISTANCE_SQUARED) - { - //scaling requires an immediate rebuild - gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); - } } else { @@ -562,7 +506,17 @@ F32 LLDrawable::updateXform(BOOL undamped) dist_squared = 0.0f; } } - + + if ((mCurrentScale != target_scale) || + (!isRoot() && (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED*camdist2))) + { //child prim moving or scale change requires immediate rebuild + gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); + } + else if (!getVOVolume() && !isAvatar()) + { + movePartition(); + } + // Update mXform.setPosition(target_pos); mXform.setRotation(target_rot); @@ -571,6 +525,10 @@ F32 LLDrawable::updateXform(BOOL undamped) mCurrentScale = target_scale; + if (mSpatialBridge) + { + gPipeline.markMoved(mSpatialBridge, FALSE); + } return dist_squared; } @@ -591,18 +549,6 @@ void LLDrawable::moveUpdatePipeline(BOOL moved) { getFace(i)->updateCenterAgent(); } - - if (moved || !isState(LLDrawable::BUILT)) // moved since last frame - { - LLVector3 tmp = mSavePos - mXform.getPositionW(); - F32 dist = tmp.magVecSquared(); // moved since last _update_ - - if (dist > 1.0f || !isState(LLDrawable::BUILT) || isLight()) - { - mSavePos = mXform.getPositionW(); - gPipeline.markRelight(this); - } - } } void LLDrawable::movePartition() @@ -703,17 +649,21 @@ BOOL LLDrawable::updateMoveDamped() void LLDrawable::updateDistance(LLCamera& camera) { //switch LOD with the spatial group to avoid artifacts - LLSpatialGroup* sg = getSpatialGroup(); + //LLSpatialGroup* sg = getSpatialGroup(); LLVector3 pos; - if (!sg || sg->changeLOD()) + //if (!sg || sg->changeLOD()) { LLVOVolume* volume = getVOVolume(); if (volume) { volume->updateRelativeXform(); - pos = LLVector3(0,0,0) * volume->getRelativeXform(); + pos = volume->getRelativeXform().getTranslation(); + if (isStatic()) + { + pos += volume->getRegion()->getOriginAgent(); + } for (S32 i = 0; i < getNumFaces(); i++) { @@ -761,7 +711,7 @@ void LLDrawable::updateTexture() { if (!isActive()) { - gPipeline.markMoved(this); + //gPipeline.markMoved(this); } else { @@ -783,18 +733,6 @@ BOOL LLDrawable::updateGeometry(BOOL priority) { llassert(mVObjp.notNull()); BOOL res = mVObjp->updateGeometry(this); - if (isState(REBUILD_LIGHTING)) - { - updateLighting(priority ? FALSE : TRUE); // only do actual lighting for non priority updates - if (priority) - { - gPipeline.markRelight(this); // schedule non priority update - } - else - { - clearState(REBUILD_LIGHTING); - } - } return res; } @@ -821,7 +759,11 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector) if (isStatic()) { - gPipeline.markRebuild(this, LLDrawable::REBUILD_GEOMETRY, TRUE); + LLVOVolume* volume = getVOVolume(); + if (!volume) + { + gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE); + } for (S32 i = 0; i < getNumFaces(); i++) { @@ -830,7 +772,7 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector) facep->mExtents[0] += shift_vector; facep->mExtents[1] += shift_vector; - if (facep->hasGeometry()) + if (!volume && facep->hasGeometry()) { facep->mVertexBuffer = NULL; facep->mLastVertexBuffer = NULL; @@ -845,9 +787,13 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector) { mSpatialBridge->shiftPos(shift_vector); } + else if (isAvatar()) + { + mExtents[0] += shift_vector; + mExtents[1] += shift_vector; + mPositionGroup += LLVector3d(shift_vector); + } - mSavePos = mXform.getPositionW(); - mVObjp->onShift(shift_vector); } @@ -894,64 +840,11 @@ void LLDrawable::updateBinRadius() { if (mVObjp.notNull()) { - mBinRadius = mVObjp->getBinRadius(); + mBinRadius = llmin(mVObjp->getBinRadius(), 256.f); } else { - mBinRadius = getRadius()*4.f; - } -} - -void LLDrawable::updateLightSet() -{ - if (isDead()) - { - llwarns << "Updating light set for dead drawable!" << llendl; - return; - } - - LLSpatialPartition* part = gPipeline.getSpatialPartition(LLPipeline::PARTITION_VOLUME); - LLVOVolume* light = getVOVolume(); - if (isLight() && light) - { - // mLightSet points to lit objects - for (drawable_set_t::iterator iter = mLightSet.begin(); iter != mLightSet.end(); iter++) - { - gPipeline.markRelight(*iter); - } - mLightSet.clear(); - part->getObjects(getPositionAgent(), light->getLightRadius(), mLightSet); - for (drawable_set_t::iterator iter = mLightSet.begin(); iter != mLightSet.end(); iter++) - { - gPipeline.markRelight(*iter); - } - } - else - { - // mLightSet points to nearby lights - mLightSet.clear(); - part->getLights(getPositionAgent(), getRadius(), mLightSet); - const drawable_set_t::size_type MAX_LIGHTS = 16; - if (mLightSet.size() > MAX_LIGHTS) - { - typedef std::set > > sorted_pair_set_t; - sorted_pair_set_t sorted_set; - for (drawable_set_t::iterator iter = mLightSet.begin(); iter != mLightSet.end(); iter++) - { - LLDrawable* drawable = *iter; - LLVector3 dvec = drawable->getPositionAgent() - getPositionAgent(); - F32 dist2 = dvec.magVecSquared(); - sorted_set.insert(std::make_pair(dist2, drawable)); - } - mLightSet.clear(); - S32 count = 0; - for (sorted_pair_set_t::iterator iter = sorted_set.begin(); iter != sorted_set.end(); iter++) - { - if (++count > 16) - break; - mLightSet.insert((*iter).second); - } - } + mBinRadius = llmin(getRadius()*4.f, 256.f); } } @@ -962,72 +855,6 @@ void LLDrawable::updateSpecialHoverCursor(BOOL enabled) // hover cursor selection. JC } -BOOL LLDrawable::updateLighting(BOOL do_lighting) -{ - if (do_lighting) - { - if (gPipeline.getLightingDetail() >= 2 && (getLit() || isLight())) - { - LLFastTimer t(LLFastTimer::FTM_UPDATE_LIGHTS); - updateLightSet(); - do_lighting = isLight() ? FALSE : TRUE; - } - else - { - do_lighting = FALSE; - } - } - if (gPipeline.getLightingDetail() >= 2) - { - LLFastTimer t(LLFastTimer::FTM_GEO_LIGHT); - if (mVObjp->updateLighting(do_lighting)) - { - setState(LIGHTING_BUILT); - } - } - - return TRUE; -} - -void LLDrawable::applyLightsAsPoint(LLColor4& result) -{ - LLMemType mt1(LLMemType::MTYPE_DRAWABLE); - - LLVector3 point_agent(getPositionAgent()); - LLVector3 normal(-gCamera->getXAxis()); // make point agent face camera - - F32 sun_int = normal * gPipeline.mSunDir; - LLColor4 color(gSky.getTotalAmbientColor()); - color += gPipeline.mSunDiffuse * sun_int; - - for (drawable_set_t::iterator iter = mLightSet.begin(); - iter != mLightSet.end(); ++iter) - { - LLDrawable* drawable = *iter; - LLVOVolume* light = drawable->getVOVolume(); - if (!light) - { - continue; - } - LLColor4 light_color; - light->calcLightAtPoint(point_agent, normal, light_color); - color += light_color; - } - - // Clamp the color... - color.mV[0] = llmax(color.mV[0], 0.f); - color.mV[1] = llmax(color.mV[1], 0.f); - color.mV[2] = llmax(color.mV[2], 0.f); - - F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]); - if (max_color > 1.f) - { - color *= 1.f/max_color; - } - - result = color; -} - F32 LLDrawable::getVisibilityRadius() const { if (isDead()) @@ -1053,10 +880,10 @@ void LLDrawable::updateUVMinMax() void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) { - if (mSpatialGroupp && (groupp != mSpatialGroupp)) +/*if (mSpatialGroupp && (groupp != mSpatialGroupp)) { mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY); - } + }*/ mSpatialGroupp = groupp; } @@ -1113,7 +940,7 @@ BOOL LLDrawable::isVisible() const { LLSpatialGroup* group = mSpatialBridge.notNull() ? mSpatialBridge->getSpatialGroup() : getSpatialGroup(); - if (!group || group->isVisible()) + if (group && group->isVisible()) { mVisible = sCurVisible; return TRUE; @@ -1131,7 +958,7 @@ BOOL LLDrawable::isVisible() const else { LLSpatialGroup* group = getSpatialGroup(); - if (!group || group->isVisible()) + if (group && group->isVisible()) { mVisible = sCurVisible; return TRUE; @@ -1154,18 +981,19 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, U32 data_mask) mRenderType = mDrawable->mRenderType; mDrawableType = mDrawable->mRenderType; - mPartitionType = LLPipeline::PARTITION_VOLUME; + mPartitionType = LLViewerRegion::PARTITION_VOLUME; mOctree->balance(); - gPipeline.getSpatialPartition(mPartitionType)->put(this); + mDrawable->getRegion()->getSpatialPartition(mPartitionType)->put(this); } LLSpatialBridge::~LLSpatialBridge() { - if (getSpatialGroup()) + LLSpatialGroup* group = getSpatialGroup(); + if (group) { - gPipeline.getSpatialPartition(mPartitionType)->remove(this, getSpatialGroup()); + group->mSpatialPartition->remove(this, group); } } @@ -1252,6 +1080,11 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) up_axis *= rot; left_axis *= rot; + if (!delta.isFinite()) + { + delta.clearVec(); + } + ret.setOrigin(delta); ret.setAxes(lookAt, left_axis, up_axis); @@ -1305,13 +1138,13 @@ public: virtual void traverse(const LLOctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - group->clearState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED); + group->setVisible(); LLOctreeTraveler::traverse(node); } - void visit(const LLOctreeState* branch) + void visit(const LLOctreeNode* branch) { - gPipeline.markNotCulled((LLSpatialGroup*) branch->getListener(0), *mCamera, TRUE); + gPipeline.markNotCulled((LLSpatialGroup*) branch->getListener(0), *mCamera); } }; @@ -1322,17 +1155,26 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* return; } + + //HACK don't draw attachments for avatars that haven't been visible in more than a frame LLViewerObject *vobj = mDrawable->getVObj(); if (vobj && vobj->isAttachment() && !vobj->isHUDAttachment()) { - LLVOAvatar* av; + LLDrawable* av; LLDrawable* parent = mDrawable->getParent(); if (parent) { - av = (LLVOAvatar*) parent->getVObj().get(); - - if (!av->isVisible()) + LLViewerObject* objparent = parent->getVObj(); + av = objparent->mDrawable; + LLSpatialGroup* group = av->getSpatialGroup(); + + BOOL impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor(); + + if (!group || + av->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance || + LLDrawable::getCurrentFrame() - av->mVisible > 1 || + impostor) { return; } @@ -1346,7 +1188,8 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* LLVector3 center = (mExtents[0] + mExtents[1]) * 0.5f; LLVector3 size = (mExtents[1]-mExtents[0]) * 0.5f; - if (camera_in.AABBInFrustum(center, size)) + if (camera_in.AABBInFrustumNoFarClip(center, size) && + AABBSphereIntersect(mExtents[0], mExtents[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist)) { if (LLPipeline::calcPixelArea(center, size, camera_in) < FORCE_INVISIBLE_AREA) { @@ -1392,7 +1235,11 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in) llwarns << "Corrupt drawable found while updating spatial bridge distance." << llendl; continue; } - child->updateDistance(camera); + + if (!child->isAvatar()) + { + child->updateDistance(camera); + } } } @@ -1401,11 +1248,6 @@ void LLSpatialBridge::makeActive() llerrs << "makeActive called on spatial bridge" << llendl; } -void LLSpatialBridge::makeStatic() -{ - llerrs << "makeStatic called on spatial bridge" << llendl; -} - void LLSpatialBridge::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate) { LLSpatialPartition::move(drawablep, curp, immediate); @@ -1415,7 +1257,7 @@ void LLSpatialBridge::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL imm BOOL LLSpatialBridge::updateMove() { mOctree->balance(); - gPipeline.getSpatialPartition(mPartitionType)->move(this, getSpatialGroup(), TRUE); + mDrawable->getRegion()->getSpatialPartition(mPartitionType)->move(this, getSpatialGroup(), TRUE); return TRUE; } @@ -1453,14 +1295,12 @@ const LLVector3 LLDrawable::getPositionAgent() const { if (isActive()) { - if (isRoot()) - { - return LLVector3(0,0,0) * getWorldMatrix(); - } - else + LLVector3 pos(0,0,0); + if (!isRoot()) { - return mVObjp->getPosition() * getParent()->getWorldMatrix(); + pos = mVObjp->getPosition(); } + return pos * getRenderMatrix(); } else { @@ -1485,11 +1325,6 @@ BOOL LLDrawable::isAnimating() const return TRUE; } - if (mVObjp->isFlexible()) - { - return TRUE; - } - if (mVObjp->getPCode() == LLViewerObject::LL_VO_PART_GROUP) { return TRUE; @@ -1500,12 +1335,6 @@ BOOL LLDrawable::isAnimating() const return TRUE; } - LLVOVolume* vol = getVOVolume(); - if (vol && vol->mTextureAnimp) - { - return TRUE; - } - if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero()) { return TRUE; @@ -1527,16 +1356,16 @@ LLBridgePartition::LLBridgePartition() { mRenderByGroup = FALSE; mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; - mPartitionType = LLPipeline::PARTITION_BRIDGE; - mLODPeriod = 1; - mSlopRatio = 0.f; + mPartitionType = LLViewerRegion::PARTITION_BRIDGE; + mLODPeriod = 16; + mSlopRatio = 0.25f; } LLHUDBridge::LLHUDBridge(LLDrawable* drawablep) : LLVolumeBridge(drawablep) { mDrawableType = LLPipeline::RENDER_TYPE_HUD; - mPartitionType = LLPipeline::PARTITION_HUD; + mPartitionType = LLViewerRegion::PARTITION_HUD; mSlopRatio = 0.0f; } diff --git a/linden/indra/newview/lldrawable.h b/linden/indra/newview/lldrawable.h index 1903587..8493747 100644 --- a/linden/indra/newview/lldrawable.h +++ b/linden/indra/newview/lldrawable.h @@ -83,7 +83,7 @@ public: virtual void setVisible(LLCamera& camera_in, std::vector* results = NULL, BOOL for_select = FALSE); - const LLViewerRegion* getRegion() const { return mVObjp->getRegion(); } + LLViewerRegion* getRegion() const { return mVObjp->getRegion(); } const LLTextureEntry* getTextureEntry(U8 which) const { return mVObjp->getTE(which); } LLPointer& getVObj() { return mVObjp; } const LLViewerObject *getVObj() const { return mVObjp; } @@ -153,13 +153,8 @@ public: void updateMaterial(); virtual void updateDistance(LLCamera& camera); BOOL updateGeometry(BOOL priority); - BOOL updateLighting(BOOL priority); void updateFaceSize(S32 idx); - void updateLightSet(); - - F32 getSunShadowFactor() const { return mSunShadowFactor; } - void setSunShadowFactor(F32 factor) { mSunShadowFactor = factor; } - void applyLightsAsPoint(LLColor4& result); + void updateSpecialHoverCursor(BOOL enabled); virtual void shiftPos(const LLVector3 &shift_vector); @@ -169,7 +164,6 @@ public: BOOL getLit() const { return isState(UNLIT) ? FALSE : TRUE; } void setLit(BOOL lit) { lit ? clearState(UNLIT) : setState(UNLIT); } - void clearLightSet(); virtual void cleanupReferences(); void setRadius(const F32 radius); @@ -245,7 +239,6 @@ public: typedef enum e_drawable_flags { -// TEXTURE = 0x00000001, IN_REBUILD_Q1 = 0x00000002, IN_REBUILD_Q2 = 0x00000004, IN_LIGHT_Q = 0x00000008, @@ -260,13 +253,11 @@ public: REBUILD_VOLUME = 0x00001000, //volume changed LOD or parameters, or vertex buffer changed REBUILD_TCOORD = 0x00002000, //texture coordinates changed REBUILD_COLOR = 0x00004000, //color changed - REBUILD_LIGHTING= 0x00008000, //lighting information changed REBUILD_POSITION= 0x00010000, //vertex positions/normals changed REBUILD_GEOMETRY= REBUILD_POSITION|REBUILD_TCOORD|REBUILD_COLOR, REBUILD_MATERIAL= REBUILD_TCOORD|REBUILD_COLOR, - REBUILD_ALL = REBUILD_GEOMETRY|REBUILD_LIGHTING|REBUILD_VOLUME, + REBUILD_ALL = REBUILD_GEOMETRY|REBUILD_VOLUME, ON_SHIFT_LIST = 0x00100000, -// NO_INTERP_COLOR = 0x00200000, BLOCKER = 0x00400000, ACTIVE = 0x00800000, DEAD = 0x01000000, @@ -284,14 +275,7 @@ public: LLPointer mParent; F32 mDistanceWRTCamera; - - LLRectf mUVRect; - F32 mUVZ; - - drawable_set_t mLightSet; - drawable_set_t mBlockSet; - - LLVector3 mSavePos; + S32 mQuietCount; static S32 getCurrentFrame() { return sCurVisible; } @@ -301,7 +285,7 @@ public: static F32 sCurPixelAngle; //current pixels per radian -protected: +private: typedef std::vector face_list_t; U32 mState; @@ -318,8 +302,6 @@ protected: F64 mBinRadius; S32 mGeneration; - F32 mSunShadowFactor; - LLVector3 mCurrentScale; static U32 sCurVisible; // Counter for what value of mVisible means currently visible diff --git a/linden/indra/newview/lldrawpool.cpp b/linden/indra/newview/lldrawpool.cpp index a3bdfdc..409439a 100644 --- a/linden/indra/newview/lldrawpool.cpp +++ b/linden/indra/newview/lldrawpool.cpp @@ -32,7 +32,7 @@ #include "llviewerprecompiledheaders.h" #include "lldrawpool.h" - +#include "llglimmediate.h" #include "llfasttimer.h" #include "llviewercontrol.h" @@ -44,17 +44,18 @@ #include "lldrawpoolground.h" #include "lldrawpoolsimple.h" #include "lldrawpoolsky.h" -#include "lldrawpoolstars.h" #include "lldrawpooltree.h" #include "lldrawpoolterrain.h" #include "lldrawpoolwater.h" #include "llface.h" #include "llviewerobjectlist.h" // For debug listing. #include "pipeline.h" +#include "llspatialpartition.h" +#include "llviewercamera.h" +#include "lldrawpoolwlsky.h" S32 LLDrawPool::sNumDrawPools = 0; - //============================= // Draw Pool Implementation //============================= @@ -66,15 +67,15 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0) case POOL_SIMPLE: poolp = new LLDrawPoolSimple(); break; + case POOL_INVISIBLE: + poolp = new LLDrawPoolInvisible(); + break; case POOL_GLOW: poolp = new LLDrawPoolGlow(); break; case POOL_ALPHA: poolp = new LLDrawPoolAlpha(); break; - case POOL_ALPHA_POST_WATER: - poolp = new LLDrawPoolAlphaPostWater(); - break; case POOL_AVATAR: poolp = new LLDrawPoolAvatar(); break; @@ -87,9 +88,6 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0) case POOL_SKY: poolp = new LLDrawPoolSky(); break; - case POOL_STARS: - poolp = new LLDrawPoolStars(); - break; case POOL_WATER: poolp = new LLDrawPoolWater(); break; @@ -99,6 +97,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0) case POOL_BUMP: poolp = new LLDrawPoolBump(); break; + case POOL_WL_SKY: + poolp = new LLDrawPoolWLSky(); + break; default: llerrs << "Unknown draw pool type!" << llendl; return NULL; @@ -196,7 +197,6 @@ S32 LLFacePool::drawLoop(face_array_t& face_list) iter != face_list.end(); iter++) { LLFace *facep = *iter; - //facep->enableLights(); res += facep->renderIndexed(); } } @@ -214,7 +214,6 @@ S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage) { LLFace *facep = *iter; facep->bindTexture(stage); - facep->enableLights(); res += facep->renderIndexed(); } } @@ -236,92 +235,6 @@ void LLFacePool::renderFaceSelected(LLFace *facep, { } -void LLFacePool::renderVisibility() -{ - if (mDrawFace.empty()) - { - return; - } - - // SJB: Note: This may be broken now. If you need it, fix it :) - - glLineWidth(1.0); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - glTranslatef(-0.4f,-0.3f,0); - - float table[7][3] = { - { 1,0,0 }, - { 0,1,0 }, - { 1,1,0 }, - { 0,0,1 }, - { 1,0,1 }, - { 0,1,1 }, - { 1,1,1 } - }; - - glColor4f(0,0,0,0.5); - glBegin(GL_POLYGON); - glVertex3f(-0.5f,-0.5f,1.0f); - glVertex3f(+0.5f,-0.5f,1.0f); - glVertex3f(+0.5f,+0.5f,1.0f); - glVertex3f(-0.5f,+0.5f,1.0f); - glVertex3f(-0.5f,-0.5f,1.0f); - glEnd(); - - for (std::vector::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace *face = *iter; - - S32 geom_count = face->getGeomCount(); - for (S32 j=0;jgetVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0) - { - glVertexAttrib4fvARB(mPool->getMaterialAttribIndex(), color.mV); - } - else - { - glColor4fv(color.mV); - } + glColor4fv(color.mV); } void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color) { - if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0) - { - glVertexAttrib4ubvARB(mPool->getMaterialAttribIndex(), color.mV); - } - else - { - glColor4ubv(color.mV); - } + glColor4ubv(color.mV); } void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a) { - if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0) - { - glVertexAttrib4fARB(mPool->getMaterialAttribIndex(), r,g,b,a); - } - else - { - glColor4f(r,g,b,a); - } + glColor4f(r,g,b,a); } @@ -483,51 +375,45 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t } } -void LLRenderPass::renderInvisible(U32 mask) +void LLRenderPass::renderTexture(U32 type, U32 mask) +{ + pushBatches(type, mask, TRUE); +} + +void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture) { #if !LL_RELEASE_FOR_DOWNLOAD LLGLState::checkClientArrays(mask); #endif - - LLSpatialGroup::drawmap_elem_t& draw_info = gPipeline.mRenderMap[LLRenderPass::PASS_INVISIBLE]; - for (LLSpatialGroup::drawmap_elem_t::iterator i = draw_info.begin(); i != draw_info.end(); ++i) + for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) { - - LLDrawInfo *pparams = *i; - if (pparams && pparams->mVertexBuffer.notNull()) { - LLDrawInfo ¶ms = *pparams; - - params.mVertexBuffer->setBuffer(mask); - U32 *indices_pointer = - (U32 *) params.mVertexBuffer->getIndicesPointer(); - glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, - params.mCount, GL_UNSIGNED_INT, - indices_pointer + params.mOffset); - gPipeline.mTrianglesDrawn += params.mCount / 3; + LLDrawInfo* pparams = *i; + if (pparams) + { + pushBatch(*pparams, mask, texture); } } } -void LLRenderPass::renderTexture(U32 type, U32 mask) +void LLRenderPass::applyModelMatrix(LLDrawInfo& params) { -#if !LL_RELEASE_FOR_DOWNLOAD - LLGLState::checkClientArrays(mask); -#endif - - LLSpatialGroup::drawmap_elem_t& draw_info = gPipeline.mRenderMap[type]; - - for (LLSpatialGroup::drawmap_elem_t::iterator i = draw_info.begin(); i != draw_info.end(); ++i) + if (params.mModelMatrix != gGLLastMatrix) { - LLDrawInfo* pparams = *i; - if (pparams) { - pushBatch(*pparams, mask, TRUE); + gGLLastMatrix = params.mModelMatrix; + glLoadMatrixd(gGLModelView); + if (params.mModelMatrix) + { + glMultMatrixf((GLfloat*) params.mModelMatrix->mMatrix); } + gPipeline.mMatrixOpCount++; } } void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) { + applyModelMatrix(params); + if (texture) { if (params.mTexture.notNull()) @@ -537,6 +423,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) { glMatrixMode(GL_TEXTURE); glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; } params.mTexture->addTextureStats(params.mVSize); } @@ -545,14 +432,14 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) LLImageGL::unbindTexture(0); } } - + if (params.mVertexBuffer.notNull()) { params.mVertexBuffer->setBuffer(mask); - U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer(); + U16* indices_pointer = (U16*) params.mVertexBuffer->getIndicesPointer(); glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount, - GL_UNSIGNED_INT, indices_pointer+params.mOffset); - gPipeline.mTrianglesDrawn += params.mCount/3; + GL_UNSIGNED_SHORT, indices_pointer+params.mOffset); + gPipeline.addTrianglesDrawn(params.mCount/3); } if (params.mTextureMatrix && texture && params.mTexture.notNull()) @@ -562,52 +449,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) } } -void LLRenderPass::renderActive(U32 type, U32 mask, BOOL texture) -{ -#if !LL_RELEASE_FOR_DOWNLOAD - LLGLState::checkClientArrays(mask); -#endif - - LLSpatialBridge* last_bridge = NULL; - glPushMatrix(); - - for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mActiveGroups.begin(); i != gPipeline.mActiveGroups.end(); ++i) - { - LLSpatialGroup* group = *i; - if (!group->isDead() && - gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && - group->mDrawMap.find(type) != group->mDrawMap.end()) - { - LLSpatialBridge* bridge = (LLSpatialBridge*) group->mSpatialPartition; - if (bridge != last_bridge) - { - glPopMatrix(); - glPushMatrix(); - glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); - last_bridge = bridge; - } - - renderGroup(group,type,mask,texture); - } - } - - glPopMatrix(); -} - -void LLRenderPass::renderStatic(U32 type, U32 mask, BOOL texture) +void LLRenderPass::renderGroups(U32 type, U32 mask, BOOL texture) { -#if !LL_RELEASE_FOR_DOWNLOAD - LLGLState::checkClientArrays(mask); -#endif - - for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mVisibleGroups.begin(); i != gPipeline.mVisibleGroups.end(); ++i) - { - LLSpatialGroup* group = *i; - if (!group->isDead() && - gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && - group->mDrawMap.find(type) != group->mDrawMap.end()) - { - renderGroup(group,type,mask,texture); - } - } + gPipeline.renderGroups(this, type, mask, texture); } diff --git a/linden/indra/newview/lldrawpool.h b/linden/indra/newview/lldrawpool.h index f283abd..bb354e3 100644 --- a/linden/indra/newview/lldrawpool.h +++ b/linden/indra/newview/lldrawpool.h @@ -43,8 +43,6 @@ class LLViewerImage; class LLSpatialGroup; class LLDrawInfo; -#define DEFAULT_MAX_VERTICES 65535 - class LLDrawPool { public: @@ -53,18 +51,18 @@ public: enum { // Correspond to LLPipeline render type - POOL_SKY = 1, - POOL_STARS, - POOL_GROUND, + POOL_SIMPLE = 1, POOL_TERRAIN, - POOL_SIMPLE, + POOL_TREE, + POOL_SKY, + POOL_WL_SKY, + POOL_GROUND, POOL_BUMP, + POOL_INVISIBLE, POOL_AVATAR, - POOL_TREE, + POOL_WATER, POOL_GLOW, POOL_ALPHA, - POOL_WATER, - POOL_ALPHA_POST_WATER, NUM_POOL_TYPES, }; @@ -82,7 +80,6 @@ public: virtual S32 getNumPasses() { return 1; } virtual void render(S32 pass = 0) = 0; virtual void prerender() = 0; - virtual S32 getMaterialAttribIndex() = 0; virtual U32 getVertexDataMask() = 0; virtual BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct! virtual S32 getVertexShaderLevel() const { return mVertexShaderLevel; } @@ -110,12 +107,14 @@ public: enum { PASS_SIMPLE = NUM_POOL_TYPES, - PASS_GLOW, + PASS_GRASS, PASS_FULLBRIGHT, PASS_INVISIBLE, + PASS_INVISI_SHINY, + PASS_FULLBRIGHT_SHINY, PASS_SHINY, PASS_BUMP, - PASS_GRASS, + PASS_GLOW, PASS_ALPHA, NUM_RENDER_TYPES, }; @@ -123,17 +122,16 @@ public: LLRenderPass(const U32 type); virtual ~LLRenderPass(); /*virtual*/ LLDrawPool* instancePool(); - /*vritual*/ S32 getMaterialAttribIndex() { return -1; } /*virtual*/ LLViewerImage* getDebugTexture() { return NULL; } LLViewerImage* getTexture() { return NULL; } BOOL isDead() { return FALSE; } void resetDrawOrders() { } + static void applyModelMatrix(LLDrawInfo& params); + virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE); virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture); virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); - virtual void renderStatic(U32 type, U32 mask, BOOL texture = TRUE); - virtual void renderActive(U32 type, U32 mask, BOOL texture = TRUE); - virtual void renderInvisible(U32 mask); + virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE); virtual void renderTexture(U32 type, U32 mask); }; @@ -179,8 +177,6 @@ public: static S32 drawLoopSetTex(face_array_t& face_list, S32 stage); void drawLoop(); - void renderVisibility(); - void addFaceReference(LLFace *facep); void removeFaceReference(LLFace *facep); @@ -235,4 +231,5 @@ public: }; }; + #endif //LL_LLDRAWPOOL_H diff --git a/linden/indra/newview/lldrawpoolalpha.cpp b/linden/indra/newview/lldrawpoolalpha.cpp index 24cf8e7..1ad7132 100644 --- a/linden/indra/newview/lldrawpoolalpha.cpp +++ b/linden/indra/newview/lldrawpoolalpha.cpp @@ -48,20 +48,20 @@ #include "llviewerobjectlist.h" // For debugging #include "llviewerwindow.h" #include "pipeline.h" -#include "llviewerregion.h" #include "llglslshader.h" +#include "llviewerregion.h" +#include "lldrawpoolwater.h" +#include "llspatialpartition.h" BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE; -LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) : - LLRenderPass(type) -{ -} -LLDrawPoolAlphaPostWater::LLDrawPoolAlphaPostWater() -: LLDrawPoolAlpha(POOL_ALPHA_POST_WATER) +LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) : + LLRenderPass(type), current_shader(NULL), target_shader(NULL), + simple_shader(NULL), fullbright_shader(NULL) { + } LLDrawPoolAlpha::~LLDrawPoolAlpha() @@ -76,61 +76,58 @@ void LLDrawPoolAlpha::prerender() void LLDrawPoolAlpha::beginRenderPass(S32 pass) { + LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); -} - -void setup_clip_plane(BOOL pre_water) -{ - F32 height = gAgent.getRegion()->getWaterHeight(); - BOOL above = gCamera->getOrigin().mV[2] > height ? TRUE : FALSE; - F64 plane[4]; - - plane[0] = 0; - plane[1] = 0; - plane[2] = above == pre_water ? -1.0 : 1.0; - plane[3] = -plane[2] * height; - - glClipPlane(GL_CLIP_PLANE0, plane); -} - -void LLDrawPoolAlphaPostWater::render(S32 pass) -{ - LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA); - - if (gPipeline.hasRenderType(LLDrawPool::POOL_ALPHA)) + if (LLPipeline::sUnderWaterRender) { - LLGLEnable clip(GL_CLIP_PLANE0); - setup_clip_plane(FALSE); - LLDrawPoolAlpha::render(gPipeline.mAlphaGroupsPostWater); + simple_shader = &gObjectSimpleWaterProgram; + fullbright_shader = &gObjectFullbrightWaterProgram; } else { - LLDrawPoolAlpha::render(gPipeline.mAlphaGroupsPostWater); + simple_shader = &gObjectSimpleProgram; + fullbright_shader = &gObjectFullbrightProgram; } + + if (mVertexShaderLevel > 0) + { + // Start out with no shaders. + current_shader = target_shader = NULL; + glUseProgramObjectARB(0); + } + gPipeline.enableLightsDynamic(); } -void LLDrawPoolAlpha::render(S32 pass) +void LLDrawPoolAlpha::endRenderPass( S32 pass ) { LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA); - - LLGLEnable clip(GL_CLIP_PLANE0); - setup_clip_plane(TRUE); - render(gPipeline.mAlphaGroups); + LLRenderPass::endRenderPass(pass); + + if(gPipeline.canUseWindLightShaders()) + { + glUseProgramObjectARB(0); + } } -void LLDrawPoolAlpha::render(std::vector& groups) +void LLDrawPoolAlpha::render(S32 pass) { - LLGLDepthTest gls_depth(GL_TRUE); - LLGLSPipelineAlpha gls_pipeline_alpha; + LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA); - gPipeline.enableLightsDynamic(1.f); - renderAlpha(getVertexDataMask(), groups); + LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE); + + LLGLSPipelineAlpha gls_pipeline_alpha; + + renderAlpha(getVertexDataMask()); if (sShowDebugAlpha) { + if(gPipeline.canUseWindLightShaders()) + { + glUseProgramObjectARB(0); + } glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); @@ -138,90 +135,39 @@ void LLDrawPoolAlpha::render(std::vector& groups) LLViewerImage::sSmokeImagep->addTextureStats(1024.f*1024.f); LLViewerImage::sSmokeImagep->bind(); renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_TEXCOORD, groups); + LLVertexBuffer::MAP_TEXCOORD); } } -void LLDrawPoolAlpha::renderAlpha(U32 mask, std::vector& groups) +void LLDrawPoolAlpha::renderAlpha(U32 mask) { #if !LL_RELEASE_FOR_DOWNLOAD LLGLState::checkClientArrays(mask); #endif - - LLSpatialBridge* last_bridge = NULL; - LLSpatialPartition* last_part = NULL; - glPushMatrix(); - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - - for (std::vector::iterator i = groups.begin(); i != groups.end(); ++i) + + for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; if (group->mSpatialPartition->mRenderByGroup && !group->isDead()) { - LLSpatialPartition* part = group->mSpatialPartition; - if (part != last_part) - { - LLSpatialBridge* bridge = part->asBridge(); - if (bridge != last_bridge) - { - glPopMatrix(); - glPushMatrix(); - if (bridge) - { - glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); - } - last_bridge = bridge; - } - -// if (!last_part || part->mDepthMask != last_part->mDepthMask) -// { -// glDepthMask(part->mDepthMask); -// } - last_part = part; - } - renderGroupAlpha(group,LLRenderPass::PASS_ALPHA,mask,TRUE); } } - - glPopMatrix(); } -void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask, std::vector& groups) +void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) { #if !LL_RELEASE_FOR_DOWNLOAD LLGLState::checkClientArrays(mask); #endif - LLSpatialBridge* last_bridge = NULL; - LLSpatialPartition* last_part = NULL; - glPushMatrix(); - - for (std::vector::iterator i = groups.begin(); i != groups.end(); ++i) + for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; if (group->mSpatialPartition->mRenderByGroup && !group->isDead()) { - LLSpatialPartition* part = group->mSpatialPartition; - if (part != last_part) - { - LLSpatialBridge* bridge = part->asBridge(); - if (bridge != last_bridge) - { - glPopMatrix(); - glPushMatrix(); - if (bridge) - { - glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); - } - last_bridge = bridge; - } - - last_part = part; - } - LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) @@ -232,104 +178,135 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask, std::vectorsetBuffer(mask); - U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer(); + U16* indices_pointer = (U16*) params.mVertexBuffer->getIndicesPointer(); glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount, - GL_UNSIGNED_INT, indices_pointer+params.mOffset); - - addIndicesDrawn(params.mCount); + GL_UNSIGNED_SHORT, indices_pointer+params.mOffset); + gPipeline.addTrianglesDrawn(params.mCount/3); } } } - glPopMatrix(); } void LLDrawPoolAlpha::renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture) -{ +{ + BOOL initialized_lighting = FALSE; BOOL light_enabled = TRUE; - - LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; + BOOL is_particle = FALSE; + BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders()) + || gPipeline.canUseWindLightShadersOnObjects(); + F32 dist; + + // check to see if it's a particle and if it's "close" + is_particle = !LLPipeline::sUnderWaterRender && (group->mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_PARTICLES); + dist = group->mDistance; - U32 prim_type = GL_TRIANGLES; + // don't use shader if debug setting is off and it's close or if it's a particle + // and it's close + if(is_particle && !gSavedSettings.getBOOL("RenderUseShaderNearParticles")) + { + if((dist < gCamera->getFar() * gSavedSettings.getF32("RenderShaderParticleThreshold"))) + { + use_shaders = FALSE; + } + } - //F32 width = (F32) gViewerWindow->getWindowDisplayWidth(); + LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; - //F32 view = gCamera->getView(); - if (group->mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_CLOUDS) - { + { + if (!gSavedSettings.getBOOL("SkyUseClassicClouds")) + { + return; + } + // *TODO - Uhhh, we should always be doing some type of alpha rejection. These should probably both be 0.01f glAlphaFunc(GL_GREATER, 0.f); } else { - glAlphaFunc(GL_GREATER, 0.01f); + if (LLPipeline::sImpostorRender) + { + glAlphaFunc(GL_GREATER, 0.5f); + } + else + { + glAlphaFunc(GL_GREATER, 0.01f); + } } - /*LLGLEnable point_sprite(GL_POINT_SPRITE_ARB); - - if (gGLManager.mHasPointParameters) - { - glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, TRUE); - glPointParameterfARB(GL_POINT_SIZE_MIN_ARB, 0.f); - glPointParameterfARB(GL_POINT_SIZE_MAX_ARB, width*16.f); - glPointSize(width/(view*view)); - }*/ - for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo& params = **k; + + LLRenderPass::applyModelMatrix(params); + if (texture && params.mTexture.notNull()) { + glActiveTextureARB(GL_TEXTURE0_ARB); params.mTexture->bind(); params.mTexture->addTextureStats(params.mVSize); if (params.mTextureMatrix) { glMatrixMode(GL_TEXTURE); glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; } } - + if (params.mFullbright) { - if (light_enabled) + // Turn off lighting if it hasn't already been so. + if (light_enabled || !initialized_lighting) { - gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); - light_enabled = FALSE; - if (LLPipeline::sRenderGlow) + initialized_lighting = TRUE; + if (use_shaders) { - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + target_shader = fullbright_shader; } + else + { + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + } + light_enabled = FALSE; } } - else if (!light_enabled) + // Turn on lighting if it isn't already. + else if (!light_enabled || !initialized_lighting) { - gPipeline.enableLightsDynamic(1.f); - light_enabled = TRUE; - if (LLPipeline::sRenderGlow) + initialized_lighting = TRUE; + if (use_shaders) + { + target_shader = simple_shader; + } + else { - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + gPipeline.enableLightsDynamic(); } + light_enabled = TRUE; } - /*if (params.mParticle) + // 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)) { - F32 size = params.mPartSize; - size *= size; - float param[] = { 0, 0, 0.01f/size*view*view }; - prim_type = GL_POINTS; - glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, param); + llassert(target_shader != NULL); + current_shader = target_shader; + current_shader->bind(); } - else*/ + else if (!use_shaders && current_shader != NULL) { - prim_type = GL_TRIANGLES; + glUseProgramObjectARB(0); + current_shader = NULL; } params.mVertexBuffer->setBuffer(mask); - U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer(); - glDrawRangeElements(prim_type, params.mStart, params.mEnd, params.mCount, - GL_UNSIGNED_INT, indices_pointer+params.mOffset); - - addIndicesDrawn(params.mCount); + U16* indices_pointer = (U16*) params.mVertexBuffer->getIndicesPointer(); + glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount, + GL_UNSIGNED_SHORT, indices_pointer+params.mOffset); + gPipeline.addTrianglesDrawn(params.mCount/3); if (params.mTextureMatrix && texture && params.mTexture.notNull()) { @@ -340,19 +317,6 @@ void LLDrawPoolAlpha::renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask if (!light_enabled) { - gPipeline.enableLightsDynamic(1.f); - - if (LLPipeline::sRenderGlow) - { - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - } + gPipeline.enableLightsDynamic(); } - - /*glPointSize(1.f); - - if (gGLManager.mHasPointParameters) - { - float param[] = {1, 0, 0 }; - glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, param); - }*/ -} +} diff --git a/linden/indra/newview/lldrawpoolalpha.h b/linden/indra/newview/lldrawpoolalpha.h index c7709f7..4318045 100644 --- a/linden/indra/newview/lldrawpoolalpha.h +++ b/linden/indra/newview/lldrawpoolalpha.h @@ -37,6 +37,7 @@ class LLFace; class LLColor4; +class LLGLSLShader; class LLDrawPoolAlpha: public LLRenderPass { @@ -54,15 +55,26 @@ public: /*virtual*/ ~LLDrawPoolAlpha(); /*virtual*/ void beginRenderPass(S32 pass = 0); + /*virtual*/ void endRenderPass( S32 pass ); + /*virtual*/ S32 getNumPasses() { return 1; } + virtual void render(S32 pass = 0); - void render(std::vector& groups); /*virtual*/ void prerender(); void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); - void renderAlpha(U32 mask, std::vector& groups); - void renderAlphaHighlight(U32 mask, std::vector& groups); + void renderAlpha(U32 mask); + void renderAlphaHighlight(U32 mask); static BOOL sShowDebugAlpha; + +private: + S32 mDiffuse; + LLGLSLShader* current_shader; + LLGLSLShader* target_shader; + LLGLSLShader* simple_shader; + LLGLSLShader* simple_lod_shader; + LLGLSLShader* fullbright_shader; + LLGLSLShader* fullbright_lod_shader; }; class LLDrawPoolAlphaPostWater : public LLDrawPoolAlpha diff --git a/linden/indra/newview/lldrawpoolavatar.cpp b/linden/indra/newview/lldrawpoolavatar.cpp index 6e22632..5518a93 100644 --- a/linden/indra/newview/lldrawpoolavatar.cpp +++ b/linden/indra/newview/lldrawpoolavatar.cpp @@ -32,6 +32,7 @@ #include "llviewerprecompiledheaders.h" #include "lldrawpoolavatar.h" +#include "llglimmediate.h" #include "llvoavatar.h" #include "m3math.h" @@ -142,20 +143,33 @@ LLMatrix4& LLDrawPoolAvatar::getModelView() S32 LLDrawPoolAvatar::getNumPasses() { - return 3; + return LLPipeline::sImpostorRender ? 1 : 3; } void LLDrawPoolAvatar::render(S32 pass) { LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); + if (LLPipeline::sImpostorRender) + { + renderAvatars(NULL, 2); + return; + } + renderAvatars(NULL, pass); // render all avatars } void LLDrawPoolAvatar::beginRenderPass(S32 pass) { + LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); //reset vertex buffer mappings LLVertexBuffer::unbind(); + if (LLPipeline::sImpostorRender) + { + beginSkinned(); + return; + } + switch (pass) { case 0: @@ -172,6 +186,14 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass) void LLDrawPoolAvatar::endRenderPass(S32 pass) { + LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); + + if (LLPipeline::sImpostorRender) + { + endSkinned(); + return; + } + switch (pass) { case 0: @@ -187,31 +209,47 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass) void LLDrawPoolAvatar::beginFootShadow() { - glDepthMask(GL_FALSE); + if (!LLPipeline::sReflectionRender) + { + LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f); + LLVOAvatar::sNumVisibleAvatars = 0; + } + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); glEnableClientState(GL_TEXTURE_COORD_ARRAY); } void LLDrawPoolAvatar::endFootShadow() { - gPipeline.enableLightsDynamic(1.f); - glDepthMask(GL_TRUE); + gPipeline.enableLightsDynamic(); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } void LLDrawPoolAvatar::beginRigid() { - sVertexProgram = NULL; - sShaderLevel = 0; + if (gPipeline.canUseVertexShaders()) + { + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &gObjectSimpleWaterProgram; + } + else + { + sVertexProgram = &gObjectSimpleProgram; + } + + if (sVertexProgram != NULL) + { //eyeballs render with the specular shader + sVertexProgram->bind(); + } + } + else + { + sVertexProgram = NULL; + } + glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - /*if (sShaderLevel > 0) - { //eyeballs render with the specular shader - gAvatarEyeballProgram.bind(); - gMaterialIndex = gAvatarEyeballProgram.mAttribute[LLShaderMgr::MATERIAL_COLOR]; - gSpecularIndex = gAvatarEyeballProgram.mAttribute[LLShaderMgr::SPECULAR_COLOR]; - }*/ } void LLDrawPoolAvatar::endRigid() @@ -219,6 +257,10 @@ void LLDrawPoolAvatar::endRigid() sShaderLevel = mVertexShaderLevel; glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); + if (sVertexProgram != NULL) + { + sVertexProgram->unbind(); + } } void LLDrawPoolAvatar::beginSkinned() @@ -226,17 +268,35 @@ void LLDrawPoolAvatar::beginSkinned() glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - sVertexProgram = &gAvatarProgram; - + if (sShaderLevel > 0) + { + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &gAvatarWaterProgram; + sShaderLevel = llmin((U32) 1, sShaderLevel); + } + else + { + sVertexProgram = &gAvatarProgram; + } + } + else + { + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &gObjectSimpleWaterProgram; + } + else + { + sVertexProgram = &gObjectSimpleProgram; + } + } + if (sShaderLevel > 0) // for hardware blending { sRenderingSkinned = TRUE; glClientActiveTextureARB(GL_TEXTURE1_ARB); - if (sShaderLevel >= SHADER_LEVEL_BUMP) - { - gMaterialIndex = sVertexProgram->mAttribute[LLShaderMgr::MATERIAL_COLOR]; - gSpecularIndex = sVertexProgram->mAttribute[LLShaderMgr::SPECULAR_COLOR]; - } + sVertexProgram->bind(); if (sShaderLevel >= SHADER_LEVEL_CLOTH) { @@ -252,6 +312,15 @@ void LLDrawPoolAvatar::beginSkinned() sVertexProgram->enableTexture(LLShaderMgr::BUMP_MAP); glActiveTextureARB(GL_TEXTURE0_ARB); } + else + { + if(gPipeline.canUseVertexShaders()) + { + // software skinning, use a basic shader for windlight. + // TODO: find a better fallback method for software skinning. + sVertexProgram->bind(); + } + } } void LLDrawPoolAvatar::endSkinned() @@ -274,6 +343,16 @@ void LLDrawPoolAvatar::endSkinned() } sVertexProgram->unbind(); + sShaderLevel = mVertexShaderLevel; + } + else + { + if(gPipeline.canUseVertexShaders()) + { + // software skinning, use a basic shader for windlight. + // TODO: find a better fallback method for software skinning. + sVertexProgram->unbind(); + } } glActiveTextureARB(GL_TEXTURE0_ARB); @@ -299,6 +378,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) return; } + + if (!gRenderAvatar) { return; @@ -330,60 +411,50 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) return; } - LLOverrideFaceColor color(this, 1.0f, 1.0f, 1.0f, 1.0f); + BOOL impostor = avatarp->isImpostor() && !single_avatar; + + if (impostor && pass != 0) + { //don't draw anything but the impostor for impostored avatars + return; + } + if (pass == 0 && !impostor && LLPipeline::sUnderWaterRender) + { //don't draw foot shadows under water + return; + } + + LLOverrideFaceColor color(this, 1.0f, 1.0f, 1.0f, 1.0f); + if (pass == 0) { - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS)) + if (!LLPipeline::sReflectionRender) + { + LLVOAvatar::sNumVisibleAvatars++; + } + + if (impostor) + { + avatarp->renderImpostor(); + } + else if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS)) { mIndicesDrawn += avatarp->renderFootShadows(); } return; } - if (avatarp->mSpecialRenderMode == 0) // normal - { - gPipeline.enableLightsAvatar(avatarp->mDrawable->getSunShadowFactor()); - } - else if (avatarp->mSpecialRenderMode == 1) // anim preview - { - gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f)); - } - else // 2=image preview, 3=morph view + if (single_avatar && avatarp->mSpecialRenderMode >= 2) // 2=image preview, 3=morph view { gPipeline.enableLightsAvatarEdit(LLColor4(.5f, .5f, .5f, 1.f)); } - + if (pass == 1) { // render rigid meshes (eyeballs) first mIndicesDrawn += avatarp->renderRigid(); - - if (!gRenderForSelect && avatarp->mIsSelf && LLVOAvatar::sAvatarLoadTest) - { - LLVector3 orig_pos_root = avatarp->mRoot.getPosition(); - LLVector3 next_pos_root = orig_pos_root; - for (S32 i = 0; i < NUM_TEST_AVATARS; i++) - { - next_pos_root.mV[VX] += 1.f; - if (i % 5 == 0) - { - next_pos_root.mV[VY] += 1.f; - next_pos_root.mV[VX] = orig_pos_root.mV[VX]; - } - - avatarp->mRoot.setPosition(next_pos_root); // avatar load test - avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test - - mIndicesDrawn += avatarp->renderRigid(); - } - avatarp->mRoot.setPosition(orig_pos_root); // avatar load test - avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test - } return; } - if (sShaderLevel > 0) { gAvatarMatrixParam = sVertexProgram->mUniform[LLShaderMgr::AVATAR_MATRIX]; @@ -427,79 +498,57 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) LLGLSNoTexture gls_no_texture; LLVector3 pos = avatarp->getPositionAgent(); - color.setColor(1.0f, 0.0f, 0.0f, 0.8f); - glBegin(GL_LINES); + gGL.color4f(1.0f, 0.0f, 0.0f, 0.8f); + gGL.begin(GL_LINES); { - glVertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); - glVertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); - glVertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); - glVertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); - glVertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); - glVertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); - }glEnd(); + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + }gGL.end(); pos = avatarp->mDrawable->getPositionAgent(); - color.setColor(1.0f, 0.0f, 0.0f, 0.8f); - glBegin(GL_LINES); + gGL.color4f(1.0f, 0.0f, 0.0f, 0.8f); + gGL.begin(GL_LINES); { - glVertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); - glVertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); - glVertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); - glVertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); - glVertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); - glVertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); - }glEnd(); + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + }gGL.end(); pos = avatarp->mRoot.getWorldPosition(); - color.setColor(1.0f, 1.0f, 1.0f, 0.8f); - glBegin(GL_LINES); + gGL.color4f(1.0f, 1.0f, 1.0f, 0.8f); + gGL.begin(GL_LINES); { - glVertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); - glVertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); - glVertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); - glVertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); - glVertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); - glVertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); - }glEnd(); + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + }gGL.end(); pos = avatarp->mPelvisp->getWorldPosition(); - color.setColor(0.0f, 0.0f, 1.0f, 0.8f); - glBegin(GL_LINES); + gGL.color4f(0.0f, 0.0f, 1.0f, 0.8f); + gGL.begin(GL_LINES); { - glVertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); - glVertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); - glVertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); - glVertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); - glVertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); - glVertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); - }glEnd(); + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + }gGL.end(); color.setColor(1.0f, 1.0f, 1.0f, 1.0f); } mIndicesDrawn += avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); - - if (!gRenderForSelect && avatarp->mIsSelf && LLVOAvatar::sAvatarLoadTest) - { - LLVector3 orig_pos_root = avatarp->mRoot.getPosition(); - LLVector3 next_pos_root = orig_pos_root; - for (S32 i = 0; i < NUM_TEST_AVATARS; i++) - { - next_pos_root.mV[VX] += 1.f; - if (i % 5 == 0) - { - next_pos_root.mV[VY] += 1.f; - next_pos_root.mV[VX] = orig_pos_root.mV[VX]; - } - - avatarp->mRoot.setPosition(next_pos_root); // avatar load test - avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test - - mIndicesDrawn += avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); - } - avatarp->mRoot.setPosition(orig_pos_root); // avatar load test - avatarp->mRoot.updateWorldMatrixChildren(); // avatar load test - } } } @@ -535,6 +584,31 @@ void LLDrawPoolAvatar::renderForSelect() return; } + S32 name = avatarp->mDrawable->getVObj()->mGLName; + LLColor4U color((U8)(name >> 16), (U8)(name >> 8), (U8)name); + + BOOL impostor = avatarp->isImpostor(); + if (impostor) + { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA); + + avatarp->renderImpostor(color); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + return; + } + glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -544,15 +618,10 @@ void LLDrawPoolAvatar::renderForSelect() gAvatarMatrixParam = sVertexProgram->mUniform[LLShaderMgr::AVATAR_MATRIX]; } glAlphaFunc(GL_GEQUAL, 0.2f); - glBlendFunc(GL_ONE, GL_ZERO); + gGL.blendFunc(GL_ONE, GL_ZERO); - S32 name = avatarp->mDrawable->getVObj()->mGLName; - LLColor4U color((U8)(name >> 16), (U8)(name >> 8), (U8)name); glColor4ubv(color.mV); - // render rigid meshes (eyeballs) first - //mIndicesDrawn += avatarp->renderRigid(); - if ((sShaderLevel > 0) && !gUseGLPick) // for hardware blending { glClientActiveTextureARB(GL_TEXTURE0_ARB); @@ -572,7 +641,7 @@ void LLDrawPoolAvatar::renderForSelect() } glAlphaFunc(GL_GREATER, 0.01f); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // restore texture mode glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); diff --git a/linden/indra/newview/lldrawpoolavatar.h b/linden/indra/newview/lldrawpoolavatar.h index a521e57..077764a 100644 --- a/linden/indra/newview/lldrawpoolavatar.h +++ b/linden/indra/newview/lldrawpoolavatar.h @@ -53,9 +53,7 @@ public: LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD | LLVertexBuffer::MAP_WEIGHT | - LLVertexBuffer::MAP_CLOTHWEIGHT | - LLVertexBuffer::MAP_BINORMAL - + LLVertexBuffer::MAP_CLOTHWEIGHT }; virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } @@ -86,8 +84,6 @@ public: /*virtual*/ LLViewerImage *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display - virtual S32 getMaterialAttribIndex() { return 0; } - void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null. }; diff --git a/linden/indra/newview/lldrawpoolbump.cpp b/linden/indra/newview/lldrawpoolbump.cpp index 51a7749..987e65e 100644 --- a/linden/indra/newview/lldrawpoolbump.cpp +++ b/linden/indra/newview/lldrawpoolbump.cpp @@ -40,17 +40,19 @@ #include "m3math.h" #include "m4math.h" #include "v4math.h" +#include "llglheaders.h" +#include "llglimmediate.h" #include "llagent.h" #include "llcubemap.h" #include "lldrawable.h" -#include "lldrawpoolsimple.h" #include "llface.h" #include "llsky.h" #include "lltextureentry.h" #include "llviewercamera.h" #include "llviewerimagelist.h" #include "pipeline.h" +#include "llspatialpartition.h" #include "llglslshader.h" //#include "llimagebmp.h" @@ -73,6 +75,10 @@ const U32 VERTEX_MASK_BUMP = LLVertexBuffer::MAP_VERTEX |LLVertexBuffer::MAP_TEX U32 LLDrawPoolBump::sVertexMask = VERTEX_MASK_SHINY; static LLCubeMap* sCubeMap = NULL; +static LLGLSLShader* shader = NULL; +static S32 cube_channel = -1; +static S32 diffuse_channel = -1; + // static void LLStandardBumpmap::init() { @@ -158,8 +164,9 @@ void LLStandardBumpmap::destroyGL() //////////////////////////////////////////////////////////////// LLDrawPoolBump::LLDrawPoolBump() -: LLRenderPass(LLDrawPool::POOL_BUMP) +: LLRenderPass(LLDrawPool::POOL_BUMP) { + mShiny = FALSE; } @@ -173,7 +180,25 @@ S32 LLDrawPoolBump::numBumpPasses() { if (gSavedSettings.getBOOL("RenderObjectBump")) { - return 2; + if (mVertexShaderLevel > 1) + { + if (LLPipeline::sImpostorRender) + { + return 2; + } + else + { + return 3; + } + } + else if (LLPipeline::sImpostorRender) + { + return 1; + } + else + { + return 2; + } } else { @@ -188,12 +213,23 @@ S32 LLDrawPoolBump::getNumPasses() void LLDrawPoolBump::beginRenderPass(S32 pass) { + LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP); switch( pass ) { case 0: beginShiny(); break; case 1: + if (mVertexShaderLevel > 1) + { + beginFullbrightShiny(); + } + else + { + beginBump(); + } + break; + case 2: beginBump(); break; default: @@ -213,32 +249,47 @@ void LLDrawPoolBump::render(S32 pass) switch( pass ) { - case 0: - { - renderShiny(); - break; - } - case 1: - { - renderBump(); - break; - } - default: - { - llassert(0); - break; - } + case 0: + renderShiny(); + break; + case 1: + if (mVertexShaderLevel > 1) + { + renderFullbrightShiny(); + } + else + { + renderBump(); + } + break; + case 2: + renderBump(); + break; + default: + llassert(0); + break; } } void LLDrawPoolBump::endRenderPass(S32 pass) { + LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP); switch( pass ) { case 0: endShiny(); break; case 1: + if (mVertexShaderLevel > 1) + { + endFullbrightShiny(); + } + else + { + endBump(); + } + break; + case 2: endBump(); break; default: @@ -248,36 +299,77 @@ void LLDrawPoolBump::endRenderPass(S32 pass) } //static -void LLDrawPoolBump::beginShiny() +void LLDrawPoolBump::beginShiny(bool invisible) { + LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); + if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| + invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) + { + return; + } + + mShiny = TRUE; sVertexMask = VERTEX_MASK_SHINY; // Second pass: environment map glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); + if (!invisible && mVertexShaderLevel > 1) + { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD; + } + + if (LLPipeline::sUnderWaterRender) + { + shader = &gObjectShinyWaterProgram; + } + else + { + shader = &gObjectShinyProgram; + } - LLCubeMap* cube_map = gSky.mVOSkyp->getCubeMap(); + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { - cube_map->enable(0); - cube_map->setMatrix(0); - cube_map->bind(); - - if (LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_OBJECT) > 0) + if (!invisible && LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_OBJECT) > 0 ) { LLMatrix4 mat; mat.initRows(LLVector4(gGLModelView+0), LLVector4(gGLModelView+4), LLVector4(gGLModelView+8), LLVector4(gGLModelView+12)); - gObjectShinyProgram.bind(); + shader->bind(); LLVector3 vec = LLVector3(gShinyOrigin) * mat; LLVector4 vec4(vec, gShinyOrigin.mV[3]); - glUniform4fvARB(gObjectShinyProgram.mUniform[LLShaderMgr::SHINY_ORIGIN], 1, - vec4.mV); + shader->uniform4fv(LLShaderMgr::SHINY_ORIGIN, 1, vec4.mV); + if (mVertexShaderLevel > 1) + { + cube_map->setMatrix(1); + // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for + // the cube map in the one pass shiny shaders + cube_channel = shader->enableTexture(LLShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); + cube_map->enableTexture(cube_channel); + cube_map->enableTextureCoords(1); + diffuse_channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP); + } + else + { + cube_channel = 0; + diffuse_channel = -1; + cube_map->setMatrix(0); + cube_map->enable(shader->enableTexture(LLShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB)); + } + cube_map->bind(); } else { + cube_channel = 0; + diffuse_channel = -1; + cube_map->enable(0); + cube_map->setMatrix(0); + cube_map->bind(); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); //use RGB from texture @@ -293,63 +385,188 @@ void LLDrawPoolBump::beginShiny() } } -void LLDrawPoolBump::renderShiny() +void LLDrawPoolBump::renderShiny(bool invisible) { LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); - + if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| + invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) + { + return; + } + sCubeMap = NULL; if( gSky.mVOSkyp->getCubeMap() ) { LLGLEnable blend_enable(GL_BLEND); - renderStatic(LLRenderPass::PASS_SHINY, sVertexMask); - renderActive(LLRenderPass::PASS_SHINY, sVertexMask); + if (!invisible && mVertexShaderLevel > 1) + { + LLRenderPass::renderTexture(LLRenderPass::PASS_SHINY, sVertexMask); + } + else if (!invisible) + { + renderGroups(LLRenderPass::PASS_SHINY, sVertexMask); + } + else // invisible + { + renderGroups(LLRenderPass::PASS_INVISI_SHINY, sVertexMask); + } } } -void LLDrawPoolBump::renderActive(U32 type, U32 mask, BOOL texture) +void LLDrawPoolBump::endShiny(bool invisible) { -#if !LL_RELEASE_FOR_DOWNLOAD - LLGLState::checkClientArrays(mask); -#endif + LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); + if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| + invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) + { + return; + } - LLSpatialBridge* last_bridge = NULL; - glPushMatrix(); - - for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mActiveGroups.begin(); i != gPipeline.mActiveGroups.end(); ++i) + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if( cube_map ) { - LLSpatialGroup* group = *i; - if (!group->isDead() && - gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && - group->mDrawMap.find(type) != group->mDrawMap.end()) + cube_map->disable(); + cube_map->restoreMatrix(); + + if (!invisible && mVertexShaderLevel > 1) { - LLSpatialBridge* bridge = (LLSpatialBridge*) group->mSpatialPartition; - if (bridge != last_bridge) + shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); + + if (LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_OBJECT) > 0) { - glPopMatrix(); - glPushMatrix(); - glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); - last_bridge = bridge; - - if (LLPipeline::sDynamicReflections) + if (diffuse_channel != 0) { - LLSpatialPartition* part = gPipeline.getSpatialPartition(LLPipeline::PARTITION_VOLUME); - LLSpatialGroup::OctreeNode* node = part->mOctree->getNodeAt(LLVector3d(bridge->mDrawable->getPositionAgent()), 32.0); - if (node) - { - sCubeMap = ((LLSpatialGroup*) node->getListener(0))->mReflectionMap; - } + shader->disableTexture(LLShaderMgr::DIFFUSE_MAP); } } - renderGroup(group,type,mask,texture); + shader->unbind(); + glActiveTextureARB(GL_TEXTURE0_ARB); + glEnable(GL_TEXTURE_2D); } + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } - glPopMatrix(); + LLImageGL::unbindTexture(0, GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + if (!invisible && mVertexShaderLevel > 1) + { + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + + diffuse_channel = -1; + cube_channel = 0; + mShiny = FALSE; } +void LLDrawPoolBump::beginFullbrightShiny() +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); + if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY)) + { + return; + } + + sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD; + + // Second pass: environment map + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + if (LLPipeline::sUnderWaterRender) + { + shader = &gObjectShinyWaterProgram; + } + else + { + shader = &gObjectFullbrightShinyProgram; + } + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if( cube_map ) + { + LLMatrix4 mat; + mat.initRows(LLVector4(gGLModelView+0), + LLVector4(gGLModelView+4), + LLVector4(gGLModelView+8), + LLVector4(gGLModelView+12)); + shader->bind(); + LLVector3 vec = LLVector3(gShinyOrigin) * mat; + LLVector4 vec4(vec, gShinyOrigin.mV[3]); + shader->uniform4fv(LLShaderMgr::SHINY_ORIGIN, 1, vec4.mV); + + cube_map->setMatrix(1); + // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for + // the cube map in the one pass shiny shaders + cube_channel = shader->enableTexture(LLShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); + cube_map->enableTexture(cube_channel); + cube_map->enableTextureCoords(1); + diffuse_channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP); + + cube_map->bind(); + } + mShiny = TRUE; +} + +void LLDrawPoolBump::renderFullbrightShiny() +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); + if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY)) + { + return; + } + + sCubeMap = NULL; + + if( gSky.mVOSkyp->getCubeMap() ) + { + LLGLEnable blend_enable(GL_BLEND); + LLRenderPass::renderTexture(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask); + } +} + +void LLDrawPoolBump::endFullbrightShiny() +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); + if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY)) + { + return; + } + + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if( cube_map ) + { + cube_map->disable(); + cube_map->restoreMatrix(); + + if (diffuse_channel != 0) + { + shader->disableTexture(LLShaderMgr::DIFFUSE_MAP); + } + glActiveTextureARB(GL_TEXTURE0_ARB); + glEnable(GL_TEXTURE_2D); + + shader->unbind(); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + + LLImageGL::unbindTexture(0, GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + diffuse_channel = -1; + cube_channel = 0; + mShiny = FALSE; +} void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE) { @@ -366,6 +583,11 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL } else { + if (params.mModelMatrix) + { + sCubeMap = gPipeline.findReflectionMap(params.mModelMatrix->getTranslation()); + } + if (sCubeMap) { sCubeMap->bind(); @@ -377,34 +599,14 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL } } + applyModelMatrix(params); + params.mVertexBuffer->setBuffer(mask); - U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer(); + U16* indices_pointer = (U16*) params.mVertexBuffer->getIndicesPointer(); glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount, - GL_UNSIGNED_INT, indices_pointer+params.mOffset); - gPipeline.mTrianglesDrawn += params.mCount/3; - } -} - -void LLDrawPoolBump::endShiny() -{ - LLCubeMap* cube_map = gSky.mVOSkyp->getCubeMap(); - if( cube_map ) - { - cube_map->disable(); - cube_map->restoreMatrix(); - - if (LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_OBJECT) > 0) - { - gObjectShinyProgram.unbind(); - } - - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GL_UNSIGNED_SHORT, indices_pointer+params.mOffset); + gPipeline.addTrianglesDrawn(params.mCount/3); } - - LLImageGL::unbindTexture(0, GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); } @@ -450,6 +652,11 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params) //static void LLDrawPoolBump::beginBump() { + if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) + { + return; + } + sVertexMask = VERTEX_MASK_BUMP; LLFastTimer t(LLFastTimer::FTM_RENDER_BUMP); // Optional second pass: emboss bump map @@ -503,28 +710,41 @@ void LLDrawPoolBump::beginBump() // = 2 * ((1 + bump0 - bump1) / 2) * dst [0 - 2 * dst] // = (1 + bump0 - bump1) * dst.rgb // = dst.rgb + dst.rgb * (bump0 - bump1) - glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); -// glBlendFunc(GL_ONE, GL_ZERO); // temp + gGL.blendFunc(GL_DST_COLOR, GL_SRC_COLOR); +// gGL.blendFunc(GL_ONE, GL_ZERO); // temp glActiveTextureARB(GL_TEXTURE0_ARB); stop_glerror(); + + LLViewerImage::unbindTexture(1, GL_TEXTURE_2D); } //static void LLDrawPoolBump::renderBump() { + if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) + { + return; + } + LLFastTimer ftm(LLFastTimer::FTM_RENDER_BUMP); LLGLDisable fog(GL_FOG); - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_EQUAL); - LLGLEnable tex2d(GL_TEXTURE_2D); + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL); LLGLEnable blend(GL_BLEND); glColor4f(1,1,1,1); + /// Get rid of z-fighting with non-bump pass. + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -1.0f); renderBump(LLRenderPass::PASS_BUMP, sVertexMask); - renderBumpActive(LLRenderPass::PASS_BUMP, sVertexMask); } //static void LLDrawPoolBump::endBump() { + if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) + { + return; + } + // Disable texture unit 1 glActiveTextureARB(GL_TEXTURE1_ARB); glClientActiveTextureARB(GL_TEXTURE1_ARB); @@ -538,7 +758,7 @@ void LLDrawPoolBump::endBump() glDisableClientState(GL_TEXTURE_COORD_ARRAY); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gGL.blendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); } //////////////////////////////////////////////////////////////// @@ -864,47 +1084,16 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerImage *src_vi, LLIma } } -void LLDrawPoolBump::renderBumpActive(U32 type, U32 mask) -{ -#if !LL_RELEASE_FOR_DOWNLOAD - LLGLState::checkClientArrays(mask); -#endif - - LLSpatialBridge* last_bridge = NULL; - glPushMatrix(); - - for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mActiveGroups.begin(); i != gPipeline.mActiveGroups.end(); ++i) - { - LLSpatialGroup* group = *i; - if (!group->isDead() && - group->mSpatialPartition->mRenderByGroup && - group->mDrawMap.find(type) != group->mDrawMap.end()) - { - LLSpatialBridge* bridge = (LLSpatialBridge*) group->mSpatialPartition; - if (bridge != last_bridge) - { - glPopMatrix(); - glPushMatrix(); - glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); - last_bridge = bridge; - } - - renderGroupBump(group,type,mask); - } - } - - glPopMatrix(); -} - void LLDrawPoolBump::renderBump(U32 type, U32 mask) { #if !LL_RELEASE_FOR_DOWNLOAD LLGLState::checkClientArrays(mask); #endif - LLSpatialGroup::drawmap_elem_t& draw_info = gPipeline.mRenderMap[type]; + LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type); + LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type); - for (LLSpatialGroup::drawmap_elem_t::iterator i = draw_info.begin(); i != draw_info.end(); ++i) + for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i) { LLDrawInfo& params = **i; @@ -932,25 +1121,96 @@ void LLDrawPoolBump::renderGroupBump(LLSpatialGroup* group, U32 type, U32 mask) void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) { + applyModelMatrix(params); + if (params.mTextureMatrix) { - glActiveTextureARB(GL_TEXTURE1_ARB); - glMatrixMode(GL_TEXTURE); - glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); - glActiveTextureARB(GL_TEXTURE0_ARB); + if (mShiny) + { + glActiveTextureARB(GL_TEXTURE0_ARB); + glMatrixMode(GL_TEXTURE); + } + else + { + glActiveTextureARB(GL_TEXTURE1_ARB); + glMatrixMode(GL_TEXTURE); + glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + glActiveTextureARB(GL_TEXTURE0_ARB); + } + glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } + + if (mShiny && mVertexShaderLevel > 1 && texture) + { + if (params.mTexture.notNull()) + { + params.mTexture->bind(diffuse_channel); + params.mTexture->addTextureStats(params.mVSize); + } + else + { + LLImageGL::unbindTexture(0); + } + + if (LLPipeline::sDynamicReflections) + { + LLCubeMap* cube_map = params.mReflectionMap; + + if (!cube_map && params.mModelMatrix) + { + cube_map = gPipeline.findReflectionMap(params.mModelMatrix->getTranslation()); + } + + if (cube_map) + { + cube_map->enableTexture(cube_channel); + cube_map->bind(); + } + } } + params.mVertexBuffer->setBuffer(mask); - U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer(); + U16* indices_pointer = (U16*) params.mVertexBuffer->getIndicesPointer(); glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount, - GL_UNSIGNED_INT, indices_pointer+params.mOffset); - gPipeline.mTrianglesDrawn += params.mCount/3; + GL_UNSIGNED_SHORT, indices_pointer+params.mOffset); + gPipeline.addTrianglesDrawn(params.mCount/3); + if (params.mTextureMatrix) { - glActiveTextureARB(GL_TEXTURE1_ARB); - glLoadIdentity(); - glActiveTextureARB(GL_TEXTURE0_ARB); + if (mShiny) + { + glActiveTextureARB(GL_TEXTURE0_ARB); + } + else + { + glActiveTextureARB(GL_TEXTURE1_ARB); + glLoadIdentity(); + glActiveTextureARB(GL_TEXTURE0_ARB); + } glLoadIdentity(); glMatrixMode(GL_MODELVIEW); } } + +void LLDrawPoolInvisible::render(S32 pass) +{ //render invisiprims + LLFastTimer t(LLFastTimer::FTM_RENDER_INVISIBLE); + + U32 invisi_mask = LLVertexBuffer::MAP_VERTEX; + glStencilMask(0); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + pushBatches(LLRenderPass::PASS_INVISIBLE, invisi_mask, FALSE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + glStencilMask(0xFFFFFFFF); + + if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) + { + beginShiny(true); + renderShiny(true); + endShiny(true); + } +} + diff --git a/linden/indra/newview/lldrawpoolbump.h b/linden/indra/newview/lldrawpoolbump.h index 665529e..246f5f3 100644 --- a/linden/indra/newview/lldrawpoolbump.h +++ b/linden/indra/newview/lldrawpoolbump.h @@ -43,31 +43,36 @@ class LLDrawInfo; class LLDrawPoolBump : public LLRenderPass { +protected : + LLDrawPoolBump(const U32 type):LLRenderPass(type) { mShiny = FALSE; } public: static U32 sVertexMask; + BOOL mShiny; virtual U32 getVertexDataMask() { return sVertexMask; } LLDrawPoolBump(); virtual void render(S32 pass = 0); - /*virtual*/ void beginRenderPass( S32 pass ); - /*virtual*/ void endRenderPass( S32 pass ); - /*virtual*/ S32 getNumPasses(); + virtual void beginRenderPass( S32 pass ); + virtual void endRenderPass( S32 pass ); + virtual S32 getNumPasses(); /*virtual*/ void prerender(); /*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture); void renderBump(U32 type, U32 mask); - void renderBumpActive(U32 type, U32 mask); void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture); void renderGroupBump(LLSpatialGroup* group, U32 type, U32 mask); S32 numBumpPasses(); - void beginShiny(); - void renderShiny(); - void endShiny(); - void renderActive(U32 type, U32 mask, BOOL texture = TRUE); + void beginShiny(bool invisible = false); + void renderShiny(bool invisible = false); + void endShiny(bool invisible = false); + + void beginFullbrightShiny(); + void renderFullbrightShiny(); + void endFullbrightShiny(); void beginBump(); void renderBump(); @@ -143,6 +148,25 @@ private: extern LLBumpImageList gBumpImageList; +class LLDrawPoolInvisible : public LLDrawPoolBump +{ +public: + LLDrawPoolInvisible() : LLDrawPoolBump(LLDrawPool::POOL_INVISIBLE) { } + + enum + { + VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX + }; + + virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + + virtual void prerender() { } + + virtual void render(S32 pass = 0); + virtual void beginRenderPass( S32 pass ) { } + virtual void endRenderPass( S32 pass ) { } + virtual S32 getNumPasses() {return 1;} +}; #endif // LL_LLDRAWPOOLBUMP_H diff --git a/linden/indra/newview/lldrawpoolclouds.h b/linden/indra/newview/lldrawpoolclouds.h index b350ad0..f7e4dda 100644 --- a/linden/indra/newview/lldrawpoolclouds.h +++ b/linden/indra/newview/lldrawpoolclouds.h @@ -55,7 +55,6 @@ public: /*virtual*/ void beginRenderPass(S32 pass); /*virtual*/ void render(S32 pass = 0); /*virtual*/ void renderForSelect(); - virtual S32 getMaterialAttribIndex() { return 0; } }; #endif // LL_LLDRAWPOOLSKY_H diff --git a/linden/indra/newview/lldrawpoolground.cpp b/linden/indra/newview/lldrawpoolground.cpp index 6ff7f06..dc5e397 100644 --- a/linden/indra/newview/lldrawpoolground.cpp +++ b/linden/indra/newview/lldrawpoolground.cpp @@ -72,15 +72,10 @@ void LLDrawPoolGround::render(S32 pass) glEnableClientState(GL_VERTEX_ARRAY); LLGLSPipelineSkyBox gls_skybox; - LLGLDisable tex(GL_TEXTURE_2D); - LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); + LLImageGL::unbindTexture(0, GL_TEXTURE_2D); + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - glMatrixMode( GL_PROJECTION ); - - glPushMatrix(); - //gViewerWindow->setup3DRender(); - - glMatrixMode(GL_MODELVIEW); + LLGLClampToFarClip far_clip(glh_get_current_projection()); F32 water_height = gAgent.getRegion()->getWaterHeight(); glPushMatrix(); @@ -94,9 +89,6 @@ void LLDrawPoolGround::render(S32 pass) LLOverrideFaceColor col(this, gSky.mVOSkyp->getGLFogColor()); facep->renderIndexed(); - glMatrixMode( GL_PROJECTION ); - glPopMatrix(); - glMatrixMode( GL_MODELVIEW ); glPopMatrix(); } diff --git a/linden/indra/newview/lldrawpoolground.h b/linden/indra/newview/lldrawpoolground.h index 5cdce7b..3bfdc14 100644 --- a/linden/indra/newview/lldrawpoolground.h +++ b/linden/indra/newview/lldrawpoolground.h @@ -49,7 +49,6 @@ public: LLDrawPoolGround(); /*virtual*/ LLDrawPool *instancePool(); - virtual S32 getMaterialAttribIndex() { return 0; } /*virtual*/ void prerender(); /*virtual*/ void render(S32 pass = 0); diff --git a/linden/indra/newview/lldrawpoolsimple.cpp b/linden/indra/newview/lldrawpoolsimple.cpp index 7e6c3dd..cdb22bf 100644 --- a/linden/indra/newview/lldrawpoolsimple.cpp +++ b/linden/indra/newview/lldrawpoolsimple.cpp @@ -32,7 +32,6 @@ #include "llviewerprecompiledheaders.h" #include "lldrawpoolsimple.h" -#include "lldrawpoolbump.h" #include "llviewercamera.h" #include "llagent.h" @@ -40,76 +39,46 @@ #include "llface.h" #include "llsky.h" #include "pipeline.h" +#include "llspatialpartition.h" #include "llglslshader.h" +#include "llglimmediate.h" -class LLRenderShinyGlow : public LLDrawPoolBump -{ -public: - LLRenderShinyGlow() { } - - void render(S32 pass = 0) - { - LLCubeMap* cube_map = gSky.mVOSkyp->getCubeMap(); - if( cube_map ) - { - cube_map->enable(0); - cube_map->setMatrix(0); - cube_map->bind(); - glEnableClientState(GL_NORMAL_ARRAY); - - glColor4f(1,1,1,1); - - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL; - renderStatic(LLRenderPass::PASS_SHINY, mask); - renderActive(LLRenderPass::PASS_SHINY, mask); - - glDisableClientState(GL_NORMAL_ARRAY); - cube_map->disable(); - cube_map->restoreMatrix(); - } - } -}; + +static LLGLSLShader* simple_shader = NULL; +static LLGLSLShader* fullbright_shader = NULL; void LLDrawPoolGlow::render(S32 pass) { + LLFastTimer t(LLFastTimer::FTM_RENDER_GLOW); LLGLEnable blend(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask()); - renderActive(LLRenderPass::PASS_GLOW, getVertexDataMask()); + LLGLDisable test(GL_ALPHA_TEST); + gGL.blendFunc(GL_ONE, GL_ONE); + + U32 shader_level = LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_OBJECT); - if (gSky.mVOSkyp) + if (shader_level > 0 && fullbright_shader) { - glPushMatrix(); - LLVector3 origin = gCamera->getOrigin(); - glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]); - - LLFace* facep = gSky.mVOSkyp->mFace[LLVOSky::FACE_BLOOM]; - - if (facep) - { - LLGLDisable cull(GL_CULL_FACE); - facep->getTexture()->bind(); - glColor4f(1,1,1,1); - facep->renderIndexed(getVertexDataMask()); - } - - glPopMatrix(); + fullbright_shader->bind(); } - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - - if (LLPipeline::sDynamicReflections) + else { - LLRenderShinyGlow glow; - glow.render(); + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); } + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + renderTexture(LLRenderPass::PASS_GLOW, getVertexDataMask()); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (shader_level > 0 && fullbright_shader) + { + fullbright_shader->unbind(); + } } void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) @@ -131,53 +100,87 @@ void LLDrawPoolSimple::prerender() void LLDrawPoolSimple::beginRenderPass(S32 pass) { + LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); + + if (LLPipeline::sUnderWaterRender) + { + simple_shader = &gObjectSimpleWaterProgram; + fullbright_shader = &gObjectFullbrightWaterProgram; + } + else + { + simple_shader = &gObjectSimpleProgram; + fullbright_shader = &gObjectFullbrightProgram; + } + + if (mVertexShaderLevel > 0) + { + simple_shader->bind(); + simple_shader->uniform1f(LLShaderMgr::FULLBRIGHT, 0.f); + } + else + { + // don't use shaders! + if (gGLManager.mHasShaderObjects) + { + glUseProgramObjectARB(0); + } + } +} + +void LLDrawPoolSimple::endRenderPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); + LLRenderPass::endRenderPass(pass); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + if (mVertexShaderLevel > 0){ + + simple_shader->unbind(); + } } void LLDrawPoolSimple::render(S32 pass) { LLGLDisable blend(GL_BLEND); - LLGLDisable alpha_test(GL_ALPHA_TEST); - - { + LLGLState alpha_test(GL_ALPHA_TEST, gPipeline.canUseWindLightShadersOnObjects()); + glAlphaFunc(GL_GREATER, 0.5f); + + { //render simple LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); - gPipeline.enableLightsDynamic(1.f); + gPipeline.enableLightsDynamic(); renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); - renderActive(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); } { LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); + LLGLEnable test(GL_ALPHA_TEST); LLGLEnable blend(GL_BLEND); - LLGLEnable alpha_test(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.5f); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //render grass LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask()); - glAlphaFunc(GL_GREATER, 0.01f); - } - - { + } + + { //render fullbright + if (mVertexShaderLevel > 0) + { + fullbright_shader->bind(); + fullbright_shader->uniform1f(LLShaderMgr::FULLBRIGHT, 1.f); + } + else + { + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + } LLFastTimer t(LLFastTimer::FTM_RENDER_FULLBRIGHT); U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD | LLVertexBuffer::MAP_COLOR; - gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); glDisableClientState(GL_NORMAL_ARRAY); renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask); - renderActive(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask); } - { - LLFastTimer t(LLFastTimer::FTM_RENDER_INVISIBLE); - U32 invisi_mask = LLVertexBuffer::MAP_VERTEX; - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - renderInvisible(invisi_mask); - renderActive(LLRenderPass::PASS_INVISIBLE, invisi_mask); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - } + glAlphaFunc(GL_GREATER, 0.01f); } diff --git a/linden/indra/newview/lldrawpoolsimple.h b/linden/indra/newview/lldrawpoolsimple.h index 8eeb8ed..bb14703 100644 --- a/linden/indra/newview/lldrawpoolsimple.h +++ b/linden/indra/newview/lldrawpoolsimple.h @@ -49,6 +49,9 @@ public: LLDrawPoolSimple(); /*virtual*/ void beginRenderPass(S32 pass); + /*virtual*/ void endRenderPass(S32 pass); + /// We need two passes so we can handle emissive materials separately. + /*virtual*/ S32 getNumPasses() { return 1; } /*virtual*/ void render(S32 pass = 0); /*virtual*/ void prerender(); diff --git a/linden/indra/newview/lldrawpoolsky.cpp b/linden/indra/newview/lldrawpoolsky.cpp index 127c5c5..ef91b58 100644 --- a/linden/indra/newview/lldrawpoolsky.cpp +++ b/linden/indra/newview/lldrawpoolsky.cpp @@ -49,7 +49,7 @@ #include "llglslshader.h" LLDrawPoolSky::LLDrawPoolSky() : - LLFacePool(POOL_SKY) + LLFacePool(POOL_SKY), mShader(NULL) { } @@ -61,6 +61,7 @@ LLDrawPool *LLDrawPoolSky::instancePool() void LLDrawPoolSky::prerender() { mVertexShaderLevel = LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_ENVIRONMENT); + gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable); } void LLDrawPoolSky::render(S32 pass) @@ -70,25 +71,45 @@ void LLDrawPoolSky::render(S32 pass) return; } + // Don't draw the sky box if we can and are rendering the WL sky dome. + if (gPipeline.canUseWindLightShaders()) + { + return; + } + + // use a shader only underwater + if(mVertexShaderLevel > 0 && LLPipeline::sUnderWaterRender) + { + mShader = &gObjectFullbrightWaterProgram; + mShader->bind(); + } + else + { + // don't use shaders! + if (gGLManager.mHasShaderObjects) + { + // Ironically, we must support shader objects to be + // able to use this call. + glUseProgramObjectARB(0); + } + mShader = NULL; + } + + LLVOSky *voskyp = gSky.mVOSkyp; LLGLSPipelineSkyBox gls_skybox; - LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); - if (gCamera->getOrigin().mV[VZ] < gAgent.getRegion()->getWaterHeight()) - //gWorldPointer->getWaterHeight()) - { - //gGLSFog.set(); - } + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + + LLGLClampToFarClip far_clip(glh_get_current_projection()); + + LLGLEnable fog_enable( (mVertexShaderLevel < 1 && gCamera->cameraUnderWater()) ? GL_FOG : 0); gPipeline.disableLights(); - glMatrixMode( GL_PROJECTION ); + LLGLDisable clip(GL_CLIP_PLANE0); glPushMatrix(); - //gViewerWindow->setup3DRender(); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); LLVector3 origin = gCamera->getOrigin(); glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]); @@ -128,21 +149,19 @@ void LLDrawPoolSky::render(S32 pass) if (hbfaces[2]) { - renderSunHalo(hbfaces[2]); + // renderSunHalo(hbfaces[2]); } if (hbfaces[0]) { - renderHeavenlyBody(0, hbfaces[0]); + // renderHeavenlyBody(0, hbfaces[0]); } if (hbfaces[1]) { - renderHeavenlyBody(1, hbfaces[1]); + // renderHeavenlyBody(1, hbfaces[1]); } + glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glMatrixMode( GL_PROJECTION ); - glPopMatrix(); - glMatrixMode( GL_MODELVIEW ); glPopMatrix(); } @@ -204,3 +223,6 @@ void LLDrawPoolSky::renderForSelect() { } +void LLDrawPoolSky::endRenderPass( S32 pass ) +{ +} diff --git a/linden/indra/newview/lldrawpoolsky.h b/linden/indra/newview/lldrawpoolsky.h index fe4cc36..282ec1d 100644 --- a/linden/indra/newview/lldrawpoolsky.h +++ b/linden/indra/newview/lldrawpoolsky.h @@ -36,12 +36,14 @@ class LLSkyTex; class LLHeavenBody; +class LLGLSLShader; class LLDrawPoolSky : public LLFacePool { private: LLSkyTex *mSkyTex; LLHeavenBody *mHB[2]; // Sun and Moon + LLGLSLShader *mShader; public: enum @@ -59,6 +61,7 @@ public: /*virtual*/ void prerender(); /*virtual*/ void render(S32 pass = 0); /*virtual*/ void renderForSelect(); + /*virtual*/ void endRenderPass(S32 pass); void setSkyTex(LLSkyTex* const st) { mSkyTex = st; } void setSun(LLHeavenBody* sun_flag) { mHB[0] = sun_flag; } void setMoon(LLHeavenBody* moon) { mHB[1] = moon; } @@ -67,7 +70,6 @@ public: void renderHeavenlyBody(U8 hb, LLFace* face); void renderSunHalo(LLFace* face); - virtual S32 getMaterialAttribIndex() { return 0; } }; #endif // LL_LLDRAWPOOLSKY_H diff --git a/linden/indra/newview/lldrawpoolstars.cpp b/linden/indra/newview/lldrawpoolstars.cpp deleted file mode 100644 index 3f9c8db..0000000 --- a/linden/indra/newview/lldrawpoolstars.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/** - * @file lldrawpoolstars.cpp - * @brief LLDrawPoolStars class implementation - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "lldrawpoolstars.h" - -#include "llface.h" -#include "llsky.h" -#include "llvostars.h" -#include "pipeline.h" -#include "llviewercamera.h" -#include "llglslshader.h" - -LLDrawPoolStars::LLDrawPoolStars() : - LLFacePool(POOL_STARS) -{ -} - -LLDrawPool *LLDrawPoolStars::instancePool() -{ - return new LLDrawPoolStars(); -} - -void LLDrawPoolStars::prerender() -{ - mVertexShaderLevel = LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_ENVIRONMENT); -} - -void LLDrawPoolStars::render(S32 pass) -{ - if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))) - { - return; - } - - if (mDrawFace.empty()) - { - return; - } - - LLGLSPipelineSkyBox gls_sky; - LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE); - LLGLEnable blend(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - LLGLDisable gl_texture_2d(GL_TEXTURE_2D); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - - gPipeline.disableLights(); - - GLint* viewport = (GLint*) gGLViewport; - - if (viewport[2] > 512 && viewport[3] > 512) - { - glPointSize(2.f); - } - - LLVector3 origin = gCamera->getOrigin(); - glPushMatrix(); - glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]); - - glEnableClientState(GL_COLOR_ARRAY); - - S32 face_count = (S32)mDrawFace.size(); - for (S32 curr_face = 0; curr_face < face_count; curr_face++) - { - LLFace* face = mDrawFace[curr_face]; - if (!face->getGeomCount()) - { - continue; - } - - // render the stars as a sphere centered at viewer camera - if (face->mVertexBuffer.notNull()) - { - face->mVertexBuffer->setBuffer(getVertexDataMask()); - U32* indicesp = (U32*) face->mVertexBuffer->getIndicesPointer(); - glDrawElements(GL_POINTS, face->getIndicesCount(), GL_UNSIGNED_INT, indicesp); - mIndicesDrawn += face->getIndicesCount(); - } - } - glDisableClientState(GL_COLOR_ARRAY); - glPointSize(1.f); - glPopMatrix(); -} - - -void LLDrawPoolStars::renderForSelect() -{ -} - diff --git a/linden/indra/newview/lldrawpoolstars.h b/linden/indra/newview/lldrawpoolstars.h deleted file mode 100644 index 05b7f9e..0000000 --- a/linden/indra/newview/lldrawpoolstars.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @file lldrawpoolstars.h - * @brief LLDrawPoolStars class definition - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLDRAWPOOLSTARS_H -#define LL_LLDRAWPOOLSTARS_H - -#include "lldrawpool.h" - -class LLDrawPoolStars : public LLFacePool -{ -public: - enum - { - VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_COLOR - }; - - virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } - - LLDrawPoolStars(); - - /*virtual*/ LLDrawPool *instancePool(); - /*virtual*/ void prerender(); - /*virtual*/ void render(S32 pass = 0); - /*virtual*/ void renderForSelect(); - virtual S32 getMaterialAttribIndex() { return 0; } -}; - -#endif // LL_LLDRAWPOOLSKY_H diff --git a/linden/indra/newview/lldrawpoolterrain.cpp b/linden/indra/newview/lldrawpoolterrain.cpp index e315259..82fcd59 100644 --- a/linden/indra/newview/lldrawpoolterrain.cpp +++ b/linden/indra/newview/lldrawpoolterrain.cpp @@ -52,12 +52,14 @@ #include "llworld.h" #include "pipeline.h" #include "llglslshader.h" +#include "llglimmediate.h" const F32 DETAIL_SCALE = 1.f/16.f; int DebugDetailMap = 0; S32 LLDrawPoolTerrain::sDetailMode = 1; F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE; +static LLGLSLShader* sShader = NULL; LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerImage *texturep) : LLFacePool(POOL_TERRAIN), @@ -95,10 +97,40 @@ LLDrawPool *LLDrawPoolTerrain::instancePool() void LLDrawPoolTerrain::prerender() { -#if 0 // 1.9.2 - mVertexShaderLevel = gPipeline.getVertexShaderLevel(LLPipeline::SHADER_ENVIRONMENT); -#endif - sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); + mVertexShaderLevel = LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_ENVIRONMENT); + if (mVertexShaderLevel > 0) + { + sDetailMode = 1; + } + else + { + sDetailMode = gSavedSettings.getS32("RenderTerrainDetail"); + } +} + +void LLDrawPoolTerrain::beginRenderPass( S32 pass ) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + LLFacePool::beginRenderPass(pass); + + sShader = LLPipeline::sUnderWaterRender ? + &gTerrainWaterProgram : + &gTerrainProgram; + + if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0) + { + sShader->bind(); + } +} + +void LLDrawPoolTerrain::endRenderPass( S32 pass ) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + LLFacePool::endRenderPass(pass); + + if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0) { + sShader->unbind(); + } } //static @@ -127,7 +159,7 @@ void LLDrawPoolTerrain::render(S32 pass) if (!gGLManager.mHasMultitexture) { - // No mulititexture, render simple land. + // No multitexture, render simple land. renderSimple(); // Render without multitexture return; } @@ -141,52 +173,47 @@ void LLDrawPoolTerrain::render(S32 pass) LLGLSPipeline gls; LLOverrideFaceColor override(this, 1.f, 1.f, 1.f, 1.f); - if (mVertexShaderLevel > 0) + if (mVertexShaderLevel > 1 && sShader->mShaderLevel > 0) { - gPipeline.enableLightsDynamic(1.f); - renderFull4TUShader(); + gPipeline.enableLightsDynamic(); + renderFullShader(); } else { - gPipeline.enableLightsStatic(1.f); - switch (sDetailMode) - { - case 0: + gPipeline.enableLightsStatic(); + + if (sDetailMode == 0){ renderSimple(); - break; - default: - if (gGLManager.mNumTextureUnits < 4) - { - renderFull2TU(); - } - else - { - renderFull4TU(); - } - break; + } else if (gGLManager.mNumTextureUnits < 4){ + renderFull2TU(); + } else { + renderFull4TU(); } } // Special-case for land ownership feedback if (gSavedSettings.getBOOL("ShowParcelOwners")) { - gPipeline.disableLights(); - if ((mVertexShaderLevel > 0)) - { - gHighlightProgram.bind(); - gHighlightProgram.vertexAttrib4f(LLShaderMgr::MATERIAL_COLOR,1,1,1,1); + if (mVertexShaderLevel > 1) + { //use fullbright shader for highlighting + LLGLSLShader* old_shader = sShader; + sShader->unbind(); + sShader = &gObjectFullbrightProgram; + sShader->bind(); renderOwnership(); - gTerrainProgram.bind(); + sShader = old_shader; + sShader->bind(); } else { + gPipeline.disableLights(); renderOwnership(); } } } -void LLDrawPoolTerrain::renderFull4TUShader() +void LLDrawPoolTerrain::renderFullShader() { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); @@ -195,9 +222,7 @@ void LLDrawPoolTerrain::renderFull4TUShader() { glEnableClientState(GL_COLOR_ARRAY); } - - glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); - + // Hack! Get the region that this draw pool is rendering from! LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion(); LLVLComposition *compp = regionp->getComposition(); @@ -206,12 +231,7 @@ void LLDrawPoolTerrain::renderFull4TUShader() LLViewerImage *detail_texture2p = compp->mDetailTextures[2]; LLViewerImage *detail_texture3p = compp->mDetailTextures[3]; - static F32 dp = 0.f; - static LLFrameTimer timer; - dp += timer.getElapsedTimeAndResetF32(); - LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal(); - F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale; F32 offset_y = (F32)fmod(region_origin_global.mdV[VY], 1.0/(F64)sDetailScale)*sDetailScale; @@ -220,145 +240,111 @@ void LLDrawPoolTerrain::renderFull4TUShader() tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); - //---------------------------------------------------------------------------- - // Pass 1/1 - // - // Stage 0: detail texture 0 + // detail texture 0 // - - S32 detailTex0 = gTerrainProgram.enableTexture(LLShaderMgr::TERRAIN_DETAIL0); - S32 detailTex1 = gTerrainProgram.enableTexture(LLShaderMgr::TERRAIN_DETAIL1); - S32 rampTex = gTerrainProgram.enableTexture(LLShaderMgr::TERRAIN_ALPHARAMP); - - LLViewerImage::bindTexture(detail_texture0p,detailTex0); - + S32 detail0 = sShader->enableTexture(LLShaderMgr::TERRAIN_DETAIL0); + LLViewerImage::bindTexture(detail_texture0p,detail0); glClientActiveTextureARB(GL_TEXTURE0_ARB); glActiveTextureARB(GL_TEXTURE0_ARB); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); - // - // Stage 1: Generate alpha ramp for detail0/detail1 transition - // - LLViewerImage::bindTexture(m2DAlphaRampImagep,rampTex); - - glClientActiveTextureARB(GL_TEXTURE1_ARB); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - // - // Stage 2: Interpolate detail1 with existing based on ramp - // - LLViewerImage::bindTexture(detail_texture1p,detailTex1); - - glClientActiveTextureARB(GL_TEXTURE2_ARB); - glActiveTextureARB(GL_TEXTURE2_ARB); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); - // - // Stage 3: Modulate with primary color for lighting - // - //LLViewerImage::bindTexture(detail_texture1p,3); // bind any texture - //glEnable(GL_TEXTURE_2D); // Texture unit 3 - glClientActiveTextureARB(GL_TEXTURE3_ARB); - glActiveTextureARB(GL_TEXTURE3_ARB); - // GL_BLEND disabled by default - drawLoop(); - - //---------------------------------------------------------------------------- - // Second pass - - // - // Stage 0: Write detail3 into base - // - LLViewerImage::bindTexture(detail_texture2p,detailTex0); - - glClientActiveTextureARB(GL_TEXTURE0_ARB); - glActiveTextureARB(GL_TEXTURE0_ARB); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); // - // Stage 1: Generate alpha ramp for detail2/detail3 transition + // detail texture 1 // - LLViewerImage::bindTexture(m2DAlphaRampImagep,rampTex); + S32 detail1 = sShader->enableTexture(LLShaderMgr::TERRAIN_DETAIL1); + LLViewerImage::bindTexture(detail_texture1p,detail1); + /// ALPHA TEXTURE COORDS 0: glClientActiveTextureARB(GL_TEXTURE1_ARB); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); glActiveTextureARB(GL_TEXTURE1_ARB); - - // Set the texture matrix + glEnableClientState(GL_TEXTURE_COORD_ARRAY); glMatrixMode(GL_TEXTURE); glLoadIdentity(); - glTranslatef(-2.f, 0.f, 0.f); - - // - // Stage 2: Interpolate detail2 with existing based on ramp + glMatrixMode(GL_MODELVIEW); + + // detail texture 2 // - LLViewerImage::bindTexture(detail_texture3p,detailTex1); + S32 detail2 = sShader->enableTexture(LLShaderMgr::TERRAIN_DETAIL2); + LLViewerImage::bindTexture(detail_texture2p,detail2); + glEnable(GL_TEXTURE_2D); + /// ALPHA TEXTURE COORDS 1: glClientActiveTextureARB(GL_TEXTURE2_ARB); glActiveTextureARB(GL_TEXTURE2_ARB); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glTranslatef(-2.f, 0.f, 0.f); + glMatrixMode(GL_MODELVIEW); // - // Stage 3: Generate alpha ramp for detail1/detail2 transition + // detail texture 3 // - //LLViewerImage::bindTexture(m2DAlphaRampImagep,3); - - //glEnable(GL_TEXTURE_2D); // Texture unit 3 + S32 detail3 = sShader->enableTexture(LLShaderMgr::TERRAIN_DETAIL3); + LLViewerImage::bindTexture(detail_texture3p,detail3); + /// ALPHA TEXTURE COORDS 2: glClientActiveTextureARB(GL_TEXTURE3_ARB); glActiveTextureARB(GL_TEXTURE3_ARB); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - // Set the texture matrix glMatrixMode(GL_TEXTURE); glLoadIdentity(); glTranslatef(-1.f, 0.f, 0.f); + glMatrixMode(GL_MODELVIEW); - { - LLGLEnable blend(GL_BLEND); - drawLoop(); - } + // + // Alpha Ramp + // + S32 alpha_ramp = sShader->enableTexture(LLShaderMgr::TERRAIN_ALPHARAMP); + LLViewerImage::bindTexture(m2DAlphaRampImagep,alpha_ramp); + + // GL_BLEND disabled by default + drawLoop(); // Disable multitexture - gTerrainProgram.disableTexture(LLShaderMgr::TERRAIN_ALPHARAMP); - gTerrainProgram.disableTexture(LLShaderMgr::TERRAIN_DETAIL0); - gTerrainProgram.disableTexture(LLShaderMgr::TERRAIN_DETAIL1); - + sShader->disableTexture(LLShaderMgr::TERRAIN_ALPHARAMP); + sShader->disableTexture(LLShaderMgr::TERRAIN_DETAIL0); + sShader->disableTexture(LLShaderMgr::TERRAIN_DETAIL1); + sShader->disableTexture(LLShaderMgr::TERRAIN_DETAIL2); + sShader->disableTexture(LLShaderMgr::TERRAIN_DETAIL3); + + LLImageGL::unbindTexture(alpha_ramp, GL_TEXTURE_2D); + glClientActiveTextureARB(GL_TEXTURE4_ARB); + glActiveTextureARB(GL_TEXTURE4_ARB); + glDisable(GL_TEXTURE_2D); // Texture unit 4 + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + + LLImageGL::unbindTexture(detail3, GL_TEXTURE_2D); glClientActiveTextureARB(GL_TEXTURE3_ARB); glActiveTextureARB(GL_TEXTURE3_ARB); + glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); + LLImageGL::unbindTexture(detail2, GL_TEXTURE_2D); glClientActiveTextureARB(GL_TEXTURE2_ARB); glActiveTextureARB(GL_TEXTURE2_ARB); + glDisable(GL_TEXTURE_2D); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); @@ -366,32 +352,32 @@ void LLDrawPoolTerrain::renderFull4TUShader() glLoadIdentity(); glMatrixMode(GL_MODELVIEW); + LLImageGL::unbindTexture(detail1, GL_TEXTURE_2D); glClientActiveTextureARB(GL_TEXTURE1_ARB); glActiveTextureARB(GL_TEXTURE1_ARB); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_TEXTURE_2D); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); - - // Restore blend state - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //---------------------------------------------------------------------------- // Restore Texture Unit 0 defaults + LLImageGL::unbindTexture(detail0, GL_TEXTURE_2D); glClientActiveTextureARB(GL_TEXTURE0_ARB); glActiveTextureARB(GL_TEXTURE0_ARB); + glEnable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); - glEnable(GL_TEXTURE_2D); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); // Restore non Texture Unit specific defaults glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } void LLDrawPoolTerrain::renderFull4TU() @@ -416,7 +402,7 @@ void LLDrawPoolTerrain::renderFull4TU() tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); - glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); + gGL.blendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); //---------------------------------------------------------------------------- // Pass 1/1 @@ -649,7 +635,7 @@ void LLDrawPoolTerrain::renderFull4TU() glMatrixMode(GL_MODELVIEW); // Restore blend state - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //---------------------------------------------------------------------------- // Restore Texture Unit 0 defaults @@ -690,7 +676,7 @@ void LLDrawPoolTerrain::renderFull2TU() tp0.setVec(sDetailScale, 0.0f, 0.0f, offset_x); tp1.setVec(0.0f, sDetailScale, 0.0f, offset_y); - glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); + gGL.blendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); //---------------------------------------------------------------------------- // Pass 1/4 @@ -887,7 +873,7 @@ void LLDrawPoolTerrain::renderFull2TU() } // Restore blend state - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Disable multitexture LLImageGL::unbindTexture(1, GL_TEXTURE_2D); @@ -1015,7 +1001,6 @@ void LLDrawPoolTerrain::renderOwnership() const F32 TEXTURE_FUDGE = 257.f / 256.f; glScalef( TEXTURE_FUDGE, TEXTURE_FUDGE, 1.f ); - for (std::vector::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { @@ -1082,8 +1067,3 @@ LLColor3 LLDrawPoolTerrain::getDebugColor() const { return LLColor3(0.f, 0.f, 1.f); } - -S32 LLDrawPoolTerrain::getMaterialAttribIndex() -{ - return gTerrainProgram.mAttribute[LLShaderMgr::MATERIAL_COLOR]; -} diff --git a/linden/indra/newview/lldrawpoolterrain.h b/linden/indra/newview/lldrawpoolterrain.h index 80a1fcb..53a5cd0 100644 --- a/linden/indra/newview/lldrawpoolterrain.h +++ b/linden/indra/newview/lldrawpoolterrain.h @@ -58,6 +58,8 @@ public: /*virtual*/ void render(S32 pass = 0); /*virtual*/ void prerender(); + /*virtual*/ void beginRenderPass( S32 pass ); + /*virtual*/ void endRenderPass( S32 pass ); /*virtual*/ void renderForSelect(); /*virtual*/ void dirtyTextures(const std::set& textures); /*virtual*/ LLViewerImage *getTexture(); @@ -68,8 +70,6 @@ public: LLPointer m2DAlphaRampImagep; LLPointer mAlphaNoiseImagep; - virtual S32 getMaterialAttribIndex(); - static S32 sDetailMode; static F32 sDetailScale; // meters per texture protected: @@ -78,7 +78,7 @@ protected: void renderFull2TU(); void renderFull4TU(); - void renderFull4TUShader(); + void renderFullShader(); }; #endif // LL_LLDRAWPOOLSIMPLE_H diff --git a/linden/indra/newview/lldrawpooltree.cpp b/linden/indra/newview/lldrawpooltree.cpp index f5971be..fd1ca8e 100644 --- a/linden/indra/newview/lldrawpooltree.cpp +++ b/linden/indra/newview/lldrawpooltree.cpp @@ -41,8 +41,10 @@ #include "pipeline.h" #include "llviewercamera.h" #include "llglslshader.h" +#include "llglimmediate.h" S32 LLDrawPoolTree::sDiffTex = 0; +static LLGLSLShader* shader = NULL; LLDrawPoolTree::LLDrawPoolTree(LLViewerImage *texturep) : LLFacePool(POOL_TREE), @@ -59,15 +61,34 @@ LLDrawPool *LLDrawPoolTree::instancePool() void LLDrawPoolTree::prerender() { - mVertexShaderLevel = 0; + mVertexShaderLevel = LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_OBJECT); } void LLDrawPoolTree::beginRenderPass(S32 pass) { + LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glAlphaFunc(GL_GREATER, 0.5f); + + if (LLPipeline::sUnderWaterRender) + { + shader = &gObjectSimpleWaterProgram; + } + else + { + shader = &gObjectSimpleProgram; + } + + if (gPipeline.canUseWindLightShadersOnObjects()) + { + shader->bind(); + } + else + { + gPipeline.enableLightsDynamic(); + } } void LLDrawPoolTree::render(S32 pass) @@ -79,8 +100,7 @@ void LLDrawPoolTree::render(S32 pass) return; } - gPipeline.enableLightsDynamic(1.f); - LLGLSPipelineAlpha gls_pipeline_alpha; + LLGLEnable test(GL_ALPHA_TEST); LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f); renderTree(); @@ -88,9 +108,15 @@ void LLDrawPoolTree::render(S32 pass) void LLDrawPoolTree::endRenderPass(S32 pass) { + LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); glAlphaFunc(GL_GREATER, 0.01f); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + if (gPipeline.canUseWindLightShadersOnObjects()) + { + shader->unbind(); + } } void LLDrawPoolTree::renderForSelect() @@ -107,7 +133,7 @@ void LLDrawPoolTree::renderForSelect() LLGLSObjectSelectAlpha gls_alpha; - glBlendFunc(GL_ONE, GL_ZERO); + gGL.blendFunc(GL_ONE, GL_ZERO); glAlphaFunc(GL_GREATER, 0.5f); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); @@ -126,7 +152,7 @@ void LLDrawPoolTree::renderForSelect() renderTree(TRUE); glAlphaFunc(GL_GREATER, 0.01f); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisableClientState (GL_TEXTURE_COORD_ARRAY); @@ -138,16 +164,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting) // Bind the texture for this tree. LLViewerImage::bindTexture(mTexturep,sDiffTex); - if (mTexturep) - { - if (mTexturep->getClampS()) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - } - if (mTexturep->getClampT()) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - } - } - + U32 indices_drawn = 0; glMatrixMode(GL_MODELVIEW); @@ -164,7 +181,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting) } face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - U32* indicesp = (U32*) face->mVertexBuffer->getIndicesPointer(); + U16* indicesp = (U16*) face->mVertexBuffer->getIndicesPointer(); // Render each of the trees LLVOTree *treep = (LLVOTree *)drawablep->getVObj().get(); @@ -180,28 +197,43 @@ void LLDrawPoolTree::renderTree(BOOL selecting) color = LLColor4U((U8)(name >> 16), (U8)(name >> 8), (U8)name, 255); } - glPushMatrix(); + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + //glPushMatrix(); + F32 mat[16]; + for (U32 i = 0; i < 16; i++) + mat[i] = (F32) gGLModelView[i]; + + LLMatrix4 matrix(mat); // Translate to tree base HACK - adjustment in Z plants tree underground const LLVector3 &pos_agent = treep->getPositionAgent(); - glTranslatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); - - // Rotate to tree position - F32 angle_radians, x, y, z; - treep->getRotation().getAngleAxis(&angle_radians, &x, &y, &z); - glRotatef(angle_radians * RAD_TO_DEG, x, y, z); - - // Rotate and bend for current trunk/wind + //glTranslatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); + LLMatrix4 trans_mat; + trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); + trans_mat *= matrix; + + // Rotate to tree position and bend for current trunk/wind // Note that trunk stiffness controls the amount of bend at the trunk as // opposed to the crown of the tree // - glRotatef(90.f, 0, 0, 1); const F32 TRUNK_STIFF = 22.f; - glRotatef(treep->mTrunkBend.magVec()*TRUNK_STIFF, treep->mTrunkBend.mV[VX], treep->mTrunkBend.mV[VY], 0); + + LLQuaternion rot = + LLQuaternion(treep->mTrunkBend.magVec()*TRUNK_STIFF*DEG_TO_RAD, LLVector4(treep->mTrunkBend.mV[VX], treep->mTrunkBend.mV[VY], 0)) * + LLQuaternion(90.f*DEG_TO_RAD, LLVector4(0,0,1)) * + treep->getRotation(); - F32 radius = treep->getScale().magVec()*0.5f; - radius *= 0.1f; - glScalef(radius, radius, radius); + LLMatrix4 rot_mat(rot); + rot_mat *= trans_mat; + + F32 radius = treep->getScale().magVec()*0.05f; + LLMatrix4 scale_mat; + scale_mat.mMatrix[0][0] = + scale_mat.mMatrix[1][1] = + scale_mat.mMatrix[2][2] = radius; + + scale_mat *= rot_mat; const F32 THRESH_ANGLE_FOR_BILLBOARD = 15.f; const F32 BLEND_RANGE_FOR_BILLBOARD = 3.f; @@ -231,7 +263,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting) // Only the billboard, can use closer to normal alpha func. stop_depth = -1; LLFacePool::LLOverrideFaceColor clr(this, color); - indices_drawn += treep->drawBranchPipeline(indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha); + indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha); } else // if (app_angle > (THRESH_ANGLE_FOR_BILLBOARD + BLEND_RANGE_FOR_BILLBOARD)) { @@ -240,20 +272,10 @@ void LLDrawPoolTree::renderTree(BOOL selecting) // //stop_depth = (app_angle < THRESH_ANGLE_FOR_RECURSION_REDUCTION); LLFacePool::LLOverrideFaceColor clr(this, color); - indices_drawn += treep->drawBranchPipeline(indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha); + indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha); } - glPopMatrix(); - } - } - - if (mTexturep) - { - if (mTexturep->getClampS()) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - } - if (mTexturep->getClampT()) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + //glPopMatrix(); } } @@ -289,7 +311,3 @@ LLColor3 LLDrawPoolTree::getDebugColor() const return LLColor3(1.f, 0.f, 1.f); } -S32 LLDrawPoolTree::getMaterialAttribIndex() -{ - return gObjectSimpleProgram.mAttribute[LLShaderMgr::MATERIAL_COLOR]; -} diff --git a/linden/indra/newview/lldrawpooltree.h b/linden/indra/newview/lldrawpooltree.h index bf18b65..151e4ab 100644 --- a/linden/indra/newview/lldrawpooltree.h +++ b/linden/indra/newview/lldrawpooltree.h @@ -55,14 +55,13 @@ public: /*virtual*/ void beginRenderPass( S32 pass ); /*virtual*/ void render(S32 pass = 0); /*virtual*/ void endRenderPass( S32 pass ); + /*virtual*/ S32 getNumPasses() { return 1; } /*virtual*/ void renderForSelect(); /*virtual*/ BOOL verify() const; /*virtual*/ LLViewerImage *getTexture(); /*virtual*/ LLViewerImage *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display - virtual S32 getMaterialAttribIndex(); - static S32 sDiffTex; private: diff --git a/linden/indra/newview/lldrawpoolwater.cpp b/linden/indra/newview/lldrawpoolwater.cpp index e796d56..ed0077a 100644 --- a/linden/indra/newview/lldrawpoolwater.cpp +++ b/linden/indra/newview/lldrawpoolwater.cpp @@ -51,12 +51,16 @@ #include "llworld.h" #include "pipeline.h" #include "llglslshader.h" +#include "llwaterparammanager.h" const LLUUID WATER_TEST("2bfd3884-7e27-69b9-ba3a-3e673f680004"); static float sTime; BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE; +BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE; +LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f); +LLVector3 LLDrawPoolWater::sLightDir; LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER) @@ -70,7 +74,8 @@ LLDrawPoolWater::LLDrawPoolWater() : mHBTex[1]->setClamp(TRUE, TRUE); mWaterImagep = gImageList.getImage(WATER_TEST); - mWaterNormp = gImageList.getImage(LLUUID(gViewerArt.getString("water_normal.tga"))); + //mWaterNormp = gImageList.getImage(LLUUID(gViewerArt.getString("water_normal.tga"))); + mWaterNormp = gImageList.getImage(LLWaterParamManager::instance()->getNormalMapID()); restoreGL(); } @@ -94,12 +99,25 @@ LLDrawPool *LLDrawPoolWater::instancePool() void LLDrawPoolWater::prerender() { - mVertexShaderLevel = (gSavedSettings.getBOOL("RenderRippleWater") && gGLManager.mHasCubeMap && gFeatureManagerp->isFeatureAvailable("RenderCubeMap")) ? - LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_ENVIRONMENT) : 0; + mVertexShaderLevel = (gGLManager.mHasCubeMap && gFeatureManagerp->isFeatureAvailable("RenderCubeMap")) ? + LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_WATER) : 0; + + // got rid of modulation by light color since it got a little too + // green at sunset and sl-57047 (underwater turns black at 8:00) + sWaterFogColor = LLWaterParamManager::instance()->getFogColor(); + sWaterFogColor.mV[3] = 0; } -extern LLColor4U MAX_WATER_COLOR; +S32 LLDrawPoolWater::getNumPasses() +{ + if (gCamera->getOrigin().mV[2] < 1024.f) + { + return 1; + } + + return 0; +} void LLDrawPoolWater::render(S32 pass) { @@ -121,18 +139,12 @@ void LLDrawPoolWater::render(S32 pass) LLGLEnable blend(GL_BLEND); - if ((mVertexShaderLevel >= SHADER_LEVEL_RIPPLE)) + if ((mVertexShaderLevel > 0) && !sSkipScreenCopy) { shade(); return; } - if ((mVertexShaderLevel > 0)) - { - renderShaderSimple(); - return; - } - LLVOSky *voskyp = gSky.mVOSkyp; stop_glerror(); @@ -229,9 +241,9 @@ void LLDrawPoolWater::render(S32 pass) glClientActiveTextureARB(GL_TEXTURE1_ARB); glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_2D); // Texture unit 1 - LLImageGL::unbindTexture(1, GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); //texture unit 1 glDisable(GL_TEXTURE_GEN_T); //texture unit 1 + LLImageGL::unbindTexture(1, GL_TEXTURE_2D); // Disable texture coordinate and color arrays glClientActiveTextureARB(GL_TEXTURE0_ARB); @@ -259,17 +271,6 @@ void LLDrawPoolWater::render(S32 pass) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - /*glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);*/ - for (std::vector::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { @@ -315,153 +316,6 @@ void LLDrawPoolWater::render(S32 pass) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } - -void LLDrawPoolWater::renderShaderSimple() -{ - LLVOSky *voskyp = gSky.mVOSkyp; - - stop_glerror(); - - if (!gGLManager.mHasMultitexture) - { - // Ack! No multitexture! Bail! - return; - } - - LLFace* refl_face = voskyp->getReflFace(); - - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - - LLGLDisable cullFace(GL_CULL_FACE); - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - // Set up second pass first - S32 bumpTex = gWaterProgram.enableTexture(LLShaderMgr::BUMP_MAP); - mWaterImagep->addTextureStats(1024.f*1024.f); - mWaterImagep->bind(bumpTex); - - glClientActiveTextureARB(GL_TEXTURE1_ARB); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - - LLVector3 camera_up = gCamera->getUpAxis(); - F32 up_dot = camera_up * LLVector3::z_axis; - - LLColor4 water_color; - if (gCamera->cameraUnderWater()) - { - water_color.setVec(1.f, 1.f, 1.f, 0.4f); - } - else - { - water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); - } - - glColor4fv(water_color.mV); - - // Automatically generate texture coords for detail map - glActiveTextureARB(GL_TEXTURE1_ARB); - glEnable(GL_TEXTURE_GEN_S); //texture unit 1 - glEnable(GL_TEXTURE_GEN_T); //texture unit 1 - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - - // Slowly move over time. - F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f); - F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f}; - F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f}; - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); - - glClientActiveTextureARB(GL_TEXTURE0_ARB); - glActiveTextureARB(GL_TEXTURE0_ARB); - - glClearStencil(1); - glClear(GL_STENCIL_BUFFER_BIT); - LLGLEnable gls_stencil(GL_STENCIL_TEST); - glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); - glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); - - S32 envTex = -1; - - if (gSky.mVOSkyp->getCubeMap()) - { - envTex = gWaterProgram.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); - gSky.mVOSkyp->getCubeMap()->bind(); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - LLMatrix4 camera_mat = gCamera->getModelview(); - LLMatrix4 camera_rot(camera_mat.getMat3()); - camera_rot.invert(); - - glLoadMatrixf((F32 *)camera_rot.mMatrix); - - glMatrixMode(GL_MODELVIEW); - } - - S32 diffTex = gWaterProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP); - - gWaterProgram.bind(); - - for (std::vector::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace *face = *iter; - if (voskyp->isReflFace(face)) - { - continue; - } - face->bindTexture(diffTex); - face->renderIndexed(); - mIndicesDrawn += face->getIndicesCount(); - } - - if (gSky.mVOSkyp->getCubeMap()) - { - gWaterProgram.disableTexture(LLShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - } - - // Now, disable texture coord generation on texture state 1 - gWaterProgram.disableTexture(LLShaderMgr::BUMP_MAP); - LLImageGL::unbindTexture(bumpTex, GL_TEXTURE_2D); - - glActiveTextureARB(GL_TEXTURE1_ARB); - glDisable(GL_TEXTURE_GEN_S); //texture unit 1 - glDisable(GL_TEXTURE_GEN_T); //texture unit 1 - - gWaterProgram.disableTexture(LLShaderMgr::DIFFUSE_MAP); - - // Disable texture coordinate and color arrays - LLImageGL::unbindTexture(diffTex, GL_TEXTURE_2D); - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - stop_glerror(); - - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - - glUseProgramObjectARB(0); - gPipeline.disableLights(); - - glActiveTextureARB(GL_TEXTURE0_ARB); - glClientActiveTextureARB(GL_TEXTURE0_ARB); - glEnable(GL_TEXTURE_2D); - - if (refl_face) - { - glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF); - renderReflection(refl_face); - } - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); -} - void LLDrawPoolWater::renderReflection(LLFace* face) { LLVOSky *voskyp = gSky.mVOSkyp; @@ -500,47 +354,33 @@ void LLDrawPoolWater::shade() { glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); - static LLVector2 d1( 0.5f, -0.17f ); - static LLVector2 d2( 0.58f, -0.67f ); - static LLVector2 d3( 0.5f, 0.25f ); - - static LLVector3 wave1(1,0.42f,1); - static LLVector3 wave2(0.58f,0.42f,0.17f); - static LLVector3 wave3(0.42f,0.67f,0.33f); - - /*static LLVector2 d1( 0.83f, -1 ); - static LLVector2 d2( 0.58f, 1 ); - static LLVector2 d3( 1, -0.88f ); - - static LLVector4 wave1(0.75f,0.08f,0.5f,0.67f); - static LLVector4 wave2(0.17f,0.33f,0.53f,0.62f); - static LLVector4 wave3(0.17f,0.6f,0.67f,1);*/ - - /*LLDebugVarMessageBox::show("Wave Direction 1", &d1, LLVector2(1,1), LLVector2(0.01f, 0.01f)); - LLDebugVarMessageBox::show("Wave Direction 2", &d2, LLVector2(1,1), LLVector2(0.01f, 0.01f)); - LLDebugVarMessageBox::show("Wave Direction 3", &d3, LLVector2(1,1), LLVector2(0.01f, 0.01f)); - - LLDebugVarMessageBox::show("Wave 1", &wave1, LLVector3(2,1,4), LLVector3(0.01f, 0.01f, 0.01f)); - LLDebugVarMessageBox::show("Wave 2", &wave2, LLVector3(2,1,4), LLVector3(0.01f, 0.01f, 0.01f)); - LLDebugVarMessageBox::show("Wave 3", &wave3, LLVector3(2,1,4), LLVector3(0.01f, 0.01f, 0.01f));*/ - LLVOSky *voskyp = gSky.mVOSkyp; + if(voskyp == NULL) + { + return; + } + glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); + LLGLDisable blend(GL_BLEND); LLColor3 light_diffuse(0,0,0); F32 light_exp = 0.0f; LLVector3 light_dir; + LLColor3 light_color; if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS) { light_dir = gSky.getSunDirection(); - light_dir.normVec(); - light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); - light_diffuse.normVec(); + light_dir.normVec(); + light_color = gSky.getSunDiffuseColor(); + if(gSky.mVOSkyp) { + light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); + light_diffuse.normVec(); + } light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); light_diffuse *= light_exp + 0.25f; } @@ -548,6 +388,7 @@ void LLDrawPoolWater::shade() { light_dir = gSky.getMoonDirection(); light_dir.normVec(); + light_color = gSky.getMoonDiffuseColor(); light_diffuse = gSky.mVOSkyp->getMoon().getColorCached(); light_diffuse.normVec(); light_diffuse *= 0.5f; @@ -558,57 +399,112 @@ void LLDrawPoolWater::shade() light_exp *= light_exp; light_exp *= light_exp; light_exp *= light_exp; - light_exp *= light_exp; - light_exp *= 512.f; + light_exp *= 256.f; light_exp = light_exp > 32.f ? light_exp : 32.f; - sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; - - LLCubeMap* skyMap = gSky.mVOSkyp->getCubeMap(); - - gWaterProgram.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); + LLGLSLShader* shader; - if (skyMap) + F32 eyedepth = gCamera->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight(); + + if (eyedepth < 0.f && LLPipeline::sWaterReflections) { - skyMap->bind(); + shader = &gUnderWaterProgram; } else { - llwarns << "NULL gSky.mVOSkyp->getCubeMap(), not binding." << llendl; + shader = &gWaterProgram; } + sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; + + S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX); + + if (reftex > -1) + { + glActiveTextureARB(GL_TEXTURE0_ARB+reftex); + gPipeline.mWaterRef.bindTexture(); + glActiveTextureARB(GL_TEXTURE0_ARB); + } + //bind normal map - S32 bumpTex = gWaterProgram.enableTexture(LLShaderMgr::BUMP_MAP); + S32 bumpTex = shader->enableTexture(LLShaderMgr::BUMP_MAP); + + LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + + // change mWaterNormp if needed + if (mWaterNormp->getID() != param_mgr->getNormalMapID()) + { + mWaterNormp = gImageList.getImage(param_mgr->getNormalMapID()); + } + mWaterNormp->addTextureStats(1024.f*1024.f); mWaterNormp->bind(bumpTex); - - gWaterProgram.enableTexture(LLShaderMgr::WATER_SCREENTEX); - - gWaterProgram.bind(); - - if (!sSkipScreenCopy) + if (!gSavedSettings.getBOOL("RenderWaterMipNormal")) { - gPipeline.bindScreenToTexture(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } else { - glBindTexture(GL_TEXTURE_2D, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } - glUniform2fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_FBSCALE], 1, - gPipeline.mScreenScale.mV); + S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX); + stop_glerror(); + + shader->bind(); - S32 diffTex = gWaterProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP); + if (screentex > -1) + { + shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); + shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, + param_mgr->getFogDensity()); + } - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + gPipeline.mWaterDis.bindTexture(); - glUniform1fARB(gWaterProgram.mUniform[LLShaderMgr::WATER_TIME], sTime); - glUniform3fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_SPECULAR], 1, light_diffuse.mV); - glUniform1fARB(gWaterProgram.mUniform[LLShaderMgr::WATER_SPECULAR_EXP], light_exp); - glUniform3fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_EYEVEC], 1, (GLfloat *)(gCamera->getOrigin().mV)); - glUniform2fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_WAVE_DIR1], 1, d1.mV); - glUniform2fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_WAVE_DIR2], 1, d2.mV); - glUniform3fvARB(gWaterProgram.mUniform[LLShaderMgr::WATER_LIGHT_DIR], 1, light_dir.mV); + if (mVertexShaderLevel == 1) + { + sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue; + shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); + } + + F32 screenRes[] = + { + 1.f/gGLViewport[2], + 1.f/gGLViewport[3] + }; + shader->uniform2fv("screenRes", 1, screenRes); + stop_glerror(); + + S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP); + stop_glerror(); + + light_dir.normVec(); + sLightDir = light_dir; + + light_diffuse *= 6.f; + + //shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix); + shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth); + shader->uniform1f(LLShaderMgr::WATER_TIME, sTime); + shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, gCamera->getOrigin().mV); + shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); + shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV); + shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); + + shader->uniform3fv("normScale", 1, param_mgr->getNormalScale().mV); + shader->uniform1f("fresnelScale", param_mgr->getFresnelScale()); + shader->uniform1f("fresnelOffset", param_mgr->getFresnelOffset()); + shader->uniform1f("blurMultiplier", param_mgr->getBlurMultiplier()); + + F32 sunAngle = llmax(0.f, light_dir.mV[2]); + F32 scaledAngle = 1.f - sunAngle; + + shader->uniform1f("sunAngle", sunAngle); + shader->uniform1f("scaledAngle", scaledAngle); + shader->uniform1f("sunAngle2", 0.1f + 0.2f*sunAngle); LLColor4 water_color; LLVector3 camera_up = gCamera->getUpAxis(); @@ -616,13 +512,14 @@ void LLDrawPoolWater::shade() if (gCamera->cameraUnderWater()) { water_color.setVec(1.f, 1.f, 1.f, 0.4f); - glUniform1fARB(gWaterProgram.mUniform[LLShaderMgr::WATER_REFSCALE], 0.25f); + shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow()); } else { water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); - glUniform1fARB(gWaterProgram.mUniform[LLShaderMgr::WATER_REFSCALE], 0.01f); + shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove()); } + if (water_color.mV[3] > 0.9f) { water_color.mV[3] = 0.9f; @@ -642,24 +539,46 @@ void LLDrawPoolWater::shade() continue; } + LLVOWater* water = (LLVOWater*) face->getViewerObject(); face->bindTexture(diffTex); - face->renderIndexed(); + + sNeedsReflectionUpdate = TRUE; + + if (water->getUseTexture()) + { + face->renderIndexed(); + } + else + { //smash background faces to far clip plane + if (water->getIsEdgePatch()) + { + LLGLClampToFarClip far_clip(glh_get_current_projection()); + face->renderIndexed(); + } + else + { + face->renderIndexed(); + } + } + mIndicesDrawn += face->getIndicesCount(); } } - gWaterProgram.disableTexture(LLShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); - gWaterProgram.disableTexture(LLShaderMgr::WATER_SCREENTEX); - gWaterProgram.disableTexture(LLShaderMgr::BUMP_MAP); - gWaterProgram.disableTexture(LLShaderMgr::DIFFUSE_MAP); + shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); + shader->disableTexture(LLShaderMgr::WATER_SCREENTEX); + shader->disableTexture(LLShaderMgr::BUMP_MAP); + shader->disableTexture(LLShaderMgr::DIFFUSE_MAP); + shader->disableTexture(LLShaderMgr::WATER_REFTEX); + shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH); + shader->unbind(); glActiveTextureARB(GL_TEXTURE0_ARB); - glEnable(GL_TEXTURE_2D); - glUseProgramObjectARB(0); - glClientActiveTextureARB(GL_TEXTURE0_ARB); glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glEnable(GL_TEXTURE_2D); glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); + } void LLDrawPoolWater::renderForSelect() diff --git a/linden/indra/newview/lldrawpoolwater.h b/linden/indra/newview/lldrawpoolwater.h index b6569ee..45cefac 100644 --- a/linden/indra/newview/lldrawpoolwater.h +++ b/linden/indra/newview/lldrawpoolwater.h @@ -49,6 +49,11 @@ protected: const LLWaterSurface *mWaterSurface; public: static BOOL sSkipScreenCopy; + static BOOL sNeedsReflectionUpdate; + static LLVector3 sLightDir; + + static LLColor4 sWaterFogColor; + enum { VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | @@ -58,17 +63,13 @@ public: virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } - enum - { - SHADER_LEVEL_RIPPLE = 2, - }; - LLDrawPoolWater(); /*virtual*/ ~LLDrawPoolWater(); /*virtual*/ LLDrawPool *instancePool(); static void restoreGL(); + /*virtual*/ S32 getNumPasses(); /*virtual*/ void render(S32 pass = 0); /*virtual*/ void renderFaceSelected(LLFace *facep, LLImageGL *image, const LLColor4 &color, const S32 index_offset = 0, const S32 index_count = 0); @@ -80,9 +81,6 @@ public: void renderReflection(LLFace* face); void shade(); - void renderShaderSimple(); - - virtual S32 getMaterialAttribIndex() { return 0; } }; void cgErrorCallback(); diff --git a/linden/indra/newview/lldrawpoolwlsky.cpp b/linden/indra/newview/lldrawpoolwlsky.cpp new file mode 100644 index 0000000..65d1d20 --- /dev/null +++ b/linden/indra/newview/lldrawpoolwlsky.cpp @@ -0,0 +1,343 @@ +/** + * @file lldrawpoolwlsky.cpp + * @brief LLDrawPoolWLSky class implementation + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lldrawpoolwlsky.h" + +#include "llerror.h" +#include "llgl.h" +#include "pipeline.h" +#include "llviewercamera.h" +#include "llimage.h" +#include "llwlparammanager.h" +#include "llsky.h" +#include "llvowlsky.h" +#include "llagent.h" +#include "llviewerregion.h" +#include "llface.h" +#include "llglimmediate.h" + +LLPointer LLDrawPoolWLSky::sCloudNoiseTexture = NULL; + +LLPointer LLDrawPoolWLSky::sCloudNoiseRawImage = NULL; + + + +LLDrawPoolWLSky::LLDrawPoolWLSky(void) : + LLDrawPool(POOL_WL_SKY) +{ + const LLString cloudNoiseFilename(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", "clouds2.tga")); + llinfos << "loading WindLight cloud noise from " << cloudNoiseFilename << llendl; + + LLPointer cloudNoiseFile(LLImageFormatted::createFromExtension(cloudNoiseFilename)); + + if(cloudNoiseFile.isNull()) { + llerrs << "Error: Failed to load cloud noise image " << cloudNoiseFilename << llendl; + } + + cloudNoiseFile->load(cloudNoiseFilename); + + sCloudNoiseRawImage = new LLImageRaw(); + + cloudNoiseFile->decode(sCloudNoiseRawImage); + + LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE); + + LLWLParamManager::instance()->propagateParameters(); +} + +LLDrawPoolWLSky::~LLDrawPoolWLSky() +{ + //llinfos << "destructing wlsky draw pool." << llendl; + sCloudNoiseTexture = 0; +} + +LLViewerImage *LLDrawPoolWLSky::getDebugTexture() +{ + return NULL; +} + +void LLDrawPoolWLSky::beginRenderPass( S32 pass ) +{ +} + +void LLDrawPoolWLSky::endRenderPass( S32 pass ) +{ +} + +void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) const +{ + LLVector3 const & origin = gCamera->getOrigin(); + + llassert_always(NULL != shader); + + glPushMatrix(); + + //chop off translation + if (LLPipeline::sReflectionRender && origin.mV[2] > 256.f) + { + glTranslatef(origin.mV[0], origin.mV[1], 256.f-origin.mV[2]*0.5f); + } + else + { + glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]); + } + + + // the windlight sky dome works most conveniently in a coordinate system + // where Y is up, so permute our basis vectors accordingly. + glRotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3); + + glScalef(0.333f, 0.333f, 0.333f); + + glTranslatef(0.f,-camHeightLocal, 0.f); + + // Draw WL Sky + shader->uniform3f("camPosLocal", 0.f, camHeightLocal, 0.f); + + gSky.mVOWLSkyp->drawDome(); + + glPopMatrix(); +} + +void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const +{ + if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) + { + LLGLSLShader* shader = + LLPipeline::sUnderWaterRender ? + &gObjectSimpleWaterProgram : + &gWLSkyProgram; + + LLGLDisable blend(GL_BLEND); + + shader->bind(); + + /// Render the skydome + renderDome(camHeightLocal, shader); + + shader->unbind(); + } +} + +void LLDrawPoolWLSky::renderStars(void) const +{ + LLGLSPipelineSkyBox gls_sky; + LLGLEnable blend(GL_BLEND); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // *NOTE: have to have bound the cloud noise texture already since register + // combiners blending below requires something to be bound + // and we might as well only bind once. + //LLGLEnable gl_texture_2d(GL_TEXTURE_2D); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + + gPipeline.disableLights(); + + if (!LLPipeline::sReflectionRender) + { + glPointSize(2.f); + } + + // *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid + // clamping and allow the star_alpha param to brighten the stars. + bool error; + LLColor4 star_alpha(LLColor4::black); + star_alpha.mV[3] = LLWLParamManager::instance()->mCurParams.getFloat("star_brightness", error) / 2.f; + llassert_always(!error); + + // gl_FragColor.rgb = gl_Color.rgb; + // gl_FragColor.a = gl_Color.a * star_alpha.a; + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_CONSTANT); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA); + glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 2.0f); + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, star_alpha.mV); + + gSky.mVOWLSkyp->drawStars(); + + glPointSize(1.f); + + // and disable the combiner states + glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0f); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +} + +void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const +{ + if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS)) + { + LLGLSLShader* shader = + LLPipeline::sUnderWaterRender ? + &gObjectSimpleWaterProgram : + &gWLCloudProgram; + + LLGLEnable blend(GL_BLEND); + LLGLSBlendFunc blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glAlphaFunc(GL_GREATER, 0.01f); + + sCloudNoiseTexture->bind(); + shader->bind(); + + /// Render the skydome + renderDome(camHeightLocal, shader); + + shader->unbind(); + } +} + +void LLDrawPoolWLSky::renderHeavenlyBodies() +{ + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + LLGLSPipelineSkyBox gls_skybox; + LLGLEnable blend_on(GL_BLEND); + gPipeline.disableLights(); + +#if 0 // when we want to re-add a texture sun disc, here's where to do it. + LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN]; + if (gSky.mVOSkyp->getSun().getDraw() && face->getGeomCount()) + { + LLImageGL * tex = face->getTexture(); + tex->bind(); + LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor()); + LLFacePool::LLOverrideFaceColor color_override(this, color); + face->renderIndexed(); + mIndicesDrawn += face->getIndicesCount(); + } +#endif + + LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]; + + if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount()) + { + // *NOTE: even though we already bound this texture above for the + // stars register combiners, we bind again here for defensive reasons, + // since LLImageGL::bind detects that it's a noop, and optimizes it out. + LLImageGL * tex = face->getTexture(); + tex->bind(); + LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor()); + F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2]; + if (a > 0.f) + { + a = a*a*4.f; + } + + color.mV[3] = llclamp(a, 0.f, 1.f); + + LLFacePool::LLOverrideFaceColor color_override(this, color); + face->renderIndexed(); + mIndicesDrawn += face->getIndicesCount(); + } + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +void LLDrawPoolWLSky::render(S32 pass) +{ + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) + { + return; + } + LLFastTimer ftm(LLFastTimer::FTM_RENDER_WL_SKY); + + const F32 camHeightLocal = LLWLParamManager::instance()->getDomeOffset() * LLWLParamManager::instance()->getDomeRadius(); + + LLGLSNoFog disableFog; + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + LLGLDisable clip(GL_CLIP_PLANE0); + + LLGLClampToFarClip far_clip(glh_get_current_projection()); + + renderSkyHaze(camHeightLocal); + + LLVector3 const & origin = gCamera->getOrigin(); + glPushMatrix(); + + glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]); + + // *NOTE: have to bind a texture here since register combiners blending in + // renderStars() requires something to be bound and we might as well only + // bind the moon's texture once. + LLImageGL * tex = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture(); + tex->bind(); + + renderHeavenlyBodies(); + + renderStars(); + + + glPopMatrix(); + + renderSkyClouds(camHeightLocal); + + LLImageGL::unbindTexture(0); +} + +void LLDrawPoolWLSky::prerender() +{ + //llinfos << "wlsky prerendering pass." << llendl; +} + +LLDrawPoolWLSky *LLDrawPoolWLSky::instancePool() +{ + return new LLDrawPoolWLSky(); +} + +LLViewerImage* LLDrawPoolWLSky::getTexture() +{ + return NULL; +} + +void LLDrawPoolWLSky::resetDrawOrders() +{ +} + +//static +void LLDrawPoolWLSky::cleanupGL() +{ + sCloudNoiseTexture = NULL; +} + +//static +void LLDrawPoolWLSky::restoreGL() +{ + LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE); +} diff --git a/linden/indra/newview/lldrawpoolwlsky.h b/linden/indra/newview/lldrawpoolwlsky.h new file mode 100644 index 0000000..0f6bcc3 --- /dev/null +++ b/linden/indra/newview/lldrawpoolwlsky.h @@ -0,0 +1,84 @@ +/** + * @file lldrawpoolwlsky.h + * @brief LLDrawPoolWLSky class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_DRAWPOOLWLSKY_H +#define LL_DRAWPOOLWLSKY_H + +#include "lldrawpool.h" + +class LLGLSLShader; + +class LLDrawPoolWLSky : public LLDrawPool { +public: + + static const U32 SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_TEXCOORD; + static const U32 STAR_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_COLOR; + + LLDrawPoolWLSky(void); + /*virtual*/ ~LLDrawPoolWLSky(); + + /*virtual*/ BOOL isDead() { return FALSE; } + + /*virtual*/ LLViewerImage *getDebugTexture(); + /*virtual*/ void beginRenderPass( S32 pass ); + /*virtual*/ void endRenderPass( S32 pass ); + /*virtual*/ S32 getNumPasses() { return 1; } + /*virtual*/ void render(S32 pass = 0); + /*virtual*/ void prerender(); + /*virtual*/ U32 getVertexDataMask() { return SKY_VERTEX_DATA_MASK; } + /*virtual*/ BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct! + /*virtual*/ S32 getVertexShaderLevel() const { return mVertexShaderLevel; } + + //static LLDrawPool* createPool(const U32 type, LLViewerImage *tex0 = NULL); + + // Create an empty new instance of the pool. + /*virtual*/ LLDrawPoolWLSky *instancePool(); ///< covariant override + /*virtual*/ LLViewerImage* getTexture(); + /*virtual*/ BOOL isFacePool() { return FALSE; } + /*virtual*/ void resetDrawOrders(); + + static void cleanupGL(); + static void restoreGL(); +private: + void renderDome(F32 camHeightLocal, LLGLSLShader * shader) const; + void renderSkyHaze(F32 camHeightLocal) const; + void renderStars(void) const; + void renderSkyClouds(F32 camHeightLocal) const; + void renderHeavenlyBodies(); + +private: + static LLPointer sCloudNoiseTexture; + static LLPointer sCloudNoiseRawImage; +}; + +#endif // LL_DRAWPOOLWLSKY_H diff --git a/linden/indra/newview/lldynamictexture.cpp b/linden/indra/newview/lldynamictexture.cpp index aba87e2..4a47855 100644 --- a/linden/indra/newview/lldynamictexture.cpp +++ b/linden/indra/newview/lldynamictexture.cpp @@ -32,7 +32,6 @@ #include "llviewerprecompiledheaders.h" #include "lldynamictexture.h" -#include "linked_lists.h" #include "llimagegl.h" #include "llglheaders.h" #include "llviewerwindow.h" @@ -40,10 +39,13 @@ #include "llviewercontrol.h" #include "llviewerimage.h" #include "llvertexbuffer.h" +#include "llviewerdisplay.h" +#include "llglimmediate.h" +void render_ui_and_swap_if_needed(); // static -LLLinkedList LLDynamicTexture::sInstances[ LLDynamicTexture::ORDER_COUNT ]; +LLDynamicTexture::instance_list_t LLDynamicTexture::sInstances[ LLDynamicTexture::ORDER_COUNT ]; S32 LLDynamicTexture::sNumRenders = 0; //----------------------------------------------------------------------------- @@ -62,7 +64,7 @@ LLDynamicTexture::LLDynamicTexture(S32 width, S32 height, S32 components, EOrder generateGLTexture(); llassert( 0 <= order && order < ORDER_COUNT ); - LLDynamicTexture::sInstances[ order ].addData(this); + LLDynamicTexture::sInstances[ order ].insert(this); } //----------------------------------------------------------------------------- @@ -73,7 +75,7 @@ LLDynamicTexture::~LLDynamicTexture() releaseGLTexture(); for( S32 order = 0; order < ORDER_COUNT; order++ ) { - LLDynamicTexture::sInstances[order].removeData(this); // will fail in all but one case. + LLDynamicTexture::sInstances[order].erase(this); // will fail in all but one case. } } @@ -211,20 +213,27 @@ BOOL LLDynamicTexture::updateAllInstances() BOOL result = FALSE; for( S32 order = 0; order < ORDER_COUNT; order++ ) { - for (LLDynamicTexture *dynamicTexture = LLDynamicTexture::sInstances[order].getFirstData(); - dynamicTexture; - dynamicTexture = LLDynamicTexture::sInstances[order].getNextData()) + for (instance_list_t::iterator iter = LLDynamicTexture::sInstances[order].begin(); + iter != LLDynamicTexture::sInstances[order].end(); ++iter) { + LLDynamicTexture *dynamicTexture = *iter; if (dynamicTexture->needsRender()) - { + { + render_ui_and_swap_if_needed(); + glClear(GL_DEPTH_BUFFER_BIT); + gDisplaySwapBuffers = FALSE; + + LLVertexBuffer::startRender(); + gGL.start(); + dynamicTexture->preRender(); // Must be called outside of startRender() - LLVertexBuffer::startRender(); if (dynamicTexture->render()) { result = TRUE; sNumRenders++; } + gGL.stop(); LLVertexBuffer::stopRender(); dynamicTexture->postRender(result); diff --git a/linden/indra/newview/lldynamictexture.h b/linden/indra/newview/lldynamictexture.h index 23b3c64..6069940 100644 --- a/linden/indra/newview/lldynamictexture.h +++ b/linden/indra/newview/lldynamictexture.h @@ -33,7 +33,6 @@ #define LL_LLDYNAMICTEXTURE_H #include "llgl.h" -#include "linked_lists.h" #include "llcamera.h" #include "llcoord.h" #include "llimagegl.h" @@ -84,7 +83,8 @@ protected: LLCoordGL mOrigin; LLCamera mCamera; - static LLLinkedList sInstances[ LLDynamicTexture::ORDER_COUNT ]; + typedef std::set instance_list_t; + static instance_list_t sInstances[ LLDynamicTexture::ORDER_COUNT ]; static S32 sNumRenders; }; diff --git a/linden/indra/newview/llface.cpp b/linden/indra/newview/llface.cpp index 058c506..2be82f7 100644 --- a/linden/indra/newview/llface.cpp +++ b/linden/indra/newview/llface.cpp @@ -40,9 +40,9 @@ #include "m3math.h" #include "v3color.h" -#include "lldrawpoolsimple.h" #include "lldrawpoolbump.h" #include "llgl.h" +#include "llglimmediate.h" #include "lllightconstants.h" #include "llsky.h" #include "llviewercamera.h" @@ -50,6 +50,7 @@ #include "llvosky.h" #include "llvovolume.h" #include "pipeline.h" +#include "llviewerregion.h" #define LL_MAX_INDICES_COUNT 1000000 @@ -140,19 +141,20 @@ void cylindricalProjection(LLVector2 &tc, const LLVolumeFace::VertexData &vd, co void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) { mLastUpdateTime = gFrameTimeSeconds; + mLastMoveTime = 0.f; mVSize = 0.f; - mPixelArea = 1024.f; + mPixelArea = 16.f; mState = GLOBAL; mDrawPoolp = NULL; mPoolType = 0; - mGeomIndex = -1; - // mCenterLocal - // mCenterAgent + mCenterLocal = objp->getPosition(); + mCenterAgent = drawablep->getPositionAgent(); mDistance = 0.f; mGeomCount = 0; + mGeomIndex = 0; mIndicesCount = 0; - mIndicesIndex = -1; + mIndicesIndex = 0; mTexture = NULL; mTEOffset = -1; @@ -160,7 +162,8 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) mVObjp = objp; mReferenceIndex = -1; - mAlphaFade = 0.f; + + mTextureMatrix = NULL; mFaceColor = LLColor4(1,0,0,1); @@ -182,6 +185,12 @@ void LLFace::destroy() mDrawPoolp->removeFace(this); mDrawPoolp = NULL; } + + if (mTextureMatrix) + { + delete mTextureMatrix; + mTextureMatrix = NULL; + } } @@ -216,7 +225,7 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep) gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_ALL, TRUE); } } - mGeomIndex = -1; + mGeomIndex = 0; // Add to new pool if (new_pool) @@ -260,10 +269,9 @@ void LLFace::setSize(const S32 num_vertices, const S32 num_indices) //============================================================================ -S32 LLFace::getGeometryAvatar( +U16 LLFace::getGeometryAvatar( LLStrider &vertices, LLStrider &normals, - LLStrider &binormals, LLStrider &tex_coords, LLStrider &vertex_weights, LLStrider &clothing_weights) @@ -274,56 +282,19 @@ S32 LLFace::getGeometryAvatar( { mVertexBuffer->getVertexStrider (vertices, mGeomIndex); mVertexBuffer->getNormalStrider (normals, mGeomIndex); - mVertexBuffer->getBinormalStrider (binormals, mGeomIndex); mVertexBuffer->getTexCoordStrider (tex_coords, mGeomIndex); mVertexBuffer->getWeightStrider(vertex_weights, mGeomIndex); mVertexBuffer->getClothWeightStrider(clothing_weights, mGeomIndex); } - else - { - mGeomIndex = -1; - } - - return mGeomIndex; -} -S32 LLFace::getGeometryTerrain( - LLStrider &vertices, - LLStrider &normals, - LLStrider &colors, - LLStrider &texcoords0, - LLStrider &texcoords1, - LLStrider &indicesp) -{ - LLMemType mt1(LLMemType::MTYPE_DRAWABLE); - - if (mVertexBuffer.notNull()) - { - mVertexBuffer->getVertexStrider(vertices, mGeomIndex); - mVertexBuffer->getNormalStrider(normals, mGeomIndex); - mVertexBuffer->getColorStrider(colors, mGeomIndex); - mVertexBuffer->getTexCoordStrider(texcoords0, mGeomIndex); - mVertexBuffer->getTexCoord2Strider(texcoords1, mGeomIndex); - mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); - } - else - { - mGeomIndex = -1; - } - return mGeomIndex; } -S32 LLFace::getGeometry(LLStrider &vertices, LLStrider &normals, - LLStrider &tex_coords, LLStrider &indicesp) +U16 LLFace::getGeometry(LLStrider &vertices, LLStrider &normals, + LLStrider &tex_coords, LLStrider &indicesp) { LLMemType mt1(LLMemType::MTYPE_DRAWABLE); - if (mGeomCount <= 0) - { - return -1; - } - if (mVertexBuffer.notNull()) { mVertexBuffer->getVertexStrider(vertices, mGeomIndex); @@ -338,26 +309,10 @@ S32 LLFace::getGeometry(LLStrider &vertices, LLStrider &no mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); } - else - { - mGeomIndex = -1; - } return mGeomIndex; } -S32 LLFace::getGeometryColors(LLStrider &vertices, LLStrider &normals, - LLStrider &tex_coords, LLStrider &colors, - LLStrider &indicesp) -{ - S32 res = getGeometry(vertices, normals, tex_coords, indicesp); - if (res >= 0) - { - getColors(colors); - } - return res; -} - void LLFace::updateCenterAgent() { if (mDrawablep->isActive()) @@ -372,7 +327,13 @@ void LLFace::updateCenterAgent() void LLFace::renderForSelect(U32 data_mask) { - if(mGeomIndex < 0 || mDrawablep.isNull() || mVertexBuffer.isNull()) + if(mDrawablep.isNull() || mVertexBuffer.isNull()) + { + return; + } + + LLSpatialGroup* group = mDrawablep->getSpatialGroup(); + if (!group || group->isState(LLSpatialGroup::GEOM_DIRTY)) { return; } @@ -407,7 +368,7 @@ void LLFace::renderForSelect(U32 data_mask) #if !LL_RELEASE_FOR_DOWNLOAD LLGLState::checkClientArrays(data_mask); #endif - U32* indicesp = (U32*) mVertexBuffer->getIndicesPointer() + mIndicesIndex; + U16* indicesp = (U16*) mVertexBuffer->getIndicesPointer() + mIndicesIndex; if (gPickFaces && mTEOffset != -1) { @@ -421,13 +382,23 @@ void LLFace::renderForSelect(U32 data_mask) { if (isState(GLOBAL)) { - glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_INT, indicesp); + if (mDrawablep->getVOVolume()) + { + glPushMatrix(); + glMultMatrixf((float*) mDrawablep->getRegion()->mRenderMatrix.mMatrix); + glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_SHORT, indicesp); + glPopMatrix(); + } + else + { + glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_SHORT, indicesp); + } } else { glPushMatrix(); glMultMatrixf((float*)getRenderMatrix().mMatrix); - glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_INT, indicesp); + glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_SHORT, indicesp); glPopMatrix(); } } @@ -450,7 +421,7 @@ void LLFace::renderForSelect(U32 data_mask) void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color, const S32 offset, const S32 count) { - if(mGeomIndex < 0 || mDrawablep.isNull() || mVertexBuffer.isNull()) + if(mDrawablep.isNull() || mVertexBuffer.isNull()) { return; } @@ -461,11 +432,15 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color, const S32 glColor4fv(color.mV); LLViewerImage::bindTexture(imagep); - if (!isState(GLOBAL)) + + glPushMatrix(); + if (mDrawablep->isActive()) + { + glMultMatrixf((GLfloat*)mDrawablep->getRenderMatrix().mMatrix); + } + else { - // Apply the proper transform for non-global objects. - glPushMatrix(); - glMultMatrixf((float*)getRenderMatrix().mMatrix); + glMultMatrixf((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix); } glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -476,24 +451,20 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color, const S32 #if !LL_RELEASE_FOR_DOWNLOAD LLGLState::checkClientArrays(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD); #endif - U32* indicesp = ((U32*) mVertexBuffer->getIndicesPointer()) + mIndicesIndex; + U16* indicesp = ((U16*) mVertexBuffer->getIndicesPointer()) + mIndicesIndex; if (count) { - glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, indicesp + offset); + glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indicesp + offset); } else { - glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_INT, indicesp); + glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_SHORT, indicesp); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); - if (!isState(GLOBAL)) - { - // Restore the tranform for non-global objects - glPopMatrix(); - } + glPopMatrix(); } } @@ -507,8 +478,7 @@ void LLFace::renderSelectedUV(const S32 offset, const S32 count) LLGLSObjectSelect object_select; LLGLEnable blend(GL_BLEND); - LLGLEnable texture(GL_TEXTURE_2D); - + if (!mDrawPoolp || !getIndicesCount() || getIndicesStart() < 0) { return; @@ -519,7 +489,7 @@ void LLFace::renderSelectedUV(const S32 offset, const S32 count) static F32 factor = -10.f; if (mGeomCount > 0) { - glColor4fv(LLColor4::white.mV); + gGL.color4fv(LLColor4::white.mV); if (pass == 0) { @@ -527,7 +497,7 @@ void LLFace::renderSelectedUV(const S32 offset, const S32 count) } else // pass == 1 { - glBlendFunc(GL_ONE, GL_ONE); + gGL.blendFunc(GL_ONE, GL_ONE); LLViewerImage::bindTexture(green_imagep); glMatrixMode(GL_TEXTURE); glPushMatrix(); @@ -549,15 +519,15 @@ void LLFace::renderSelectedUV(const S32 offset, const S32 count) glPolygonOffset(factor, bias); if (sSafeRenderSelect) { - glBegin(GL_TRIANGLES); + gGL.begin(GL_TRIANGLES); if (count) { for (S32 i = offset; i < offset + count; i++) { LLVector2 tc = mDrawPoolp->getTexCoord(mDrawPoolp->getIndex(getIndicesStart() + i), 0); - glTexCoord2fv(tc.mV); + gGL.texCoord2fv(tc.mV); LLVector3 vertex = mDrawPoolp->getVertex(mDrawPoolp->getIndex(getIndicesStart() + i)); - glVertex3fv(vertex.mV); + gGL.vertex3fv(vertex.mV); } } else @@ -565,12 +535,12 @@ void LLFace::renderSelectedUV(const S32 offset, const S32 count) for (U32 i = 0; i < getIndicesCount(); i++) { LLVector2 tc = mDrawPoolp->getTexCoord(mDrawPoolp->getIndex(getIndicesStart() + i), 0); - glTexCoord2fv(tc.mV); + gGL.texCoord2fv(tc.mV); LLVector3 vertex = mDrawPoolp->getVertex(mDrawPoolp->getIndex(getIndicesStart() + i)); - glVertex3fv(vertex.mV); + gGL.vertex3fv(vertex.mV); } } - glEnd(); + gGL.end(); } else { @@ -581,7 +551,7 @@ void LLFace::renderSelectedUV(const S32 offset, const S32 count) { if (mIndicesCount > 0) { - glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, getRawIndices() + offset); + glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, getRawIndices() + offset); } else { @@ -593,7 +563,7 @@ void LLFace::renderSelectedUV(const S32 offset, const S32 count) { if (mIndicesCount > 0) { - glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_INT, getRawIndices()); + glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_SHORT, getRawIndices()); } else { @@ -614,13 +584,13 @@ void LLFace::renderSelectedUV(const S32 offset, const S32 count) glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(GL_MODELVIEW); - glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); + gGL.blendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); } } } //restore blend func - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); #endif } @@ -804,34 +774,51 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, } } + if (!mDrawablep->isActive()) + { + LLVector3 offset = mDrawablep->getRegion()->getOriginAgent(); + newMin += offset; + newMax += offset; + } + mCenterLocal = (newMin+newMax)*0.5f; + updateCenterAgent(); } return TRUE; } - BOOL LLFace::getGeometryVolume(const LLVolume& volume, - S32 f, - LLStrider& vertices, - LLStrider& normals, - LLStrider& tex_coords, - LLStrider& tex_coords2, - LLStrider& colors, - LLStrider& indicesp, + const S32 &f, const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, - U32& index_offset) + const U16 &index_offset) { const LLVolumeFace &vf = volume.getVolumeFace(f); S32 num_vertices = (S32)vf.mVertices.size(); S32 num_indices = (S32)vf.mIndices.size(); - LLStrider old_verts; - LLStrider old_texcoords; - LLStrider old_texcoords2; - LLStrider old_normals; - LLStrider old_colors; + if (mVertexBuffer.notNull()) + { + if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices()) + { + llwarns << "Index buffer overflow!" << llendl; + return FALSE; + } + + if (num_vertices + mGeomIndex > mVertexBuffer->getNumVerts()) + { + llwarns << "Vertex buffer overflow!" << llendl; + return FALSE; + } + } + + LLStrider old_verts,vertices; + LLStrider old_texcoords,tex_coords; + LLStrider old_texcoords2,tex_coords2; + LLStrider old_normals,normals; + LLStrider old_colors,colors; + LLStrider indicesp; BOOL full_rebuild = mDrawablep->isState(LLDrawable::REBUILD_VOLUME); BOOL moved = TRUE; @@ -859,91 +846,49 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { //data is in same location in vertex buffer moved = FALSE; } - + if (!moved && !mDrawablep->isState(LLDrawable::REBUILD_ALL)) { //nothing needs to be done - vertices += mGeomCount; - normals += mGeomCount; - tex_coords += mGeomCount; - colors += mGeomCount; - tex_coords2 += mGeomCount; - index_offset += mGeomCount; - indicesp += mIndicesCount; return FALSE; } - - if (mLastGeomCount == mGeomCount) - { - if (mLastGeomIndex >= mGeomIndex && - mLastGeomIndex + mGeomCount+1 < mVertexBuffer->getNumVerts()) - { - //copy from further down the buffer - mVertexBuffer->getVertexStrider(old_verts, mLastGeomIndex); - mVertexBuffer->getTexCoordStrider(old_texcoords, mLastGeomIndex); - mVertexBuffer->getTexCoord2Strider(old_texcoords2, mLastGeomIndex); - mVertexBuffer->getNormalStrider(old_normals, mLastGeomIndex); - mVertexBuffer->getColorStrider(old_colors, mLastGeomIndex); - - if (!mDrawablep->isState(LLDrawable::REBUILD_ALL)) - { - //quick copy - for (S32 i = 0; i < mGeomCount; i++) - { - *vertices++ = *old_verts++; - *tex_coords++ = *old_texcoords++; - *tex_coords2++ = *old_texcoords2++; - *colors++ = *old_colors++; - *normals++ = *old_normals++; - } - - for (U32 i = 0; i < mIndicesCount; i++) - { - *indicesp++ = vf.mIndices[i] + index_offset; - } - - index_offset += mGeomCount; - mLastGeomIndex = mGeomIndex; - mLastIndicesCount = mIndicesCount; - mLastIndicesIndex = mIndicesIndex; - - return TRUE; - } - } - else - { - full_rebuild = TRUE; - } - } - else - { - full_rebuild = TRUE; - } - } - else - { - full_rebuild = TRUE; } + mLastMoveTime = gFrameTimeSeconds; } else { mLastUpdateTime = gFrameTimeSeconds; } + + BOOL rebuild_pos = full_rebuild || moved || mDrawablep->isState(LLDrawable::REBUILD_POSITION); + BOOL rebuild_color = full_rebuild || moved || mDrawablep->isState(LLDrawable::REBUILD_COLOR); + BOOL rebuild_tcoord = full_rebuild || moved || mDrawablep->isState(LLDrawable::REBUILD_TCOORD); + const LLTextureEntry *tep = mVObjp->getTE(f); + U8 bump_code = tep ? tep->getBumpmap() : 0; - BOOL rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION); - BOOL rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR); - BOOL rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD); + if (rebuild_pos) + { + mVertexBuffer->getVertexStrider(vertices, mGeomIndex); + mVertexBuffer->getNormalStrider(normals, mGeomIndex); + } + if (rebuild_tcoord) + { + mVertexBuffer->getTexCoordStrider(tex_coords, mGeomIndex); + if (bump_code) + { + mVertexBuffer->getTexCoord2Strider(tex_coords2, mGeomIndex); + } + } + if (rebuild_color) + { + mVertexBuffer->getColorStrider(colors, mGeomIndex); + } F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; BOOL is_static = mDrawablep->isStatic(); BOOL is_global = is_static; - if (index_offset == (U32) -1) - { - return TRUE; - } - LLVector3 center_sum(0.f, 0.f, 0.f); if (is_global) @@ -957,8 +902,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLVector2 tmin, tmax; - const LLTextureEntry *tep = mVObjp->getTE(f); - U8 bump_code = tep ? tep->getBumpmap() : 0; + if (rebuild_tcoord) { @@ -983,14 +927,23 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } + U8 tex_mode = 0; + if (isState(TEXTURE_ANIM)) { - LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp; - U8 mode = vobj->mTexAnimMode; - if (!mode) + LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp; + tex_mode = vobj->mTexAnimMode; + + if (!tex_mode) { clearState(TEXTURE_ANIM); } + //else if (getVirtualSize() <= 512.f) + //{ + // //vobj->mTextureAnimp->animateTextures(os, ot, ms, mt, r); + // //cos_ang = cos(r); + // //sin_ang = sin(r); + //} else { os = ot = 0.f; @@ -999,6 +952,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, sin_ang = 0.f; ms = mt = 1.f; } + + if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) + { //don't override texture transform during tc bake + tex_mode = 0; + } } LLColor4U color = tep->getColor(); @@ -1013,7 +971,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, 0.75f }; - if (gPipeline.getPoolTypeFromTE(tep, getTexture()) == LLDrawPool::POOL_BUMP) + if (getPoolType() != LLDrawPool::POOL_ALPHA && LLPipeline::sRenderBump && tep->getShiny()) { color.mV[3] = U8 (alpha[tep->getShiny()] * 255); } @@ -1022,23 +980,28 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, // INDICES if (full_rebuild || moved) { - for (S32 i = 0; i < num_indices; i++) + mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); + for (U16 i = 0; i < num_indices; i++) { *indicesp++ = vf.mIndices[i] + index_offset; } } - else - { - indicesp += num_indices; - } + //bump setup LLVector3 binormal_dir( -sin_ang, cos_ang, 0 ); LLVector3 bump_s_primary_light_ray; LLVector3 bump_t_primary_light_ray; + + LLQuaternion bump_quat; + if (mDrawablep->isActive()) + { + bump_quat = LLQuaternion(mDrawablep->getRenderMatrix()); + } if (bump_code) { + mVObjp->getVolume()->genBinormals(f); F32 offset_multiple; switch( bump_code ) { @@ -1073,14 +1036,22 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { tep->getScale( &s_scale, &t_scale ); } - LLVector3 sun_ray = gSky.getSunDirection(); + // Use the nudged south when coming from above sun angle, such + // that emboss mapping always shows up on the upward faces of cubes when + // it's noon (since a lot of builders build with the sun forced to noon). + LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir; LLVector3 moon_ray = gSky.getMoonDirection(); LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; + bump_s_primary_light_ray = offset_multiple * s_scale * primary_light_ray; bump_t_primary_light_ray = offset_multiple * t_scale * primary_light_ray; } U8 texgen = getTextureEntry()->getTexGen(); + if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) + { //planar texgen needs binormals + mVObjp->getVolume()->genBinormals(f); + } for (S32 i = 0; i < num_vertices; i++) { @@ -1110,20 +1081,37 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - xform(tc, cos_ang, sin_ang, os, ot, ms, mt); + 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); + } + *tex_coords++ = tc; if (bump_code) { LLVector3 tangent = vf.mVertices[i].mBinormal % vf.mVertices[i].mNormal; + LLMatrix3 tangent_to_object; tangent_to_object.setRows(tangent, vf.mVertices[i].mBinormal, vf.mVertices[i].mNormal); LLVector3 binormal = binormal_dir * tangent_to_object; - binormal = binormal * mat_normal; - binormal.normVec(); + + if (mDrawablep->isActive()) + { + binormal *= bump_quat; + } + binormal.normVec(); tc += LLVector2( bump_s_primary_light_ray * tangent, bump_t_primary_light_ray * binormal ); + *tex_coords2++ = tc; } } @@ -1161,26 +1149,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - if (!rebuild_pos && !moved) - { - vertices += num_vertices; - } - - if (!rebuild_tcoord && !moved) - { - tex_coords2 += num_vertices; - tex_coords += num_vertices; - } - else if (!bump_code) - { - tex_coords2 += num_vertices; - } - - if (!rebuild_color && !moved) - { - colors += num_vertices; - } - if (rebuild_tcoord) { mTexExtents[0].setVec(0,0); @@ -1189,8 +1157,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt); } - index_offset += num_vertices; - mLastVertexBuffer = mVertexBuffer; mLastGeomCount = mGeomCount; mLastGeomIndex = mGeomIndex; @@ -1200,136 +1166,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, return TRUE; } -#if 0 -BOOL LLFace::genLighting(const LLVolume* volume, const LLDrawable* drawablep, S32 fstart, S32 fend, - const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, BOOL do_lighting) -{ - if (drawablep->isLight()) - { - do_lighting = FALSE; - } - - if (!((mDrawPoolp->mDataMaskIL) & LLDrawPool::DATA_COLORS_MASK)) - { - return FALSE; - } - if (mGeomIndex < 0) - { - return FALSE; // no geometry - } - LLStrider colorsp; - S32 idx = getColors(colorsp); - if (idx < 0) - { - return FALSE; - } - - for (S32 vol_face = fstart; vol_face <= fend; vol_face++) - { - const LLVolumeFace &vf = volume->getVolumeFace(vol_face); - S32 num_vertices = (S32)vf.mVertices.size(); - - if (isState(FULLBRIGHT) || !do_lighting) - { - for (S32 i = 0; i < num_vertices; i++) - { - (*colorsp++).setToBlack(); - } - } - else - { - for (S32 i = 0; i < num_vertices; i++) - { - LLVector3 vertex = vf.mVertices[i].mPosition * mat_vert; - LLVector3 normal = vf.mVertices[i].mNormal * mat_normal; - normal.normVec(); - - LLColor4 color; - for (LLDrawable::drawable_set_t::const_iterator iter = drawablep->mLightSet.begin(); - iter != drawablep->mLightSet.end(); ++iter) - { - LLDrawable* light_drawable = *iter; - LLVOVolume* light = light_drawable->getVOVolume(); - if (!light) - { - continue; - } - LLColor4 light_color; - light->calcLightAtPoint(vertex, normal, light_color); - color += light_color; - } - - color.mV[3] = 1.0f; - - (*colorsp++).setVecScaleClamp(color); - } - } - } - return TRUE; -} - -BOOL LLFace::genShadows(const LLVolume* volume, const LLDrawable* drawablep, S32 fstart, S32 fend, - const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, BOOL use_shadow_factor) -{ - if (drawablep->isLight()) - { - return FALSE; - } - - if (!((mDrawPoolp->mDataMaskIL) & LLDrawPool::DATA_COLORS_MASK)) - { - return FALSE; - } - if (mGeomIndex < 0) - { - return FALSE; // no geometry - } - LLStrider colorsp; - S32 idx = getColors(colorsp); - if (idx < 0) - { - return FALSE; - } - - for (S32 vol_face = fstart; vol_face <= fend; vol_face++) - { - const LLVolumeFace &vf = volume->getVolumeFace(vol_face); - S32 num_vertices = (S32)vf.mVertices.size(); - - if (isState(FULLBRIGHT)) - { - continue; - } - - for (S32 i = 0; i < num_vertices; i++) - { - LLVector3 vertex = vf.mVertices[i].mPosition * mat_vert; - LLVector3 normal = vf.mVertices[i].mNormal * mat_normal; - normal.normVec(); - - U8 shadow; - - if (use_shadow_factor) - { - shadow = (U8) (drawablep->getSunShadowFactor() * 255); - } - else - { - shadow = 255; - } - - (*colorsp++).mV[3] = shadow; - } - } - return TRUE; -} -#endif - BOOL LLFace::verify(const U32* indices_array) const { BOOL ok = TRUE; // First, check whether the face data fits within the pool's range. - if ((mGeomIndex < 0) || (mGeomIndex + mGeomCount) > mVertexBuffer->getNumVerts()) + if ((mGeomIndex + mGeomCount) > mVertexBuffer->getNumVerts()) { ok = FALSE; llinfos << "Face not within pool range!" << llendl; @@ -1385,27 +1226,6 @@ void LLFace::setViewerObject(LLViewerObject* objp) mVObjp = objp; } -void LLFace::enableLights() const -{ - if (isState(FULLBRIGHT|HUD_RENDER)) - { - gPipeline.enableLightsFullbright(LLColor4::white); - } - else if (mDrawablep->isState(LLDrawable::LIGHTING_BUILT)) - { - gPipeline.enableLightsStatic(1.f); - } - else - { - gPipeline.enableLightsDynamic(1.f); - } - if (isState(LIGHT)) - { - const LLVOVolume* vovolume = (const LLVOVolume*)mDrawablep->getVObj(); - gPipeline.setAmbient(vovolume->getLightColor()); - } -} - const LLColor4& LLFace::getRenderColor() const { if (isState(USE_FACE_COLOR)) @@ -1425,18 +1245,11 @@ void LLFace::renderSetColor() const { const LLColor4* color = &(getRenderColor()); - if ((mDrawPoolp->mVertexShaderLevel > 0) && (mDrawPoolp->getMaterialAttribIndex() != 0)) - { - glVertexAttrib4fvARB(mDrawPoolp->getMaterialAttribIndex(), color->mV); - } - else - { - glColor4fv(color->mV); - } + glColor4fv(color->mV); } } -S32 LLFace::pushVertices(const U32* index_array) const +S32 LLFace::pushVertices(const U16* index_array) const { if (mIndicesCount) { @@ -1444,14 +1257,15 @@ S32 LLFace::pushVertices(const U32* index_array) const mIndicesCount <= (U32) gGLManager.mGLMaxIndexRange) { glDrawRangeElements(GL_TRIANGLES, mGeomIndex, mGeomIndex + mGeomCount-1, mIndicesCount, - GL_UNSIGNED_INT, index_array + mIndicesIndex); + GL_UNSIGNED_SHORT, index_array + mIndicesIndex); } else { - glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_INT, index_array+mIndicesIndex); + glDrawElements(GL_TRIANGLES, mIndicesCount, GL_UNSIGNED_SHORT, index_array+mIndicesIndex); } + gPipeline.addTrianglesDrawn(mIndicesCount/3); } - + return mIndicesCount; } @@ -1460,7 +1274,7 @@ const LLMatrix4& LLFace::getRenderMatrix() const return mDrawablep->getRenderMatrix(); } -S32 LLFace::renderElements(const U32 *index_array) const +S32 LLFace::renderElements(const U16 *index_array) const { S32 ret = 0; @@ -1481,7 +1295,7 @@ S32 LLFace::renderElements(const U32 *index_array) const S32 LLFace::renderIndexed() { - if(mGeomIndex < 0 || mDrawablep.isNull() || mDrawPoolp == NULL) + if(mDrawablep.isNull() || mDrawPoolp == NULL) { return 0; } @@ -1497,28 +1311,13 @@ S32 LLFace::renderIndexed(U32 mask) } mVertexBuffer->setBuffer(mask); - U32* index_array = (U32*) mVertexBuffer->getIndicesPointer(); + U16* index_array = (U16*) mVertexBuffer->getIndicesPointer(); return renderElements(index_array); } //============================================================================ // From llface.inl -S32 LLFace::getVertices(LLStrider &vertices) -{ - if (!mGeomCount) - { - return -1; - } - - if (mGeomIndex >= 0) // flexible objects may not have geometry - { - mVertexBuffer->getVertexStrider(vertices, mGeomIndex); - - } - return mGeomIndex; -} - S32 LLFace::getColors(LLStrider &colors) { if (!mGeomCount) @@ -1526,15 +1325,15 @@ S32 LLFace::getColors(LLStrider &colors) return -1; } - llassert(mGeomIndex >= 0); + // llassert(mGeomIndex >= 0); mVertexBuffer->getColorStrider(colors, mGeomIndex); return mGeomIndex; } -S32 LLFace::getIndices(LLStrider &indicesp) +S32 LLFace::getIndices(LLStrider &indicesp) { mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); - llassert(mGeomIndex >= 0 && indicesp[0] != indicesp[1]); + llassert(indicesp[0] != indicesp[1]); return mIndicesIndex; } diff --git a/linden/indra/newview/llface.h b/linden/indra/newview/llface.h index 5336d1c..4454bd6 100644 --- a/linden/indra/newview/llface.h +++ b/linden/indra/newview/llface.h @@ -55,6 +55,9 @@ class LLVertexProgram; class LLViewerImage; class LLGeometryManager; +const F32 MIN_ALPHA_SIZE = 1024.f; +const F32 MIN_TEX_ANIM_SIZE = 512.f; + class LLFace { public: @@ -79,9 +82,9 @@ public: const LLMatrix4& getRenderMatrix() const; U32 getIndicesCount() const { return mIndicesCount; }; S32 getIndicesStart() const { return mIndicesIndex; }; - S32 getGeomCount() const { return mGeomCount; } // vertex count for this face - S32 getGeomIndex() const { return mGeomIndex; } // index into draw pool - U32 getGeomStart() const { return mGeomIndex; } // index into draw pool + U16 getGeomCount() const { return mGeomCount; } // vertex count for this face + U16 getGeomIndex() const { return mGeomIndex; } // index into draw pool + U16 getGeomStart() const { return mGeomIndex; } // index into draw pool LLViewerImage* getTexture() const { return mTexture; } void setTexture(LLViewerImage* tex) { mTexture = tex; } LLXformMatrix* getXform() const { return mXform; } @@ -98,12 +101,11 @@ public: F32 getPixelArea() const { return mPixelArea; } void bindTexture(S32 stage = 0) const { LLViewerImage::bindTexture(mTexture, stage); } - void enableLights() const; void renderSetColor() const; - S32 renderElements(const U32 *index_array) const; + S32 renderElements(const U16 *index_array) const; S32 renderIndexed (); S32 renderIndexed (U32 mask); - S32 pushVertices(const U32* index_array) const; + S32 pushVertices(const U16* index_array) const; void setWorldMatrix(const LLMatrix4& mat); const LLTextureEntry* getTextureEntry() const { return mVObjp->getTE(mTEOffset); } @@ -130,49 +132,27 @@ public: const LLColor4& getRenderColor() const; //for volumes - S32 getGeometryVolume(const LLVolume& volume, - S32 f, - LLStrider& vertices, - LLStrider& normals, - LLStrider& texcoords, - LLStrider& texcoords2, - LLStrider& colors, - LLStrider& indices, + BOOL getGeometryVolume(const LLVolume& volume, + const S32 &f, const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, - U32& index_offset); + const U16 &index_offset); // For avatar - S32 getGeometryAvatar( + U16 getGeometryAvatar( LLStrider &vertices, LLStrider &normals, - LLStrider &binormals, LLStrider &texCoords, LLStrider &vertex_weights, LLStrider &clothing_weights); - // For terrain - S32 getGeometryTerrain(LLStrider &vertices, - LLStrider &normals, - LLStrider &colors, - LLStrider &texCoords0, - LLStrider &texCoords1, - LLStrider &indices); - // For volumes, etc. - S32 getGeometry(LLStrider &vertices, + U16 getGeometry(LLStrider &vertices, LLStrider &normals, LLStrider &texCoords, - LLStrider &indices); + LLStrider &indices); - S32 getGeometryColors(LLStrider &vertices, - LLStrider &normals, - LLStrider &texCoords, - LLStrider &colors, - LLStrider &indices); - - S32 getVertices(LLStrider &vertices); S32 getColors(LLStrider &colors); - S32 getIndices(LLStrider &indices); + S32 getIndices(LLStrider &indices); void setSize(const S32 numVertices, const S32 num_indices = 0); @@ -197,7 +177,7 @@ public: BOOL verify(const U32* indices_array = NULL) const; void printDebugInfo() const; - void setGeomIndex(S32 idx) { mGeomIndex = idx; } + void setGeomIndex(U16 idx) { mGeomIndex = idx; } void setIndicesIndex(S32 idx) { mIndicesIndex = idx; } protected: @@ -208,11 +188,11 @@ public: LLVector3 mExtents[2]; LLVector2 mTexExtents[2]; F32 mDistance; - F32 mAlphaFade; LLPointer mVertexBuffer; LLPointer mLastVertexBuffer; F32 mLastUpdateTime; - LLMatrix4 mTextureMatrix; + F32 mLastMoveTime; + LLMatrix4* mTextureMatrix; protected: friend class LLGeometryManager; @@ -223,16 +203,16 @@ protected: U32 mPoolType; LLColor4 mFaceColor; // overrides material color if state |= USE_FACE_COLOR - S32 mGeomCount; // vertex count for this face - S32 mGeomIndex; // index into draw pool + U16 mGeomCount; // vertex count for this face + U16 mGeomIndex; // index into draw pool U32 mIndicesCount; - S32 mIndicesIndex; // index into draw pool for indices (yeah, I know!) + U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!) //previous rebuild's geometry info - S32 mLastGeomCount; - S32 mLastGeomIndex; + U16 mLastGeomCount; + U16 mLastGeomIndex; U32 mLastIndicesCount; - S32 mLastIndicesIndex; + U32 mLastIndicesIndex; LLXformMatrix* mXform; LLPointer mTexture; @@ -264,12 +244,34 @@ public: } }; + struct CompareBatchBreaker + { + bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) + { + const LLTextureEntry* lte = lhs->getTextureEntry(); + const LLTextureEntry* rte = rhs->getTextureEntry(); + + if (lhs->getTexture() != rhs->getTexture()) + { + return lhs->getTexture() < rhs->getTexture(); + } + else if (lte->getBumpShinyFullbright() != rte->getBumpShinyFullbright()) + { + return lte->getBumpShinyFullbright() < rte->getBumpShinyFullbright(); + } + else + { + return lte->getGlow() < rte->getGlow(); + } + } + }; + struct CompareTextureAndGeomCount { bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) { return lhs->getTexture() == rhs->getTexture() ? - lhs->getGeomCount() < rhs->getGeomCount() : + lhs->getGeomCount() < rhs->getGeomCount() : //smallest = first lhs->getTexture() > rhs->getTexture(); } }; diff --git a/linden/indra/newview/llface.inl b/linden/indra/newview/llface.inl index 2cb1654..8f8cfaf 100644 --- a/linden/indra/newview/llface.inl +++ b/linden/indra/newview/llface.inl @@ -69,87 +69,6 @@ inline LLViewerObject* LLFace::getViewerObject() const return mVObjp; } - - -inline S32 LLFace::getVertices(LLStrider &vertices) -{ - if (!mGeomCount) - { - return -1; - } - if (isState(BACKLIST)) - { - if (!mBackupMem) - { - printDebugInfo(); - llerrs << "No backup memory for face" << llendl; - } - vertices = (LLVector3*)(mBackupMem + (4 * mIndicesCount) + mDrawPoolp->mDataOffsets[LLDrawPool::DATA_VERTICES]); - vertices.setStride( mDrawPoolp->getStride()); - return 0; - } - else - { - llassert(mGeomIndex >= 0); - mDrawPoolp->getVertexStrider(vertices, mGeomIndex); - mDrawPoolp->setDirty(); - return mGeomIndex; - } -} - -inline S32 LLFace::getNormals(LLStrider &normals) -{ - if (!mGeomCount) - { - return -1; - } - if (isState(BACKLIST)) - { - if (!mBackupMem) - { - printDebugInfo(); - llerrs << "No backup memory for face" << llendl; - } - normals = (LLVector3*)(mBackupMem + (4 * mIndicesCount) + mDrawPoolp->mDataOffsets[LLDrawPool::DATA_NORMALS]); - normals.setStride( mDrawPoolp->getStride()); - return 0; - } - else - { - llassert(mGeomIndex >= 0); - mDrawPoolp->getNormalStrider(normals, mGeomIndex); - mDrawPoolp->setDirty(); - return mGeomIndex; - } -} - -inline S32 LLFace::getBinormals(LLStrider &binormals) -{ - if (!mGeomCount) - { - return -1; - } - if (isState(BACKLIST)) - { - if (!mBackupMem) - { - printDebugInfo(); - llerrs << "No backup memory for face" << llendl; - } - binormals = (LLVector3*)(mBackupMem + (4 * mIndicesCount) + mDrawPoolp->mDataOffsets[LLDrawPool::DATA_BINORMALS]); - binormals.setStride( mDrawPoolp->getStride()); - return 0; - } - else - { - llassert(mGeomIndex >= 0); - mDrawPoolp->getBinormalStrider(binormals, mGeomIndex); - mDrawPoolp->setDirty(); - return mGeomIndex; - } -} - - inline S32 LLFace::getColors (LLStrider &colors) { if (!mGeomCount) diff --git a/linden/indra/newview/llfasttimerview.cpp b/linden/indra/newview/llfasttimerview.cpp index 6364fd2..0fdbb98 100644 --- a/linden/indra/newview/llfasttimerview.cpp +++ b/linden/indra/newview/llfasttimerview.cpp @@ -37,6 +37,7 @@ #include "llrect.h" #include "llerror.h" #include "llgl.h" +#include "llglimmediate.h" #include "llmath.h" #include "llfontgl.h" @@ -56,20 +57,20 @@ static const S32 LINE_GRAPH_HEIGHT = 240; struct ft_display_info { int timer; const char *desc; - LLColor4 *color; + const LLColor4 *color; S32 disabled; // initialized to 0 int level; // calculated based on desc int parent; // calculated }; -static LLColor4 red0(0.5f, 0.0f, 0.0f, 1.0f); -static LLColor4 green0(0.0f, 0.5f, 0.0f, 1.0f); -static LLColor4 blue0(0.0f, 0.0f, 0.5f, 1.0f); -static LLColor4 blue7(0.0f, 0.0f, 0.5f, 1.0f); +static const LLColor4 red0(0.5f, 0.0f, 0.0f, 1.0f); +static const LLColor4 green0(0.0f, 0.5f, 0.0f, 1.0f); +static const LLColor4 blue0(0.0f, 0.0f, 0.5f, 1.0f); +static const LLColor4 blue7(0.0f, 0.0f, 0.5f, 1.0f); -static LLColor4 green7(0.6f, 1.0f, 0.4f, 1.0f); -static LLColor4 green8(0.4f, 1.0f, 0.6f, 1.0f); -static LLColor4 green9(0.6f, 1.0f, 0.6f, 1.0f); +static const LLColor4 green7(0.6f, 1.0f, 0.4f, 1.0f); +static const LLColor4 green8(0.4f, 1.0f, 0.6f, 1.0f); +static const LLColor4 green9(0.6f, 1.0f, 0.6f, 1.0f); // green(6), blue, yellow, orange, pink(2), cyan // red (5) magenta (4) @@ -93,40 +94,14 @@ static struct ft_display_info ft_display_table[] = { LLFastTimer::FTM_WORLD_UPDATE, " World Update", &LLColor4::blue1, 1 }, { LLFastTimer::FTM_UPDATE_MOVE, " Move Objects", &LLColor4::pink2, 0 }, { LLFastTimer::FTM_OCTREE_BALANCE, " Octree Balance", &LLColor4::red3, 0 }, -// { LLFastTimer::FTM_TEMP1, " Blur", &LLColor4::red1, 0 }, - { LLFastTimer::FTM_CULL, " Object Cull", &LLColor4::blue2, 1 }, - { LLFastTimer::FTM_CULL_REBOUND, " Rebound", &LLColor4::blue3, 0 }, - { LLFastTimer::FTM_FRUSTUM_CULL, " Frustum Cull", &LLColor4::blue4, 0 }, - { LLFastTimer::FTM_OCCLUSION, " Object Occlude", &LLColor4::pink1, 0 }, - { LLFastTimer::FTM_OCCLUSION_READBACK, " Occlusion Read", &LLColor4::red2, 0 }, - { LLFastTimer::FTM_HUD_EFFECTS, " HUD Effects", &LLColor4::orange1, 0 }, - { LLFastTimer::FTM_HUD_UPDATE, " HUD Update", &LLColor4::orange2, 0 }, - { LLFastTimer::FTM_GEO_UPDATE, " Geo Update", &LLColor4::blue3, 0 }, - { LLFastTimer::FTM_UPDATE_PRIMITIVES, " Volumes", &LLColor4::blue4, 0 }, - { LLFastTimer::FTM_GEN_VOLUME, " Gen Volume", &LLColor4::yellow3, 0 }, - { LLFastTimer::FTM_GEN_FLEX, " Flexible", &LLColor4::yellow4, 0 }, - { LLFastTimer::FTM_GEN_TRIANGLES, " Triangles", &LLColor4::yellow5, 0 }, - { LLFastTimer::FTM_UPDATE_AVATAR, " Avatar", &LLColor4::yellow1, 0 }, - { LLFastTimer::FTM_UPDATE_TREE, " Tree", &LLColor4::yellow2, 0 }, - { LLFastTimer::FTM_UPDATE_TERRAIN, " Terrain", &LLColor4::yellow6, 0 }, - { LLFastTimer::FTM_UPDATE_CLOUDS, " Clouds", &LLColor4::yellow7, 0 }, - { LLFastTimer::FTM_UPDATE_GRASS, " Grass", &LLColor4::yellow8, 0 }, - { LLFastTimer::FTM_UPDATE_WATER, " Water", &LLColor4::yellow9, 0 }, - { LLFastTimer::FTM_GEO_LIGHT, " Lighting", &LLColor4::yellow1, 0 }, - { LLFastTimer::FTM_GEO_SHADOW, " Shadow", &LLColor4::black, 0 }, - { LLFastTimer::FTM_UPDATE_PARTICLES, " Particles", &LLColor4::blue5, 0 }, - { LLFastTimer::FTM_SIMULATE_PARTICLES, " Particle Sim", &LLColor4::blue4, 0 }, - { LLFastTimer::FTM_GEO_RESERVE, " Reserve", &LLColor4::blue6, 0 }, - { LLFastTimer::FTM_UPDATE_LIGHTS, " Lights", &LLColor4::yellow2, 0 }, - { LLFastTimer::FTM_UPDATE_SKY, " Sky Update", &LLColor4::cyan1, 0 }, - { LLFastTimer::FTM_OBJECTLIST_UPDATE, " Object Update", &LLColor4::purple1, 0 }, + { LLFastTimer::FTM_SIMULATE_PARTICLES, " Particle Sim", &LLColor4::blue4, 0 }, + { LLFastTimer::FTM_OBJECTLIST_UPDATE, " Object Update", &LLColor4::purple1, 1 }, { LLFastTimer::FTM_AVATAR_UPDATE, " Avatars", &LLColor4::purple2, 0 }, { LLFastTimer::FTM_JOINT_UPDATE, " Joints", &LLColor4::purple3, 0 }, { LLFastTimer::FTM_ATTACHMENT_UPDATE, " Attachments", &LLColor4::purple4, 0 }, - { LLFastTimer::FTM_UPDATE_ANIMATION, " Animation", &LLColor4::purple5, 0 }, + { LLFastTimer::FTM_UPDATE_ANIMATION, " Animation", &LLColor4::purple5, 0 }, { LLFastTimer::FTM_FLEXIBLE_UPDATE, " Flex Update", &LLColor4::pink2, 0 }, { LLFastTimer::FTM_LOD_UPDATE, " LOD Update", &LLColor4::magenta1, 0 }, -// { LLFastTimer::FTM_TEMP5, " Check", &LLColor4::red1, 1}, { LLFastTimer::FTM_REGION_UPDATE, " Region Update", &LLColor4::cyan2, 0 }, { LLFastTimer::FTM_NETWORK, " Network", &LLColor4::orange1, 1 }, { LLFastTimer::FTM_IDLE_NETWORK, " Decode Msgs", &LLColor4::orange2, 0 }, @@ -145,23 +120,48 @@ static struct ft_display_info ft_display_table[] = { LLFastTimer::FTM_VFILE_WAIT, " VFile Wait", &LLColor4::cyan6, 0 }, // { LLFastTimer::FTM_IDLE_CB, " Callbacks", &LLColor4::pink1, 0 }, { LLFastTimer::FTM_RENDER, " Render", &green0, 1 }, - { LLFastTimer::FTM_REBUILD, " Rebuild", &LLColor4::green1, 1 }, - { LLFastTimer::FTM_STATESORT, " State Sort", &LLColor4::orange1, 1 }, - { LLFastTimer::FTM_STATESORT_DRAWABLE, " Drawable", &LLColor4::orange2, 0 }, - { LLFastTimer::FTM_STATESORT_POSTSORT, " Post Sort", &LLColor4::orange3, 0 }, - { LLFastTimer::FTM_REBUILD_OCCLUSION_VB," Occlusion", &LLColor4::cyan5, 0 }, - { LLFastTimer::FTM_REBUILD_VBO, " VBO Rebuild", &LLColor4::red4, 0 }, - { LLFastTimer::FTM_REBUILD_VOLUME_VB, " Volume", &LLColor4::blue1, 0 }, - { LLFastTimer::FTM_REBUILD_NONE_VB, " Unknown", &LLColor4::cyan5, 0 }, - { LLFastTimer::FTM_REBUILD_BRIDGE_VB, " Bridge", &LLColor4::blue2, 0 }, - { LLFastTimer::FTM_REBUILD_HUD_VB, " HUD", &LLColor4::blue3, 0 }, - { LLFastTimer::FTM_REBUILD_TERRAIN_VB, " Terrain", &LLColor4::blue4, 0 }, - { LLFastTimer::FTM_REBUILD_WATER_VB, " Water", &LLColor4::blue5, 0 }, - { LLFastTimer::FTM_REBUILD_TREE_VB, " Tree", &LLColor4::cyan1, 0 }, - { LLFastTimer::FTM_REBUILD_PARTICLE_VB, " Particle", &LLColor4::cyan2, 0 }, - { LLFastTimer::FTM_REBUILD_CLOUD_VB, " Cloud", &LLColor4::cyan3, 0 }, - { LLFastTimer::FTM_REBUILD_GRASS_VB, " Grass", &LLColor4::cyan4, 0 }, - { LLFastTimer::FTM_RENDER_GEOMETRY, " Geometry", &LLColor4::green2, 1 }, + { LLFastTimer::FTM_HUD_EFFECTS, " HUD Effects", &LLColor4::orange1, 0 }, + { LLFastTimer::FTM_HUD_UPDATE, " HUD Update", &LLColor4::orange2, 0 }, + { LLFastTimer::FTM_UPDATE_SKY, " Sky Update", &LLColor4::cyan1, 0 }, + { LLFastTimer::FTM_UPDATE_TEXTURES, " Textures", &LLColor4::pink2, 0 }, + { LLFastTimer::FTM_GEO_UPDATE, " Geo Update", &LLColor4::blue3, 1 }, + { LLFastTimer::FTM_UPDATE_PRIMITIVES, " Volumes", &LLColor4::blue4, 0 }, + { LLFastTimer::FTM_GEN_VOLUME, " Gen Volume", &LLColor4::yellow3, 0 }, + { LLFastTimer::FTM_GEN_FLEX, " Flexible", &LLColor4::yellow4, 0 }, + { LLFastTimer::FTM_GEN_TRIANGLES, " Triangles", &LLColor4::yellow5, 0 }, + { LLFastTimer::FTM_UPDATE_AVATAR, " Avatar", &LLColor4::yellow1, 0 }, + { LLFastTimer::FTM_UPDATE_TREE, " Tree", &LLColor4::yellow2, 0 }, + { LLFastTimer::FTM_UPDATE_TERRAIN, " Terrain", &LLColor4::yellow6, 0 }, + { LLFastTimer::FTM_UPDATE_CLOUDS, " Clouds", &LLColor4::yellow7, 0 }, + { LLFastTimer::FTM_UPDATE_GRASS, " Grass", &LLColor4::yellow8, 0 }, + { LLFastTimer::FTM_UPDATE_WATER, " Water", &LLColor4::yellow9, 0 }, + { LLFastTimer::FTM_GEO_LIGHT, " Lighting", &LLColor4::yellow1, 0 }, + { LLFastTimer::FTM_GEO_SHADOW, " Shadow", &LLColor4::black, 0 }, + { LLFastTimer::FTM_UPDATE_PARTICLES, " Particles", &LLColor4::blue5, 0 }, + { LLFastTimer::FTM_GEO_RESERVE, " Reserve", &LLColor4::blue6, 0 }, + { LLFastTimer::FTM_UPDATE_LIGHTS, " Lights", &LLColor4::yellow2, 0 }, + { LLFastTimer::FTM_GEO_SKY, " Sky", &LLColor4::yellow3, 0 }, + { LLFastTimer::FTM_UPDATE_WLPARAM, " Windlight Param",&LLColor4::magenta2, 0 }, + { LLFastTimer::FTM_CULL, " Object Cull", &LLColor4::blue2, 1 }, + { LLFastTimer::FTM_CULL_REBOUND, " Rebound", &LLColor4::blue3, 0 }, + { LLFastTimer::FTM_FRUSTUM_CULL, " Frustum Cull", &LLColor4::blue4, 0 }, + { LLFastTimer::FTM_OCCLUSION_READBACK, " Occlusion Read", &LLColor4::red2, 0 }, + { LLFastTimer::FTM_STATESORT, " State Sort", &LLColor4::orange1, 1 }, + { LLFastTimer::FTM_STATESORT_DRAWABLE, " Drawable", &LLColor4::orange2, 0 }, + { LLFastTimer::FTM_STATESORT_POSTSORT, " Post Sort", &LLColor4::orange3, 0 }, + { LLFastTimer::FTM_REBUILD_OCCLUSION_VB," Occlusion", &LLColor4::cyan5, 0 }, + { LLFastTimer::FTM_REBUILD_VBO, " VBO Rebuild", &LLColor4::red4, 0 }, + { LLFastTimer::FTM_REBUILD_VOLUME_VB, " Volume", &LLColor4::blue1, 0 }, +// { LLFastTimer::FTM_REBUILD_NONE_VB, " Unknown", &LLColor4::cyan5, 0 }, +// { LLFastTimer::FTM_REBUILD_BRIDGE_VB, " Bridge", &LLColor4::blue2, 0 }, +// { LLFastTimer::FTM_REBUILD_HUD_VB, " HUD", &LLColor4::blue3, 0 }, + { LLFastTimer::FTM_REBUILD_TERRAIN_VB, " Terrain", &LLColor4::blue4, 0 }, +// { LLFastTimer::FTM_REBUILD_WATER_VB, " Water", &LLColor4::blue5, 0 }, +// { LLFastTimer::FTM_REBUILD_TREE_VB, " Tree", &LLColor4::cyan1, 0 }, + { LLFastTimer::FTM_REBUILD_PARTICLE_VB, " Particle", &LLColor4::cyan2, 0 }, +// { LLFastTimer::FTM_REBUILD_CLOUD_VB, " Cloud", &LLColor4::cyan3, 0 }, +// { LLFastTimer::FTM_REBUILD_GRASS_VB, " Grass", &LLColor4::cyan4, 0 }, + { LLFastTimer::FTM_RENDER_GEOMETRY, " Geometry", &LLColor4::green2, 1 }, { LLFastTimer::FTM_POOLS, " Pools", &LLColor4::green3, 1 }, { LLFastTimer::FTM_POOLRENDER, " RenderPool", &LLColor4::green4, 1 }, { LLFastTimer::FTM_RENDER_TERRAIN, " Terrain", &LLColor4::green6, 0 }, @@ -179,13 +179,17 @@ static struct ft_display_info ft_display_table[] = { LLFastTimer::FTM_RENDER_ALPHA, " Alpha", &LLColor4::yellow6, 0 }, { LLFastTimer::FTM_RENDER_HUD, " HUD", &LLColor4::yellow7, 0 }, { LLFastTimer::FTM_RENDER_WATER, " Water", &LLColor4::yellow9, 0 }, + { LLFastTimer::FTM_RENDER_WL_SKY, " WL Sky", &LLColor4::blue3, 0 }, + { LLFastTimer::FTM_RENDER_FAKE_VBO_UPDATE," Fake VBO update", &LLColor4::red2, 0 }, + { LLFastTimer::FTM_RENDER_BLOOM, " Bloom", &LLColor4::blue4, 0 }, + { LLFastTimer::FTM_RENDER_BLOOM_FBO, " First FBO", &LLColor4::blue, 0 }, { LLFastTimer::FTM_RENDER_UI, " UI", &LLColor4::cyan4, 1 }, { LLFastTimer::FTM_RENDER_TIMER, " Timers", &LLColor4::cyan5, 1, 0 }, // { LLFastTimer::FTM_RENDER_FONTS, " Fonts", &LLColor4::pink1, 0 }, -// { LLFastTimer::FTM_UPDATE_TEXTURES, " Textures", &LLColor4::pink2, 0 }, { LLFastTimer::FTM_SWAP, " Swap", &LLColor4::pink1, 0 }, { LLFastTimer::FTM_CLIENT_COPY, " Client Copy", &LLColor4::red1, 1}, - + +#if 0 || !LL_RELEASE_FOR_DOWNLOAD { LLFastTimer::FTM_TEMP1, " Temp1", &LLColor4::red1, 0 }, { LLFastTimer::FTM_TEMP2, " Temp2", &LLColor4::magenta1, 0 }, { LLFastTimer::FTM_TEMP3, " Temp3", &LLColor4::red2, 0 }, @@ -194,7 +198,8 @@ static struct ft_display_info ft_display_table[] = { LLFastTimer::FTM_TEMP6, " Temp6", &LLColor4::magenta3, 0 }, { LLFastTimer::FTM_TEMP7, " Temp7", &LLColor4::red4, 0 }, { LLFastTimer::FTM_TEMP8, " Temp8", &LLColor4::magenta4, 0 }, - +#endif + { LLFastTimer::FTM_OTHER, " Other", &red0 } }; static int ft_display_didcalc = 0; @@ -211,6 +216,7 @@ LLFastTimerView::LLFastTimerView(const std::string& name, const LLRect& rect) mMaxCountTotal = 0; mDisplayCenter = 1; mDisplayCalls = 0; + mDisplayHz = 0; mScrollIndex = 0; mHoverIndex = -1; mHoverBarIndex = -1; @@ -288,7 +294,7 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask) S32 LLFastTimerView::getLegendIndex(S32 y) { - S32 idx = (mRect.getHeight() - y) / ((S32) LLFontGL::sMonospace->getLineHeight()+2) - 5; + S32 idx = (getRect().getHeight() - y) / ((S32) LLFontGL::sMonospace->getLineHeight()+2) - 5; if (idx >= 0 && idx < FTV_DISPLAY_NUM) { return ft_display_idx[idx]; @@ -322,9 +328,17 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask) else if (mask & MASK_ALT) { if (mask & MASK_SHIFT) + { mSubtractHidden = !mSubtractHidden; + } + else if (mask & MASK_CONTROL) + { + mDisplayHz = !mDisplayHz; + } else + { mDisplayCalls = !mDisplayCalls; + } } else if (mask & MASK_SHIFT) { @@ -417,7 +431,8 @@ void LLFastTimerView::draw() S32 height = (S32) (gViewerWindow->getVirtualWindowRect().getHeight()*0.75f); S32 width = (S32) (gViewerWindow->getVirtualWindowRect().getWidth() * 0.75f); - mRect.setLeftTopAndSize(mRect.mLeft, mRect.mTop, width, height); + // HACK: casting away const. Should use setRect or some helper function instead. + const_cast(getRect()).setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height); S32 left, top, right, bottom; S32 x, y, barw, barh, dx, dy; @@ -463,7 +478,7 @@ void LLFastTimerView::draw() // Draw the window background { LLGLSNoTexture gls_ui_no_texture; - gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); } S32 xleft = margin; @@ -644,7 +659,7 @@ void LLFastTimerView::draw() // update rectangle that includes timer bars mBarRect.mLeft = xleft; - mBarRect.mRight = mRect.mRight - xleft; + mBarRect.mRight = getRect().mRight - xleft; mBarRect.mTop = ytop - ((S32)LLFontGL::sMonospace->getLineHeight() + 4); mBarRect.mBottom = margin + LINE_GRAPH_HEIGHT; @@ -755,36 +770,36 @@ void LLFastTimerView::draw() // Draw borders { LLGLSNoTexture gls_ui_no_texture; - glColor4f(0.5f,0.5f,0.5f,0.5f); + gGL.color4f(0.5f,0.5f,0.5f,0.5f); S32 by = y + 2; y -= ((S32)LLFontGL::sMonospace->getLineHeight() + 4); //heading - gl_rect_2d(xleft-5, by, mRect.getWidth()-5, y+5, FALSE); + gl_rect_2d(xleft-5, by, getRect().getWidth()-5, y+5, FALSE); //tree view gl_rect_2d(5, by, xleft-10, 5, FALSE); by = y + 5; //average bar - gl_rect_2d(xleft-5, by, mRect.getWidth()-5, by-barh-dy-5, FALSE); + gl_rect_2d(xleft-5, by, getRect().getWidth()-5, by-barh-dy-5, FALSE); by -= barh*2+dy; //current frame bar - gl_rect_2d(xleft-5, by, mRect.getWidth()-5, by-barh-dy-2, FALSE); + gl_rect_2d(xleft-5, by, getRect().getWidth()-5, by-barh-dy-2, FALSE); by -= barh+dy+1; //history bars - gl_rect_2d(xleft-5, by, mRect.getWidth()-5, LINE_GRAPH_HEIGHT-barh-dy-2, FALSE); + gl_rect_2d(xleft-5, by, getRect().getWidth()-5, LINE_GRAPH_HEIGHT-barh-dy-2, FALSE); by = LINE_GRAPH_HEIGHT-barh-dy-7; //line graph - graph_rect = LLRect(xleft-5, by, mRect.getWidth()-5, 5); + graph_rect = LLRect(xleft-5, by, getRect().getWidth()-5, 5); gl_rect_2d(graph_rect, FALSE); } @@ -920,7 +935,7 @@ void LLFastTimerView::draw() color = lerp(color, LLColor4::grey, 0.8f); } - glColor4fv(color.mV); + gGL.color4fv(color.mV); F32 start_fragment = llclamp((F32)(left - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f); F32 end_fragment = llclamp((F32)(right - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f); gl_segmented_rect_2d_fragment_tex(sublevel_left[level], top - level + scale_offset, sublevel_right[level], bottom + level - scale_offset, box_imagep->getWidth(), box_imagep->getHeight(), 16, start_fragment, end_fragment); @@ -947,6 +962,8 @@ void LLFastTimerView::draw() //display y-axis range LLString tdesc = mDisplayCalls ? llformat("%d calls", max_ticks) : + mDisplayHz ? + llformat("%d Hz", max_ticks) : llformat("%4.2f ms", ms); x = graph_rect.mRight - LLFontGL::sMonospace->getWidth(tdesc)-5; @@ -954,7 +971,7 @@ void LLFastTimerView::draw() LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); - + //highlight visible range { S32 first_frame = LLFastTimer::FTM_HISTORY_NUM - mScrollIndex; @@ -965,7 +982,7 @@ void LLFastTimerView::draw() F32 right = (F32) graph_rect.mLeft + frame_delta*first_frame; F32 left = (F32) graph_rect.mLeft + frame_delta*last_frame; - glColor4f(0.5f,0.5f,0.5f,0.3f); + gGL.color4f(0.5f,0.5f,0.5f,0.3f); gl_rect_2d((S32) left, graph_rect.mTop, (S32) right, graph_rect.mBottom); if (mHoverBarIndex >= 0) @@ -973,12 +990,12 @@ void LLFastTimerView::draw() S32 bar_frame = first_frame - mHoverBarIndex; F32 bar = (F32) graph_rect.mLeft + frame_delta*bar_frame; - glColor4f(0.5f,0.5f,0.5f,1); + gGL.color4f(0.5f,0.5f,0.5f,1); - glBegin(GL_LINES); - glVertex2i((S32)bar, graph_rect.mBottom); - glVertex2i((S32)bar, graph_rect.mTop); - glEnd(); + gGL.begin(GL_LINES); + gGL.vertex2i((S32)bar, graph_rect.mBottom); + gGL.vertex2i((S32)bar, graph_rect.mTop); + gGL.end(); } } @@ -993,10 +1010,11 @@ void LLFastTimerView::draw() //fatten highlighted timer if (mHoverIndex == idx) { + gGL.flush(); glLineWidth(3); } - F32* col = ft_display_table[idx].color->mV; + const F32 * col = ft_display_table[idx].color->mV; F32 alpha = 1.f; @@ -1009,30 +1027,38 @@ void LLFastTimerView::draw() } } - glColor4f(col[0], col[1], col[2], alpha); - glBegin(GL_LINE_STRIP); + gGL.color4f(col[0], col[1], col[2], alpha); + gGL.begin(GL_LINE_STRIP); for (U32 j = 0; j < LLFastTimer::FTM_HISTORY_NUM; j++) { U64 ticks = ticks_sum[j+1][idx]; - if (mDisplayCalls) + + if (mDisplayHz) + { + F64 tc = (F64) (ticks+1) * iclock_freq; + tc = 1000.f/tc; + ticks = llmin((U64) tc, (U64) 1024); + } + else if (mDisplayCalls) { S32 tidx = ft_display_table[idx].timer; S32 hidx = (LLFastTimer::sLastFrameIndex + j) % LLFastTimer::FTM_HISTORY_NUM; ticks = (S32)LLFastTimer::sCallHistory[hidx][tidx]; } - + if (alpha == 1.f) { //normalize to highlighted timer cur_max = llmax(cur_max, ticks); } F32 x = graph_rect.mLeft + ((F32) (graph_rect.getWidth()))/(LLFastTimer::FTM_HISTORY_NUM-1)*j; F32 y = graph_rect.mBottom + (F32) graph_rect.getHeight()/max_ticks*ticks; - glVertex2f(x,y); + gGL.vertex2f(x,y); } - glEnd(); + gGL.end(); if (mHoverIndex == idx) { + gGL.flush(); glLineWidth(1); } } @@ -1045,7 +1071,15 @@ void LLFastTimerView::draw() llmin((F32) cur_max/ (F32) last_max - 1.f,1.f); alpha_interp = alpha_interp + (alpha_target-alpha_interp) * dt; - + + if (mHoverIndex >= 0) + { + x = (graph_rect.mRight + graph_rect.mLeft)/2; + y = graph_rect.mBottom + 8; + + LLFontGL::sMonospace->renderUTF8(ft_display_table[mHoverIndex].desc, 0, x, y, LLColor4::white, + LLFontGL::LEFT, LLFontGL::BOTTOM); + } } } diff --git a/linden/indra/newview/llfasttimerview.h b/linden/indra/newview/llfasttimerview.h index 7c1acff..bd103e2 100644 --- a/linden/indra/newview/llfasttimerview.h +++ b/linden/indra/newview/llfasttimerview.h @@ -60,6 +60,7 @@ private: S32 mDisplayMode; S32 mDisplayCenter; S32 mDisplayCalls; + S32 mDisplayHz; U64 mAvgCountTotal; U64 mMaxCountTotal; LLRect mBarRect; diff --git a/linden/indra/newview/llfeaturemanager.cpp b/linden/indra/newview/llfeaturemanager.cpp index 56e0469..f96b2db 100644 --- a/linden/indra/newview/llfeaturemanager.cpp +++ b/linden/indra/newview/llfeaturemanager.cpp @@ -34,6 +34,8 @@ #include "llviewerprecompiledheaders.h" +#include + #include "llfeaturemanager.h" #include "lldir.h" @@ -43,11 +45,13 @@ #include "llviewercontrol.h" #include "llworld.h" -#include "pipeline.h" #include "lldrawpoolterrain.h" #include "llviewerimagelist.h" #include "llwindow.h" #include "llui.h" +#include "llcontrol.h" +#include "llboost.h" +#include "llweb.h" #if LL_WINDOWS #include "lldxhardware.h" @@ -73,7 +77,7 @@ const char GPU_TABLE_FILENAME[] = "gpu_table.txt"; LLFeatureManager *gFeatureManagerp = NULL; -LLFeatureInfo::LLFeatureInfo(const char *name, const BOOL available, const S32 level) : mValid(TRUE) +LLFeatureInfo::LLFeatureInfo(const char *name, const BOOL available, const F32 level) : mValid(TRUE) { mName = name; mAvailable = available; @@ -89,7 +93,7 @@ LLFeatureList::~LLFeatureList() { } -void LLFeatureList::addFeature(const char *name, const BOOL available, const S32 level) +void LLFeatureList::addFeature(const char *name, const BOOL available, const F32 level) { if (mFeatures.count(name)) { @@ -108,18 +112,21 @@ BOOL LLFeatureList::isFeatureAvailable(const char *name) } llwarns << "Feature " << name << " not on feature list!" << llendl; - return FALSE; + + // changing this to TRUE so you have to explicitly disable + // something for it to be disabled + return TRUE; } -S32 LLFeatureList::getRecommendedLevel(const char *name) +F32 LLFeatureList::getRecommendedValue(const char *name) { - if (mFeatures.count(name)) + if (mFeatures.count(name) && isFeatureAvailable(name)) { return mFeatures[name].mRecommendedLevel; } - llwarns << "Feature " << name << " not on feature list!" << llendl; - return -1; + llwarns << "Feature " << name << " not on feature list or not available!" << llendl; + return 0; } BOOL LLFeatureList::maskList(LLFeatureList &mask) @@ -207,6 +214,14 @@ BOOL LLFeatureManager::maskFeatures(const char *name) BOOL LLFeatureManager::loadFeatureTables() { + // *TODO - if I or anyone else adds something else to the skipped list + // make this data driven. Put it in the feature table and parse it + // correctly + mSkippedFeatures.insert("RenderAnisotropic"); + mSkippedFeatures.insert("RenderGamma"); + mSkippedFeatures.insert("RenderVBOEnable"); + mSkippedFeatures.insert("RenderFogRatio"); + std::string data_path = gDirUtilp->getAppRODataDir(); data_path += gDirUtilp->getDirDelimiter(); @@ -275,19 +290,8 @@ BOOL LLFeatureManager::loadFeatureTables() llerrs << "Overriding mask " << name << ", this is invalid!" << llendl; } - if (!flp) - { - // - // The first one is always the default - // - flp = this; - } - else - { - flp = new LLFeatureList(name); - mMaskList[name] = flp; - } - + flp = new LLFeatureList(name); + mMaskList[name] = flp; } else { @@ -295,7 +299,8 @@ BOOL LLFeatureManager::loadFeatureTables() { llerrs << "Specified parameter before keyword!" << llendl; } - S32 available, recommended; + S32 available; + F32 recommended; file >> available >> recommended; flp->addFeature(name, available, recommended); } @@ -314,9 +319,10 @@ void LLFeatureManager::loadGPUClass() data_path += GPU_TABLE_FILENAME; // defaults - mGPUClass = 0; + mGPUClass = GPU_CLASS_UNKNOWN; mGPUString = gGLManager.getRawGLString(); - + mGPUSupported = FALSE; + llifstream file; file.open(data_path.c_str()); /*Flawfinder: ignore*/ @@ -354,41 +360,50 @@ void LLFeatureManager::loadGPUClass() continue; } - char* cls, *label, *expr; - - label = strtok(buffer, "\t"); - expr = strtok(NULL, "\t"); - cls = strtok(NULL, "\t"); + // setup the tokenizer + std::string buf(buffer); + std::string cls, label, expr, supported; + boost_tokenizer tokens(buf, boost::char_separator("\t\n")); + boost_tokenizer::iterator token_iter = tokens.begin(); - if (label == NULL || expr == NULL || cls == NULL) + // grab the label, pseudo regular expression, and class + if(token_iter != tokens.end()) + { + label = *token_iter++; + } + if(token_iter != tokens.end()) + { + expr = *token_iter++; + } + if(token_iter != tokens.end()) + { + cls = *token_iter++; + } + if(token_iter != tokens.end()) + { + supported = *token_iter++; + } + + if (label.empty() || expr.empty() || cls.empty() || supported.empty()) { continue; } - for (U32 i = 0; i < strlen(expr); i++) /*Flawfinder: ignore*/ + for (U32 i = 0; i < expr.length(); i++) /*Flawfinder: ignore*/ { expr[i] = tolower(expr[i]); } - - char* ex = strtok(expr, ".*"); - char* rnd = (char*) renderer.c_str(); - while (ex != NULL && rnd != NULL) - { - rnd = strstr(rnd, ex); - if (rnd != NULL) - { - rnd += strlen(ex); - } - ex = strtok(NULL, ".*"); - } - - if (rnd != NULL) + // run the regular expression against the renderer + boost::regex re(expr.c_str()); + if(boost::regex_search(renderer, re)) { + // if we found it, stop! file.close(); llinfos << "GPU is " << label << llendl; mGPUString = label; - mGPUClass = (S32) strtol(cls, NULL, 10); + mGPUClass = (EGPUClass) strtol(cls.c_str(), NULL, 10); + mGPUSupported = (BOOL) strtol(supported.c_str(), NULL, 10); file.close(); return; } @@ -404,33 +419,142 @@ void LLFeatureManager::cleanupFeatureTables() mMaskList.clear(); } +void LLFeatureManager::init() +{ + // load the tables + loadFeatureTables(); + + // get the gpu class + loadGPUClass(); + + // apply the base masks, so we know if anything is disabled + applyBaseMasks(); +} -void LLFeatureManager::initCPUFeatureMasks() +void LLFeatureManager::applyRecommendedSettings() { - if (gSysMemory.getPhysicalMemoryClamped() <= 256*1024*1024) + // apply saved settings + // cap the level at 2 (high) + S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_2)); + + llinfos << "Applying Recommended Features" << llendl; + + setGraphicsLevel(level, false); + gSavedSettings.setU32("RenderQualityPerformance", level); + gSavedSettings.setBOOL("RenderCustomSettings", FALSE); + + // now apply the tweaks to draw distance + // these are double negatives, because feature masks only work by + // downgrading values, so i needed to make a true value go to false + // for certain cards, thus the awkward name, "Disregard..." + if(!gSavedSettings.getBOOL("Disregard96DefaultDrawDistance")) { - maskFeatures("RAM256MB"); + gSavedSettings.setF32("RenderFarClip", 96.0f); } - -#if LL_SOLARIS && defined(__sparc) // even low MHz SPARCs are fast -#error The 800 is hinky. Would something like a LL_MIN_MHZ make more sense here? - if (gSysCPU.getMhz() < 800) -#else - if (gSysCPU.getMhz() < 1100) + else if(!gSavedSettings.getBOOL("Disregard128DefaultDrawDistance")) + { + gSavedSettings.setF32("RenderFarClip", 128.0f); + } + + +} + +void LLFeatureManager::applyFeatures(bool skipFeatures) +{ + // see featuretable.txt / featuretable_linux.txt / featuretable_mac.txt + +#ifndef LL_RELEASE_FOR_DOWNLOAD + dump(); #endif + + // scroll through all of these and set their corresponding control value + for(feature_map_t::iterator mIt = mFeatures.begin(); + mIt != mFeatures.end(); + ++mIt) { - maskFeatures("CPUSlow"); + // skip features you want to skip + // do this for when you don't want to change certain settings + if(skipFeatures) + { + if(mSkippedFeatures.find(mIt->first) != mSkippedFeatures.end()) + { + continue; + } + } + + // get the control setting + LLControlBase* ctrl = gSavedSettings.getControl(mIt->first); + if(ctrl == NULL) + { + llwarns << "AHHH! Control setting " << mIt->first << " does not exist!" << llendl; + continue; + } + + // handle all the different types + if(ctrl->isType(TYPE_BOOLEAN)) + { + gSavedSettings.setBOOL(mIt->first, (BOOL)getRecommendedValue(mIt->first.c_str())); + } + else if (ctrl->isType(TYPE_S32)) + { + gSavedSettings.setS32(mIt->first, (S32)getRecommendedValue(mIt->first.c_str())); + } + else if (ctrl->isType(TYPE_U32)) + { + gSavedSettings.setU32(mIt->first, (U32)getRecommendedValue(mIt->first.c_str())); + } + else if (ctrl->isType(TYPE_F32)) + { + gSavedSettings.setF32(mIt->first, (F32)getRecommendedValue(mIt->first.c_str())); + } + else + { + llwarns << "AHHH! Control variable is not a numeric type!" << llendl; + } } - if (isSafe()) +} + +void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures) +{ + applyBaseMasks(); + + switch (level) { - maskFeatures("safe"); + case 0: + maskFeatures("Low"); + break; + case 1: + maskFeatures("Mid"); + break; + case 2: + maskFeatures("High"); + break; + case 3: + maskFeatures("Ultra"); + break; + default: + maskFeatures("Low"); + break; } + + applyFeatures(skipFeatures); } -void LLFeatureManager::initGraphicsFeatureMasks() +void LLFeatureManager::applyBaseMasks() { - loadGPUClass(); - + // reapply masks + mFeatures.clear(); + + LLFeatureList* maskp = findMask("all"); + if(maskp == NULL) + { + llwarns << "AHH! No \"all\" in feature table!" << llendl; + return; + } + + mFeatures = maskp->getFeatures(); + + // mask class if (mGPUClass >= 0 && mGPUClass < 4) { const char* class_table[] = @@ -444,7 +568,13 @@ void LLFeatureManager::initGraphicsFeatureMasks() llinfos << "Setting GPU Class to " << class_table[mGPUClass] << llendl; maskFeatures(class_table[mGPUClass]); } - + else + { + llinfos << "Setting GPU Class to Unknown" << llendl; + maskFeatures("Unknown"); + } + + // now all those wacky ones if (!gGLManager.mHasFragmentShader) { maskFeatures("NoPixelShaders"); @@ -477,6 +607,8 @@ void LLFeatureManager::initGraphicsFeatureMasks() { maskFeatures("OpenGLPre15"); } + + // now mask by gpu string // Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces std::string gpustr = mGPUString; for (std::string::iterator iter = gpustr.begin(); iter != gpustr.end(); ++iter) @@ -486,94 +618,28 @@ void LLFeatureManager::initGraphicsFeatureMasks() *iter = '_'; } } -// llinfos << "Masking features from gpu table match: " << gpustr << llendl; + + //llinfos << "Masking features from gpu table match: " << gpustr << llendl; maskFeatures(gpustr.c_str()); - if (isSafe()) + // now mask cpu type ones + if (gSysMemory.getPhysicalMemoryClamped() <= 256*1024*1024) { - maskFeatures("safe"); + maskFeatures("RAM256MB"); } -} - -void LLFeatureManager::applyRecommendedFeatures() -{ - // see featuretable.txt / featuretable_linux.txt / featuretable_mac.txt - - llinfos << "Applying Recommended Features" << llendl; -#ifndef LL_RELEASE_FOR_DOWNLOAD - dump(); -#endif - // Enabling VBO - if (getRecommendedLevel("RenderVBO")) - { - gSavedSettings.setBOOL("RenderVBOEnable", TRUE); - } - else +#if LL_SOLARIS && defined(__sparc) // even low MHz SPARCs are fast +#error The 800 is hinky. Would something like a LL_MIN_MHZ make more sense here? + if (gSysCPU.getMhz() < 800) +#else + if (gSysCPU.getMhz() < 1100) +#endif { - gSavedSettings.setBOOL("RenderVBOEnable", FALSE); + maskFeatures("CPUSlow"); } - // Anisotropic rendering - BOOL aniso = getRecommendedLevel("RenderAniso"); - LLImageGL::sGlobalUseAnisotropic = aniso; - gSavedSettings.setBOOL("RenderAnisotropic", LLImageGL::sGlobalUseAnisotropic); - - // Render Avatar Mode - BOOL avatar_vp = getRecommendedLevel("RenderAvatarVP"); - S32 avatar_mode = getRecommendedLevel("RenderAvatarMode"); - if (avatar_vp == FALSE) - avatar_mode = 0; - gSavedSettings.setBOOL("RenderAvatarVP", avatar_vp); - gSavedSettings.setS32("RenderAvatarMode", avatar_mode); - - // Render Distance - S32 far_clip = getRecommendedLevel("RenderDistance"); - gSavedSettings.setF32("RenderFarClip", (F32)far_clip); - - // Lighting - S32 lighting = getRecommendedLevel("RenderLighting"); - gSavedSettings.setS32("RenderLightingDetail", lighting); - - // ObjectBump - BOOL bump = getRecommendedLevel("RenderObjectBump"); - gSavedSettings.setBOOL("RenderObjectBump", bump); - - // Particle Count - S32 max_parts = getRecommendedLevel("RenderParticleCount"); - gSavedSettings.setS32("RenderMaxPartCount", max_parts); - LLViewerPartSim::setMaxPartCount(max_parts); - - // RippleWater - BOOL ripple = getRecommendedLevel("RenderRippleWater"); - gSavedSettings.setBOOL("RenderRippleWater", ripple); - - // Occlusion Culling - BOOL occlusion = getRecommendedLevel("UseOcclusion"); - gSavedSettings.setBOOL("UseOcclusion", occlusion); - - // Vertex Shaders - S32 shaders = getRecommendedLevel("VertexShaderEnable"); - gSavedSettings.setBOOL("VertexShaderEnable", shaders); - - // Terrain - S32 terrain = getRecommendedLevel("RenderTerrainDetail"); - gSavedSettings.setS32("RenderTerrainDetail", terrain); - LLDrawPoolTerrain::sDetailMode = terrain; - - // Set the amount of VRAM we have available if (isSafe()) { - gSavedSettings.setS32("GraphicsCardMemorySetting", 1); // 32 MB in 'safe' mode - } - else - { - S32 idx = gSavedSettings.getS32("GraphicsCardMemorySetting"); - // -1 indicates use default (max), don't change - if (idx != -1) - { - idx = LLViewerImageList::getMaxVideoRamSetting(-2); // get max recommended setting - gSavedSettings.setS32("GraphicsCardMemorySetting", idx); - } + maskFeatures("safe"); } } diff --git a/linden/indra/newview/llfeaturemanager.h b/linden/indra/newview/llfeaturemanager.h index 1ee62b4..c98fb0d 100644 --- a/linden/indra/newview/llfeaturemanager.h +++ b/linden/indra/newview/llfeaturemanager.h @@ -35,14 +35,22 @@ #include "stdtypes.h" #include "llstring.h" -#include "llskipmap.h" #include +typedef enum EGPUClass +{ + GPU_CLASS_UNKNOWN = -1, + GPU_CLASS_0 = 0, + GPU_CLASS_1 = 1, + GPU_CLASS_2 = 2, + GPU_CLASS_3 = 3 +} EGPUClass; + class LLFeatureInfo { public: LLFeatureInfo() : mValid(FALSE), mAvailable(FALSE), mRecommendedLevel(-1) {} - LLFeatureInfo(const char *name, const BOOL available, const S32 level); + LLFeatureInfo(const char *name, const BOOL available, const F32 level); BOOL isValid() const { return mValid; }; @@ -50,32 +58,38 @@ public: BOOL mValid; LLString mName; BOOL mAvailable; - S32 mRecommendedLevel; + F32 mRecommendedLevel; }; class LLFeatureList { public: + typedef std::map feature_map_t; + LLFeatureList(const char *name = "default"); virtual ~LLFeatureList(); BOOL isFeatureAvailable(const char *name); - S32 getRecommendedLevel(const char *name); + F32 getRecommendedValue(const char *name); void setFeatureAvailable(const char *name, const BOOL available); - void setRecommendedLevel(const char *name, const S32 level); + void setRecommendedLevel(const char *name, const F32 level); BOOL loadFeatureList(FILE *fp); BOOL maskList(LLFeatureList &mask); - void addFeature(const char *name, const BOOL available, const S32 level); + void addFeature(const char *name, const BOOL available, const F32 level); + + feature_map_t& getFeatures() + { + return mFeatures; + } void dump(); protected: LLString mName; - typedef std::map feature_map_t; feature_map_t mFeatures; }; @@ -83,14 +97,19 @@ protected: class LLFeatureManager : public LLFeatureList { public: - LLFeatureManager() : mInited(FALSE), mTableVersion(0), mSafe(FALSE), mGPUClass(0) {} + LLFeatureManager() : mInited(FALSE), mTableVersion(0), mSafe(FALSE), mGPUClass(GPU_CLASS_UNKNOWN) {} + ~LLFeatureManager() {cleanupFeatureTables();} + + // initialize this by loading feature table and gpu table + void init(); void maskCurrentList(const char *name); // Mask the current feature list with the named list BOOL loadFeatureTables(); - S32 getGPUClass() { return mGPUClass; } + EGPUClass getGPUClass() { return mGPUClass; } std::string& getGPUString() { return mGPUString; } + BOOL isGPUSupported() { return mGPUSupported; } void cleanupFeatureTables(); @@ -101,22 +120,32 @@ public: LLFeatureList *findMask(const char *name); BOOL maskFeatures(const char *name); - - void initCPUFeatureMasks(); - void initGraphicsFeatureMasks(); + // set the graphics to low, medium, high, or ultra. + // skipFeatures forces skipping of mostly hardware settings + // that we don't want to change when we change graphics + // settings + void setGraphicsLevel(S32 level, bool skipFeatures); - void applyRecommendedFeatures(); + void applyBaseMasks(); + void applyRecommendedSettings(); + + // apply the basic masks. Also, skip one saved + // in the skip list if true + void applyFeatures(bool skipFeatures); protected: void loadGPUClass(); void initBaseMask(); + std::map mMaskList; + std::set mSkippedFeatures; BOOL mInited; S32 mTableVersion; BOOL mSafe; // Reinitialize everything to the "safe" mask - S32 mGPUClass; + EGPUClass mGPUClass; std::string mGPUString; + BOOL mGPUSupported; }; extern LLFeatureManager *gFeatureManagerp; diff --git a/linden/indra/newview/llfilepicker.cpp b/linden/indra/newview/llfilepicker.cpp index 6233443..af68e21 100644 --- a/linden/indra/newview/llfilepicker.cpp +++ b/linden/indra/newview/llfilepicker.cpp @@ -216,6 +216,8 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) mCurrentFile = mFiles; LLString tstr = utf16str_to_utf8str(llutf16string(mFilesW)); memcpy(mFiles, tstr.c_str(), tstr.size()+1); /*Flawfinder: ignore*/ + + mCurrentFile = &mFiles[mOFN.nFileOffset]; } else { diff --git a/linden/indra/newview/llfirstuse.cpp b/linden/indra/newview/llfirstuse.cpp index b17bbc3..4ea950f 100644 --- a/linden/indra/newview/llfirstuse.cpp +++ b/linden/indra/newview/llfirstuse.cpp @@ -264,3 +264,14 @@ void LLFirstUse::useVoice() LLFloaterVoiceWizard::showInstance(); } } + +// static +void LLFirstUse::useMedia() +{ + if (gSavedSettings.getWarning("FirstMedia")) + { + gSavedSettings.setWarning("FirstMedia", FALSE); + + LLNotifyBox::showXml("FirstMedia"); + } +} diff --git a/linden/indra/newview/llfirstuse.h b/linden/indra/newview/llfirstuse.h index 748f4f5..413db4b 100644 --- a/linden/indra/newview/llfirstuse.h +++ b/linden/indra/newview/llfirstuse.h @@ -105,7 +105,8 @@ public: static void useDebugMenus(); static void useSculptedPrim(); static void useVoice(); - + static void useMedia(); + protected: static std::set sConfigVariables; }; diff --git a/linden/indra/newview/llflexibleobject.cpp b/linden/indra/newview/llflexibleobject.cpp index eb9b927..e9c2332 100644 --- a/linden/indra/newview/llflexibleobject.cpp +++ b/linden/indra/newview/llflexibleobject.cpp @@ -47,6 +47,7 @@ #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llworld.h" +#include "llvoavatar.h" /*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f; @@ -66,6 +67,11 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD mSimulateRes = 0; mFrameNum = 0; mRenderRes = 1; + + if(mVO->mDrawable.notNull()) + { + mVO->mDrawable->makeActive() ; + } }//----------------------------------------------- LLVector3 LLVolumeImplFlexible::getFramePosition() const @@ -240,12 +246,7 @@ void LLVolumeImplFlexible::setAttributesOfAllSections() void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, const S32 detail) { - /*doIdleUpdate(gAgent, *gWorldp, 0.0); - if (mVO && mVO->mDrawable.notNull()) - { - gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); - gPipeline.markMoved(mVO->mDrawable); - }*/ + } //--------------------------------------------------------------------------------- @@ -255,13 +256,14 @@ void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, cons //--------------------------------------------------------------------------------- BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - if (mVO->mDrawable.isNull()) { // Don't do anything until we have a drawable return FALSE; // (we are not initialized or updated) } + BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE; + //flexible objects never go static mVO->mDrawable->mQuietCount = 0; if (!mVO->mDrawable->isRoot()) @@ -307,7 +309,11 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6 return FALSE; // (we are not initialized or updated) } - if (mVO->mDrawable->isVisible() && + if (force_update) + { + gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE); + } + else if (mVO->mDrawable->isVisible() && !mVO->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) && mVO->getPixelArea() > 256.f) { @@ -332,7 +338,7 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6 } } - return TRUE; + return force_update; } inline S32 log2(S32 x) @@ -348,7 +354,8 @@ inline S32 log2(S32 x) void LLVolumeImplFlexible::doFlexibleUpdate() { - LLPath *path = &mVO->getVolume()->getPath(); + LLVolume* volume = mVO->getVolume(); + LLPath *path = &volume->getPath(); if (mSimulateRes == 0) { mVO->markForUpdate(TRUE); @@ -568,7 +575,11 @@ void LLVolumeImplFlexible::doFlexibleUpdate() // Create points S32 num_render_sections = 1<resizePath(num_render_sections+1); + if (path->getPathLength() != num_render_sections+1) + { + ((LLVOVolume*) mVO)->mVolumeChanged = TRUE; + volume->resizePath(num_render_sections+1); + } LLPath::PathPt *new_point; @@ -600,7 +611,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate() LLVector3 pos = newSection[i].mPosition * rel_xform; LLQuaternion rot = mSection[i].mAxisRotation * newSection[i].mRotation * delta_rot; - if (!mUpdated || (new_point->mPos-pos).magVecSquared() > 0.000001f) + if (!mUpdated || (new_point->mPos-pos).magVec()/mVO->mDrawable->mDistanceWRTCamera > 0.001f) { new_point->mPos = newSection[i].mPosition * rel_xform; mUpdated = FALSE; @@ -614,9 +625,19 @@ void LLVolumeImplFlexible::doFlexibleUpdate() mLastSegmentRotation = parentSegmentRotation; } +void LLVolumeImplFlexible::preRebuild() +{ + if (!mUpdated) + { + doFlexibleRebuild(); + } +} + void LLVolumeImplFlexible::doFlexibleRebuild() { - mVO->getVolume()->regen(); + LLVolume* volume = mVO->getVolume(); + volume->regen(); + mUpdated = TRUE; } @@ -631,7 +652,26 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable) { LLVOVolume *volume = (LLVOVolume*)mVO; - if (volume->mDrawable.isNull()) // Not sure why this is happening, but it is... + if (mVO->isAttachment()) + { //don't update flexible attachments for impostored avatars unless the + //impostor is being updated this frame (w00!) + LLViewerObject* parent = (LLViewerObject*) mVO->getParent(); + while (parent && !parent->isAvatar()) + { + parent = (LLViewerObject*) parent->getParent(); + } + + if (parent) + { + LLVOAvatar* avatar = (LLVOAvatar*) parent; + if (avatar->isImpostor() && !avatar->needsImpostorUpdate()) + { + return TRUE; + } + } + } + + if (volume->mDrawable.isNull()) { return TRUE; // No update to complete } @@ -660,11 +700,14 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable) { volume->regenFaces(); volume->mDrawable->setState(LLDrawable::REBUILD_VOLUME); + volume->dirtySpatialGroup(); + doFlexibleRebuild(); + volume->genBBoxes(isVolumeGlobal()); } - - if (!mUpdated || volume->mFaceMappingChanged || volume->mVolumeChanged || rotated) + else if (!mUpdated || rotated) { - doFlexibleRebuild(); + volume->mDrawable->setState(LLDrawable::REBUILD_POSITION); + volume->dirtyMesh(); volume->genBBoxes(isVolumeGlobal()); } @@ -672,7 +715,6 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable) volume->mLODChanged = FALSE; volume->mFaceMappingChanged = FALSE; - // clear UV flag drawable->clearState(LLDrawable::UV); diff --git a/linden/indra/newview/llflexibleobject.h b/linden/indra/newview/llflexibleobject.h index a14a143..f6e68fc 100644 --- a/linden/indra/newview/llflexibleobject.h +++ b/linden/indra/newview/llflexibleobject.h @@ -98,7 +98,8 @@ class LLVolumeImplFlexible : public LLVolumeInterface void updateRelativeXform(); void doFlexibleUpdate(); // Called to update the simulation void doFlexibleRebuild(); // Called to rebuild the geometry - + void preRebuild(); + //void setAttributes( LLFlexibleObjectData ); void setParentPositionAndRotationDirectly( LLVector3 p, LLQuaternion r ); void setUsingCollisionSphere( bool u ); diff --git a/linden/indra/newview/llfloaterabout.cpp b/linden/indra/newview/llfloaterabout.cpp index 47ecdff..ddedef4 100644 --- a/linden/indra/newview/llfloaterabout.cpp +++ b/linden/indra/newview/llfloaterabout.cpp @@ -48,12 +48,9 @@ #include "llviewerbuild.h" #include "llvieweruictrlfactory.h" #include "llappviewer.h" - -#if LL_LIBXUL_ENABLED -#include "llmozlib.h" -#endif // LL_LIBXUL_ENABLED - #include "llglheaders.h" +#include "llmediamanager.h" + extern LLCPUInfo gSysCPU; extern LLMemoryInfo gSysMemory; @@ -96,7 +93,7 @@ LLFloaterAbout::LLFloaterAbout() if (region) { const LLVector3d &pos = gAgent.getPositionGlobal(); - LLUIString pos_text = childGetText("you_are_at"); + LLUIString pos_text = getUIString("you_are_at"); pos_text.setArg("[POSITION]", llformat("%.1f, %.1f, %.1f ", pos.mdV[VX], pos.mdV[VY], pos.mdV[VZ])); support.append(pos_text); @@ -147,11 +144,18 @@ LLFloaterAbout::LLFloaterAbout() support.append( (const char*) glGetString(GL_VERSION) ); support.append("\n"); -#if LL_LIBXUL_ENABLED - support.append("LLMozLib Version: "); - support.append( (const char*) LLMozLib::getInstance()->getVersion().c_str() ); - support.append("\n"); -#endif // LL_LIBXUL_ENABLED + LLMediaManager *mgr = LLMediaManager::getInstance(); + if (mgr) + { + LLMediaBase *media_source = mgr->createSourceFromMimeType("http", "text/html"); + if (media_source) + { + support.append("LLMozLib Version: "); + support.append((const char*) media_source->getVersion().c_str()); + support.append("\n"); + mgr->destroySource(media_source); + } + } if (gViewerStats && gPacketsIn > 0) @@ -173,7 +177,7 @@ LLFloaterAbout::LLFloaterAbout() // Fix views childDisable("credits_editor"); - LLTextEditor * support_widget = (LLTextEditor *) getChildByName("support_editor", true); + LLTextEditor * support_widget = getChild("support_editor", true); if (support_widget) { support_widget->setEnabled( FALSE ); diff --git a/linden/indra/newview/llfloateractivespeakers.cpp b/linden/indra/newview/llfloateractivespeakers.cpp index 21b302a..7445ef0 100644 --- a/linden/indra/newview/llfloateractivespeakers.cpp +++ b/linden/indra/newview/llfloateractivespeakers.cpp @@ -55,8 +55,6 @@ const F32 TYPING_ANIMATION_FPS = 2.5f; LLLocalSpeakerMgr* gLocalSpeakerMgr = NULL; LLActiveSpeakerMgr* gActiveChannelSpeakerMgr = NULL; -LLSpeaker::speaker_map_t LLSpeaker::sSpeakers; - LLSpeaker::LLSpeaker(const LLUUID& id, const LLString& name, const ESpeakerType type) : mStatus(LLSpeaker::STATUS_TEXT_ONLY), mLastSpokeTime(0.f), @@ -71,8 +69,6 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const LLString& name, const ESpeakerType mModeratorMutedVoice(FALSE), mModeratorMutedText(FALSE) { - mHandle.init(); - sSpeakers.insert(std::make_pair(mHandle, this)); if (name.empty() && type == SPEAKER_AGENT) { lookupName(); @@ -87,30 +83,21 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const LLString& name, const ESpeakerType mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT); } -LLSpeaker::~LLSpeaker() -{ - sSpeakers.erase(mHandle); -} void LLSpeaker::lookupName() { - gCacheName->getName(mID, onAvatarNameLookup, new LLViewHandle(mHandle)); + gCacheName->getName(mID, onAvatarNameLookup, new LLHandle(getHandle())); } //static void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* user_data) { - LLViewHandle speaker_handle = *(LLViewHandle*)user_data; - delete (LLViewHandle*)user_data; + LLSpeaker* speaker_ptr = ((LLHandle*)user_data)->get(); + delete (LLHandle*)user_data; - speaker_map_t::iterator found_it = sSpeakers.find(speaker_handle); - if (found_it != sSpeakers.end()) + if (speaker_ptr) { - LLSpeaker* speakerp = found_it->second; - if (speakerp) - { - speakerp->mDisplayName = llformat("%s %s", first, last); - } + speaker_ptr->mDisplayName = llformat("%s %s", first, last); } } @@ -300,10 +287,10 @@ BOOL LLPanelActiveSpeakers::postBuild() mSpeakerList->setCommitCallback(onSelectSpeaker); mSpeakerList->setCallbackUserData(this); - mMuteTextCtrl = (LLUICtrl*)getCtrlByNameAndType("mute_text_btn", WIDGET_TYPE_DONTCARE); + mMuteTextCtrl = getCtrlByNameAndType("mute_text_btn", WIDGET_TYPE_DONTCARE); childSetCommitCallback("mute_text_btn", onClickMuteTextCommit, this); - mMuteVoiceCtrl = (LLUICtrl*)getCtrlByNameAndType("mute_btn", WIDGET_TYPE_DONTCARE); + mMuteVoiceCtrl = getCtrlByNameAndType("mute_btn", WIDGET_TYPE_DONTCARE); childSetCommitCallback("mute_btn", onClickMuteVoiceCommit, this); childSetAction("mute_btn", onClickMuteVoice, this); @@ -509,7 +496,7 @@ void LLPanelActiveSpeakers::refreshSpeakers() if (speakerp->mIsModerator) { - speaker_name += LLString(" ") + getFormattedUIString("moderator_label"); + speaker_name += LLString(" ") + getString("moderator_label"); } name_cell->setValue(speaker_name); @@ -610,8 +597,7 @@ void LLPanelActiveSpeakers::setSpeaker(const LLUUID& id, const LLString& name, L void LLPanelActiveSpeakers::setVoiceModerationCtrlMode( const BOOL& moderated_voice) { - LLUICtrl* voice_moderation_ctrl = (LLUICtrl*) getChildByName( - "moderation_mode", TRUE); //recursive lookup + LLUICtrl* voice_moderation_ctrl = getCtrlByNameAndType("moderation_mode", WIDGET_TYPE_DONTCARE); if ( voice_moderation_ctrl ) { @@ -734,7 +720,7 @@ void LLPanelActiveSpeakers::onSelectSpeaker(LLUICtrl* source, void* user_data) void LLPanelActiveSpeakers::onModeratorMuteVoice(LLUICtrl* ctrl, void* user_data) { LLPanelActiveSpeakers* self = (LLPanelActiveSpeakers*)user_data; - LLUICtrl* speakers_list = (LLUICtrl*)self->getChildByName("speakers_list", TRUE); + LLUICtrl* speakers_list = self->getCtrlByNameAndType("speakers_list", WIDGET_TYPE_DONTCARE); if (!speakers_list || !gAgent.getRegion()) return; std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest"); @@ -799,7 +785,7 @@ void LLPanelActiveSpeakers::onModeratorMuteVoice(LLUICtrl* ctrl, void* user_data void LLPanelActiveSpeakers::onModeratorMuteText(LLUICtrl* ctrl, void* user_data) { LLPanelActiveSpeakers* self = (LLPanelActiveSpeakers*)user_data; - LLUICtrl* speakers_list = (LLUICtrl*)self->getChildByName("speakers_list", TRUE); + LLUICtrl* speakers_list = self->getCtrlByNameAndType("speakers_list", WIDGET_TYPE_DONTCARE); if (!speakers_list || !gAgent.getRegion()) return; std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest"); diff --git a/linden/indra/newview/llfloateractivespeakers.h b/linden/indra/newview/llfloateractivespeakers.h index 1088be3..55acbd7 100644 --- a/linden/indra/newview/llfloateractivespeakers.h +++ b/linden/indra/newview/llfloateractivespeakers.h @@ -47,8 +47,9 @@ class LLVoiceChannel; // data for a given participant in a voice channel -struct LLSpeaker : public LLRefCount, public LLObservable +class LLSpeaker : public LLRefCount, public LLObservable, public LLHandleProvider { +public: typedef enum e_speaker_type { SPEAKER_AGENT, @@ -67,8 +68,7 @@ struct LLSpeaker : public LLRefCount, public LLObservable LLSpeaker(const LLUUID& id, const LLString& name = LLString::null, const ESpeakerType type = SPEAKER_AGENT); - ~LLSpeaker(); - + ~LLSpeaker() {}; void lookupName(); static void onAvatarNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* user_data); @@ -83,14 +83,10 @@ struct LLSpeaker : public LLRefCount, public LLObservable LLUUID mID; BOOL mTyping; S32 mSortIndex; - LLViewHandle mHandle; ESpeakerType mType; BOOL mIsModerator; BOOL mModeratorMutedVoice; BOOL mModeratorMutedText; - - typedef std::map speaker_map_t; - static speaker_map_t sSpeakers; }; class LLSpeakerTextModerationEvent : public LLEvent @@ -179,13 +175,13 @@ protected: class LLFloaterActiveSpeakers : - public LLUISingleton, + public LLFloaterSingleton, public LLFloater, public LLVoiceClientParticipantObserver { // friend of singleton class to allow construction inside getInstance() since constructor is protected // to enforce singleton constraint - friend class LLUISingleton; + friend class LLUISingleton >; public: virtual ~LLFloaterActiveSpeakers(); diff --git a/linden/indra/newview/llfloateranimpreview.cpp b/linden/indra/newview/llfloateranimpreview.cpp index 0fed525..0b486b3 100644 --- a/linden/indra/newview/llfloateranimpreview.cpp +++ b/linden/indra/newview/llfloateranimpreview.cpp @@ -46,6 +46,7 @@ #include "llcombobox.h" #include "lldrawable.h" #include "lldrawpoolavatar.h" +#include "llglimmediate.h" #include "llface.h" #include "llkeyframemotion.h" #include "lllineeditor.h" @@ -280,7 +281,7 @@ BOOL LLFloaterAnimPreview::postBuild() childSetValue("hand_pose_combo", LLHandMotion::getHandPoseName(motionp->getHandPose())); childSetValue("ease_in_time", LLSD(motionp->getEaseInDuration())); childSetValue("ease_out_time", LLSD(motionp->getEaseOutDuration())); - mEnabled = TRUE; + setEnabled(TRUE); char seconds_string[128]; /*Flawfinder: ignore*/ snprintf(seconds_string, sizeof(seconds_string), " - %.2f seconds", motionp->getDuration()); /* Flawfinder: ignore */ @@ -291,8 +292,8 @@ BOOL LLFloaterAnimPreview::postBuild() delete mAnimPreview; mAnimPreview = NULL; mMotionID.setNull(); - childSetValue("bad_animation_text", childGetText("failed_to_initialize")); - mEnabled = FALSE; + childSetValue("bad_animation_text", getString("failed_to_initialize")); + setEnabled(FALSE); } } else @@ -301,20 +302,20 @@ BOOL LLFloaterAnimPreview::postBuild() { if (loaderp->getDuration() > MAX_ANIM_DURATION) { - LLUIString out_str = childGetText("anim_too_long"); + LLUIString out_str = getString("anim_too_long"); out_str.setArg("[LENGTH]", llformat("%.1f", loaderp->getDuration())); out_str.setArg("[MAX_LENGTH]", llformat("%.1f", MAX_ANIM_DURATION)); childSetValue("bad_animation_text", out_str.getString()); } else { - LLUIString out_str = childGetText("failed_file_read"); + LLUIString out_str = getString("failed_file_read"); out_str.setArg("[STATUS]", loaderp->getStatus()); // *TODO:Translate childSetValue("bad_animation_text", out_str.getString()); } } - mEnabled = FALSE; + setEnabled(FALSE); mMotionID.setNull(); mAnimPreview = NULL; } @@ -334,7 +335,7 @@ LLFloaterAnimPreview::~LLFloaterAnimPreview() delete mAnimPreview; mAnimPreview = NULL; - mEnabled = FALSE; + setEnabled(FALSE); } //----------------------------------------------------------------------------- @@ -349,21 +350,21 @@ void LLFloaterAnimPreview::draw() if (mMotionID.notNull() && mAnimPreview) { - glColor3f(1.f, 1.f, 1.f); + gGL.color3f(1.f, 1.f, 1.f); mAnimPreview->bindTexture(); - glBegin( GL_QUADS ); + gGL.begin( GL_QUADS ); { - glTexCoord2f(0.f, 1.f); - glVertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); - glTexCoord2f(0.f, 0.f); - glVertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - glTexCoord2f(1.f, 0.f); - glVertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - glTexCoord2f(1.f, 1.f); - glVertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); } - glEnd(); + gGL.end(); mAnimPreview->unbindTexture(); @@ -507,7 +508,7 @@ void LLFloaterAnimPreview::onMouseCaptureLost() void LLFloaterAnimPreview::onBtnPlay(void* user_data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)user_data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; if (previewp->mMotionID.notNull() && previewp->mAnimPreview) { @@ -538,7 +539,7 @@ void LLFloaterAnimPreview::onBtnPlay(void* user_data) void LLFloaterAnimPreview::onBtnStop(void* user_data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)user_data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; if (previewp->mMotionID.notNull() && previewp->mAnimPreview) { @@ -563,7 +564,7 @@ void LLFloaterAnimPreview::onBtnStop(void* user_data) void LLFloaterAnimPreview::onSliderMove(LLUICtrl* ctrl, void*user_data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)user_data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; if (previewp->mAnimPreview) { @@ -609,7 +610,7 @@ void LLFloaterAnimPreview::onCommitBaseAnim(LLUICtrl* ctrl, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; if (previewp->mAnimPreview) { @@ -639,7 +640,7 @@ void LLFloaterAnimPreview::onCommitLoop(LLUICtrl* ctrl, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar(); LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID); @@ -657,7 +658,7 @@ void LLFloaterAnimPreview::onCommitLoop(LLUICtrl* ctrl, void* data) void LLFloaterAnimPreview::onCommitLoopIn(LLUICtrl* ctrl, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar(); LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID); @@ -677,7 +678,7 @@ void LLFloaterAnimPreview::onCommitLoopIn(LLUICtrl* ctrl, void* data) void LLFloaterAnimPreview::onCommitLoopOut(LLUICtrl* ctrl, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar(); LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID); @@ -697,7 +698,7 @@ void LLFloaterAnimPreview::onCommitLoopOut(LLUICtrl* ctrl, void* data) void LLFloaterAnimPreview::onCommitName(LLUICtrl* ctrl, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar(); LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID); @@ -716,7 +717,7 @@ void LLFloaterAnimPreview::onCommitName(LLUICtrl* ctrl, void* data) void LLFloaterAnimPreview::onCommitHandPose(LLUICtrl* ctrl, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar(); LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID); @@ -731,7 +732,7 @@ void LLFloaterAnimPreview::onCommitHandPose(LLUICtrl* ctrl, void* data) void LLFloaterAnimPreview::onCommitEmote(LLUICtrl* ctrl, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar(); LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID); @@ -746,7 +747,7 @@ void LLFloaterAnimPreview::onCommitEmote(LLUICtrl* ctrl, void* data) void LLFloaterAnimPreview::onCommitPriority(LLUICtrl* ctrl, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar(); LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID); @@ -760,7 +761,7 @@ void LLFloaterAnimPreview::onCommitPriority(LLUICtrl* ctrl, void* data) void LLFloaterAnimPreview::onCommitEaseIn(LLUICtrl* ctrl, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar(); LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID); @@ -775,7 +776,7 @@ void LLFloaterAnimPreview::onCommitEaseIn(LLUICtrl* ctrl, void* data) void LLFloaterAnimPreview::onCommitEaseOut(LLUICtrl* ctrl, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return; + if (!previewp->getEnabled()) return; LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar(); LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID); @@ -791,7 +792,7 @@ BOOL LLFloaterAnimPreview::validateEaseIn(LLUICtrl* spin, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return FALSE; + if (!previewp->getEnabled()) return FALSE; LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar(); LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID); @@ -812,7 +813,7 @@ BOOL LLFloaterAnimPreview::validateEaseOut(LLUICtrl* spin, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return FALSE; + if (!previewp->getEnabled()) return FALSE; LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar(); LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID); @@ -833,7 +834,7 @@ BOOL LLFloaterAnimPreview::validateLoopIn(LLUICtrl* ctrl, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return FALSE; + if (!previewp->getEnabled()) return FALSE; F32 loop_in_value = (F32)previewp->childGetValue("loop_in_point").asReal(); F32 loop_out_value = (F32)previewp->childGetValue("loop_out_point").asReal(); @@ -862,7 +863,7 @@ BOOL LLFloaterAnimPreview::validateLoopOut(LLUICtrl* spin, void* data) { LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data; - if (!previewp->mEnabled) return FALSE; + if (!previewp->getEnabled()) return FALSE; F32 loop_out_value = (F32)previewp->childGetValue("loop_out_point").asReal(); F32 loop_in_value = (F32)previewp->childGetValue("loop_in_point").asReal(); @@ -947,7 +948,7 @@ void LLFloaterAnimPreview::refresh() void LLFloaterAnimPreview::onBtnOK(void* userdata) { LLFloaterAnimPreview* floaterp = (LLFloaterAnimPreview*)userdata; - if (!floaterp->mEnabled) return; + if (!floaterp->getEnabled()) return; if (floaterp->mAnimPreview) { @@ -1040,25 +1041,27 @@ BOOL LLPreviewAnimation::render() LLVOAvatar* avatarp = mDummyAvatar; glMatrixMode(GL_PROJECTION); - glPushMatrix(); + gGL.pushMatrix(); glLoadIdentity(); glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gGL.pushMatrix(); glLoadIdentity(); LLGLSUIDefault def; LLGLSNoTexture gls_no_texture; - glColor4f(0.15f, 0.2f, 0.3f, 1.f); + gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); gl_rect_2d_simple( mWidth, mHeight ); glMatrixMode(GL_PROJECTION); - glPopMatrix(); + gGL.popMatrix(); glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gGL.popMatrix(); + + gGL.stop(); LLVector3 target_pos = avatarp->mRoot.getWorldPosition(); @@ -1105,7 +1108,8 @@ BOOL LLPreviewAnimation::render() LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool(); avatarPoolp->renderAvatars(avatarp); // renders only one avatar } - + + gGL.start(); return TRUE; } @@ -1153,3 +1157,4 @@ void LLPreviewAnimation::pan(F32 right, F32 up) } + diff --git a/linden/indra/newview/llfloaterauction.cpp b/linden/indra/newview/llfloaterauction.cpp index b2eae43..100e4dc 100644 --- a/linden/indra/newview/llfloaterauction.cpp +++ b/linden/indra/newview/llfloaterauction.cpp @@ -123,7 +123,7 @@ void LLFloaterAuction::initialize() mParcelHost.invalidate(); if(parcelp && parcelp->getForSale()) { - childSetText("parcel_text", childGetText("already for sale")); + childSetText("parcel_text", getString("already for sale")); } else { @@ -176,7 +176,7 @@ void LLFloaterAuction::onClickSnapshot(void* data) BOOL success = gViewerWindow->rawSnapshot(raw, gViewerWindow->getWindowWidth(), gViewerWindow->getWindowHeight(), - TRUE, + TRUE, FALSE, FALSE, FALSE); gForceRenderLandFence = FALSE; diff --git a/linden/indra/newview/llfloaterauction.h b/linden/indra/newview/llfloaterauction.h index 50c5aa0..cd18158 100644 --- a/linden/indra/newview/llfloaterauction.h +++ b/linden/indra/newview/llfloaterauction.h @@ -69,7 +69,7 @@ private: LLTransactionID mTransactionID; LLAssetID mImageID; LLPointer mImage; - LLHandle mParcelp; + LLSafeHandle mParcelp; S32 mParcelID; LLHost mParcelHost; }; diff --git a/linden/indra/newview/llfloateravatarinfo.cpp b/linden/indra/newview/llfloateravatarinfo.cpp index 2cd6ee2..a26299c 100644 --- a/linden/indra/newview/llfloateravatarinfo.cpp +++ b/linden/indra/newview/llfloateravatarinfo.cpp @@ -127,7 +127,7 @@ LLFloaterAvatarInfo::LLFloaterAvatarInfo(const std::string& name, const LLRect & mAvatarID( avatar_id ), mSuggestedOnlineStatus(ONLINE_STATUS_NO) { - mAutoFocus = TRUE; + setAutoFocus(TRUE); LLCallbackMap::map_t factory_map; @@ -244,8 +244,8 @@ void LLFloaterAvatarInfo::showFromProfile(const LLUUID &avatar_id, LLRect rect) { floater = new LLFloaterAvatarInfo("avatarinfo", FAI_RECT, avatar_id); - floater->translate(rect.mLeft - floater->mRect.mLeft + 16, - rect.mTop - floater->mRect.mTop - 16); + floater->translate(rect.mLeft - floater->getRect().mLeft + 16, + rect.mTop - floater->getRect().mTop - 16); floater->mPanelAvatarp->setAvatarID(avatar_id, "", ONLINE_STATUS_NO); } if (floater) diff --git a/linden/indra/newview/llfloateravatarpicker.cpp b/linden/indra/newview/llfloateravatarpicker.cpp index e7e8626..4d01bab 100644 --- a/linden/indra/newview/llfloateravatarpicker.cpp +++ b/linden/indra/newview/llfloateravatarpicker.cpp @@ -347,8 +347,9 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* LLString avatar_name; if (avatar_id.isNull()) { - self->childSetTextArg("NotFound", "[TEXT]", self->childGetText("Edit")); - avatar_name = self->childGetValue("NotFound").asString(); + LLString::format_map_t map; + map["[TEXT]"] = self->childGetText("Edit"); + avatar_name = self->getString("NotFound", map); self->mListNames->setEnabled(FALSE); } else diff --git a/linden/indra/newview/llfloateravatartextures.cpp b/linden/indra/newview/llfloateravatartextures.cpp index 31e2f11..d112ee2 100644 --- a/linden/indra/newview/llfloateravatartextures.cpp +++ b/linden/indra/newview/llfloateravatartextures.cpp @@ -67,26 +67,26 @@ LLFloaterAvatarTextures* LLFloaterAvatarTextures::show(const LLUUID &id) BOOL LLFloaterAvatarTextures::postBuild() { - mBakedHead = (LLTextureCtrl*)getChildByName("baked_head"); - mBakedEyes = (LLTextureCtrl*)getChildByName("baked_eyes"); - mBakedUpper = (LLTextureCtrl*)getChildByName("baked_upper_body"); - mBakedLower = (LLTextureCtrl*)getChildByName("baked_lower_body"); - mBakedSkirt = (LLTextureCtrl*)getChildByName("baked_skirt"); - mHair = (LLTextureCtrl*)getChildByName("hair"); - mMakeup = (LLTextureCtrl*)getChildByName("head_bodypaint"); - mEye = (LLTextureCtrl*)getChildByName("eye_texture"); - mShirt = (LLTextureCtrl*)getChildByName("shirt"); - mUpperTattoo = (LLTextureCtrl*)getChildByName("upper_bodypaint"); - mUpperJacket = (LLTextureCtrl*)getChildByName("upper_jacket"); - mGloves = (LLTextureCtrl*)getChildByName("gloves"); - mUndershirt = (LLTextureCtrl*)getChildByName("undershirt"); - mPants = (LLTextureCtrl*)getChildByName("pants"); - mLowerTattoo = (LLTextureCtrl*)getChildByName("lower_bodypaint"); - mShoes = (LLTextureCtrl*)getChildByName("shoes"); - mSocks = (LLTextureCtrl*)getChildByName("socks"); - mJacket = (LLTextureCtrl*)getChildByName("jacket"); - mUnderpants = (LLTextureCtrl*)getChildByName("underpants"); - mSkirt = (LLTextureCtrl*)getChildByName("skirt_texture"); + mBakedHead = getChild("baked_head"); + mBakedEyes = getChild("baked_eyes"); + mBakedUpper = getChild("baked_upper_body"); + mBakedLower = getChild("baked_lower_body"); + mBakedSkirt = getChild("baked_skirt"); + mHair = getChild("hair"); + mMakeup = getChild("head_bodypaint"); + mEye = getChild("eye_texture"); + mShirt = getChild("shirt"); + mUpperTattoo = getChild("upper_bodypaint"); + mUpperJacket = getChild("upper_jacket"); + mGloves = getChild("gloves"); + mUndershirt = getChild("undershirt"); + mPants = getChild("pants"); + mLowerTattoo = getChild("lower_bodypaint"); + mShoes = getChild("shoes"); + mSocks = getChild("socks"); + mJacket = getChild("jacket"); + mUnderpants = getChild("underpants"); + mSkirt = getChild("skirt_texture"); mTitle = getTitle(); childSetAction("Dump", onClickDump, this); @@ -142,16 +142,10 @@ void LLFloaterAvatarTextures::refresh() LLVOAvatar *avatarp = find_avatar(mID); if (avatarp) { - char firstname[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char lastname[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - if (gCacheName->getName(avatarp->getID(), firstname, lastname)) + std::string fullname; + if (gCacheName->getFullName(avatarp->getID(), fullname)) { - LLString name; - name.assign( firstname ); - name.append( " " ); - name.append( lastname ); - - setTitle(mTitle + ": " + name); + setTitle(mTitle + ": " + fullname); } update_texture_ctrl(avatarp, mBakedHead, LLVOAvatar::TEX_HEAD_BAKED); update_texture_ctrl(avatarp, mBakedEyes, LLVOAvatar::TEX_EYES_BAKED); diff --git a/linden/indra/newview/llfloaterbump.cpp b/linden/indra/newview/llfloaterbump.cpp index 4508702..d340112 100644 --- a/linden/indra/newview/llfloaterbump.cpp +++ b/linden/indra/newview/llfloaterbump.cpp @@ -37,13 +37,12 @@ #include "llscrolllistctrl.h" #include "llvieweruictrlfactory.h" +#include "llviewermessage.h" #include "llappviewer.h" // gPacificDaylightTime ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs ///---------------------------------------------------------------------------- -extern LLLinkedList gMeanCollisionList; - LLFloaterBump* LLFloaterBump::sInstance = NULL; ///---------------------------------------------------------------------------- @@ -83,9 +82,9 @@ void LLFloaterBump::show(void *contents) if (!list) return; list->deleteAllItems(); - if (gMeanCollisionList.isEmpty()) + if (gMeanCollisionList.empty()) { - LLString none_detected = sInstance->childGetText("none_detected"); + LLString none_detected = sInstance->getString("none_detected"); LLSD row; row["columns"][0]["value"] = none_detected; row["columns"][0]["font"] = "SansSerifBold"; @@ -93,10 +92,10 @@ void LLFloaterBump::show(void *contents) } else { - for (LLMeanCollisionData* mcd = gMeanCollisionList.getFirstData(); - mcd; - mcd = gMeanCollisionList.getNextData()) + for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin(); + iter != gMeanCollisionList.end(); ++iter) { + LLMeanCollisionData *mcd = *iter; LLFloaterBump::add(list, mcd); } } @@ -151,7 +150,7 @@ void LLFloaterBump::add(LLScrollListCtrl* list, LLMeanCollisionData* mcd) } // All above action strings are in XML file - LLUIString text = sInstance->childGetText(action); + LLUIString text = sInstance->getUIString(action); text.setArg("[TIME]", time); text.setArg("[FIRST]", mcd->mFirstName); text.setArg("[LAST]", mcd->mLastName); diff --git a/linden/indra/newview/llfloaterbuy.cpp b/linden/indra/newview/llfloaterbuy.cpp index 47d7ab5..95a7b41 100644 --- a/linden/indra/newview/llfloaterbuy.cpp +++ b/linden/indra/newview/llfloaterbuy.cpp @@ -121,11 +121,11 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) switch (sale_info.getSaleType()) { case LLSaleInfo::FS_ORIGINAL: - title = sInstance->childGetText("title_buy_text"); + title = sInstance->getString("title_buy_text"); break; case LLSaleInfo::FS_COPY: default: - title = sInstance->childGetText("title_buy_copy_text"); + title = sInstance->getString("title_buy_copy_text"); break; } title.setArg("[NAME]", node->mName); @@ -165,15 +165,15 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) LLString text = node->mName; if (!(next_owner_mask & PERM_COPY)) { - text.append(sInstance->childGetText("no_copy_text")); + text.append(sInstance->getString("no_copy_text")); } if (!(next_owner_mask & PERM_MODIFY)) { - text.append(sInstance->childGetText("no_modify_text")); + text.append(sInstance->getString("no_modify_text")); } if (!(next_owner_mask & PERM_TRANSFER)) { - text.append(sInstance->childGetText("no_transfer_text")); + text.append(sInstance->getString("no_transfer_text")); } row["columns"][1]["column"] = "text"; diff --git a/linden/indra/newview/llfloaterbuy.h b/linden/indra/newview/llfloaterbuy.h index 6c5dc79..ae3428c 100644 --- a/linden/indra/newview/llfloaterbuy.h +++ b/linden/indra/newview/llfloaterbuy.h @@ -71,7 +71,7 @@ protected: private: static LLFloaterBuy* sInstance; - LLHandle mObjectSelection; + LLSafeHandle mObjectSelection; LLSaleInfo mSaleInfo; }; diff --git a/linden/indra/newview/llfloaterbuycontents.cpp b/linden/indra/newview/llfloaterbuycontents.cpp index 1afc38f..d32a631 100644 --- a/linden/indra/newview/llfloaterbuycontents.cpp +++ b/linden/indra/newview/llfloaterbuycontents.cpp @@ -124,9 +124,7 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info) if (!node) return; if(node->mPermissions->isGroupOwned()) { - char group_name[MAX_STRING]; /*Flawfinder: ignore*/ - gCacheName->getGroupName(owner_id, group_name); - owner_name.assign(group_name); + gCacheName->getGroupName(owner_id, owner_name); } sInstance->childSetTextArg("contains_text", "[NAME]", node->mName); @@ -240,15 +238,15 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj, if (!(next_owner_mask & PERM_COPY)) { - text.append(childGetText("no_copy_text")); + text.append(getString("no_copy_text")); } if (!(next_owner_mask & PERM_MODIFY)) { - text.append(childGetText("no_modify_text")); + text.append(getString("no_modify_text")); } if (!(next_owner_mask & PERM_TRANSFER)) { - text.append(childGetText("no_transfer_text")); + text.append(getString("no_transfer_text")); } row["columns"][1]["column"] = "text"; diff --git a/linden/indra/newview/llfloaterbuycontents.h b/linden/indra/newview/llfloaterbuycontents.h index 3fecc43..bef789c 100644 --- a/linden/indra/newview/llfloaterbuycontents.h +++ b/linden/indra/newview/llfloaterbuycontents.h @@ -67,7 +67,7 @@ protected: protected: static LLFloaterBuyContents* sInstance; - LLHandle mObjectSelection; + LLSafeHandle mObjectSelection; LLSaleInfo mSaleInfo; }; diff --git a/linden/indra/newview/llfloaterbuycurrency.cpp b/linden/indra/newview/llfloaterbuycurrency.cpp index c3c7ffa..f4e1118 100644 --- a/linden/indra/newview/llfloaterbuycurrency.cpp +++ b/linden/indra/newview/llfloaterbuycurrency.cpp @@ -316,7 +316,7 @@ void LLFloaterBuyCurrencyUI::onClickBuy(void* data) LLFloaterBuyCurrencyUI* self = LLFloaterBuyCurrencyUI::soleInstance(false); if (self) { - self->mManager.buy(self->childGetText("buy_currency")); + self->mManager.buy(self->getString("buy_currency")); self->updateUI(); // JC: updateUI() doesn't get called again until progress is made // with transaction processing, so the "Purchase" button would be diff --git a/linden/indra/newview/llfloaterbuyland.cpp b/linden/indra/newview/llfloaterbuyland.cpp index 7681da5..2786a34 100644 --- a/linden/indra/newview/llfloaterbuyland.cpp +++ b/linden/indra/newview/llfloaterbuyland.cpp @@ -390,13 +390,13 @@ void LLFloaterBuyLandUI::updateParcelInfo() if (!mParcelValid) { - mCannotBuyReason= childGetText("no_land_selected"); + mCannotBuyReason = getString("no_land_selected"); return; } if (mParcel->getMultipleOwners()) { - mCannotBuyReason = childGetText("multiple_parcels_selected"); + mCannotBuyReason = getString("multiple_parcels_selected"); return; } @@ -454,13 +454,13 @@ void LLFloaterBuyLandUI::updateParcelInfo() bool haveEnoughCash = mParcelPrice <= mAgentCashBalance; S32 cashBuy = haveEnoughCash ? 0 : (mParcelPrice - mAgentCashBalance); mCurrency.setAmount(cashBuy, true); - mCurrency.setZeroMessage(haveEnoughCash ? childGetText("none_needed") : ""); + mCurrency.setZeroMessage(haveEnoughCash ? getString("none_needed") : ""); // checks that we can buy the land if(mIsForGroup && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED)) { - mCannotBuyReason = childGetText("cant_buy_for_group"); + mCannotBuyReason = getString("cant_buy_for_group"); return; } @@ -474,7 +474,7 @@ void LLFloaterBuyLandUI::updateParcelInfo() || (mParcelPrice == 0 && authorizedBuyer.isNull())) { - mCannotBuyReason = childGetText("parcel_not_for_sale"); + mCannotBuyReason = getString("parcel_not_for_sale"); return; } @@ -482,18 +482,18 @@ void LLFloaterBuyLandUI::updateParcelInfo() { if (mIsForGroup) { - mCannotBuyReason = childGetText("group_already_owns"); + mCannotBuyReason = getString("group_already_owns"); } else { - mCannotBuyReason = childGetText("you_already_own"); + mCannotBuyReason = getString("you_already_own"); } return; } if (!authorizedBuyer.isNull() && buyer != authorizedBuyer) { - mCannotBuyReason = childGetText("set_to_sell_to_other"); + mCannotBuyReason = getString("set_to_sell_to_other"); return; } } @@ -501,14 +501,14 @@ void LLFloaterBuyLandUI::updateParcelInfo() { if (mParcelActualArea == 0) { - mCannotBuyReason = childGetText("no_public_land"); + mCannotBuyReason = getString("no_public_land"); return; } if (mParcel->hasOthersSelected()) { // Policy: Must not have someone else's land selected - mCannotBuyReason = childGetText("not_owned_by_you"); + mCannotBuyReason = getString("not_owned_by_you"); return; } } @@ -521,39 +521,39 @@ void LLFloaterBuyLandUI::updateCovenantInfo() LLViewerRegion* region = gParcelMgr->getSelectionRegion(); if(!region) return; - LLTextBox* region_name = (LLTextBox*)getChildByName("region_name_text"); + LLTextBox* region_name = getChild("region_name_text"); if (region_name) { region_name->setText(region->getName()); } - LLTextBox* resellable_clause = (LLTextBox*)getChildByName("resellable_clause"); + LLTextBox* resellable_clause = getChild("resellable_clause"); if (resellable_clause) { if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) { - resellable_clause->setText(childGetText("can_not_resell")); + resellable_clause->setText(getString("can_not_resell")); } else { - resellable_clause->setText(childGetText("can_resell")); + resellable_clause->setText(getString("can_resell")); } } - LLTextBox* changeable_clause = (LLTextBox*)getChildByName("changeable_clause"); + LLTextBox* changeable_clause = getChild("changeable_clause"); if (changeable_clause) { if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) { - changeable_clause->setText(childGetText("can_change")); + changeable_clause->setText(getString("can_change")); } else { - changeable_clause->setText(childGetText("can_not_change")); + changeable_clause->setText(getString("can_not_change")); } } - LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)getChildByName("agree_covenant"); + LLCheckBoxCtrl* check = getChild("agree_covenant"); if(check) { check->set(false); @@ -562,7 +562,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo() check->setCommitCallback(onChangeAgreeCovenant); } - LLTextBox* box = (LLTextBox*)getChildByName("covenant_text"); + LLTextBox* box = getChild("covenant_text"); if(box) { box->setVisible(FALSE); @@ -589,14 +589,14 @@ void LLFloaterBuyLandUI::onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data) void LLFloaterBuyLandUI::updateCovenantText(const std::string &string, const LLUUID& asset_id) { - LLViewerTextEditor* editor = (LLViewerTextEditor*)getChildByName("covenant_editor"); + LLViewerTextEditor* editor = getChild("covenant_editor"); if (editor) { editor->setHandleEditKeysDirectly(FALSE); editor->setText(string); - LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)getChildByName("agree_covenant"); - LLTextBox* box = (LLTextBox*)getChildByName("covenant_text"); + LLCheckBoxCtrl* check = getChild("agree_covenant"); + LLTextBox* box = getChild("covenant_text"); if(check && box) { if (asset_id.isNull()) @@ -621,19 +621,19 @@ void LLFloaterBuyLandUI::updateCovenantText(const std::string &string, const LLU void LLFloaterBuyLandUI::updateEstateName(const std::string& name) { - LLTextBox* box = (LLTextBox*)getChildByName("estate_name_text"); + LLTextBox* box = getChild("estate_name_text"); if (box) box->setText(name); } void LLFloaterBuyLandUI::updateLastModified(const std::string& text) { - LLTextBox* editor = (LLTextBox*)getChildByName("covenant_timestamp_text"); + LLTextBox* editor = getChild("covenant_timestamp_text"); if (editor) editor->setText(text); } void LLFloaterBuyLandUI::updateEstateOwnerName(const std::string& name) { - LLTextBox* box = (LLTextBox*)getChildByName("estate_owner_text"); + LLTextBox* box = getChild("estate_owner_text"); if (box) box->setText(name); } @@ -819,18 +819,11 @@ void LLFloaterBuyLandUI::updateNames() } else if (parcelp->getIsGroupOwned()) { - char groupName[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - - gCacheName->getGroupName(parcelp->getGroupID(), &groupName[0]); - mParcelSellerName = groupName; + gCacheName->getGroupName(parcelp->getGroupID(), mParcelSellerName); } else { - char firstName[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char lastName[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - - gCacheName->getName(parcelp->getOwnerID(), firstName, lastName); - mParcelSellerName = llformat("%s %s", firstName, lastName); + gCacheName->getFullName(parcelp->getOwnerID(), mParcelSellerName); } } @@ -908,7 +901,7 @@ void LLFloaterBuyLandUI::tellUserError( { mCanBuy = false; mCannotBuyIsError = true; - mCannotBuyReason = childGetText("fetching_error"); + mCannotBuyReason = getString("fetching_error"); mCannotBuyReason += message; mCannotBuyURI = uri; } @@ -998,17 +991,15 @@ void LLFloaterBuyLandUI::refreshUI() mParcelValid ? mParcelSnapshot : LLUUID::null); } - - if (mParcelValid) { childSetText("info_parcel", mParcelLocation); - - childSetTextArg("meters_supports_object", "[AMOUNT]", llformat("%d", mParcelActualArea)); - childSetTextArg("meters_supports_object", "[AMOUNT2]", llformat("%d", mParcelSupportedObjects)); - - childSetText("info_size", childGetText("meters_supports_object")); + LLString::format_map_t string_args; + string_args["[AMOUNT]"] = llformat("%d", mParcelActualArea); + string_args["[AMOUNT2]"] = llformat("%d", mParcelSupportedObjects); + + childSetText("info_size", getString("meters_supports_object", string_args)); childSetText("info_price", @@ -1022,7 +1013,7 @@ void LLFloaterBuyLandUI::refreshUI() } else { - childSetText("info_parcel", childGetText("no_parcel_selected")); + childSetText("info_parcel", getString("no_parcel_selected")); childSetText("info_size", LLString::null); childSetText("info_price", LLString::null); } @@ -1031,12 +1022,12 @@ void LLFloaterBuyLandUI::refreshUI() mCanBuy ? mIsForGroup - ? childGetText("buying_for_group")//"Buying land for group:" - : childGetText("buying_will")//"Buying this land will:" + ? getString("buying_for_group")//"Buying land for group:" + : getString("buying_will")//"Buying this land will:" : mCannotBuyIsError - ? childGetText("cannot_buy_now")//"Cannot buy now:" - : childGetText("not_for_sale")//"Not for sale:" + ? getString("cannot_buy_now")//"Cannot buy now:" + : getString("not_for_sale")//"Not for sale:" ); } @@ -1081,8 +1072,8 @@ void LLFloaterBuyLandUI::refreshUI() childSetText("account_action", mSiteMembershipAction); childSetText("account_reason", mSiteMembershipUpgrade - ? childGetText("must_upgrade") - : childGetText("cant_own_land") + ? getString("must_upgrade") + : getString("cant_own_land") ); LLComboBox* levels = LLUICtrlFactory::getComboBoxByName(this, "account_level"); @@ -1127,18 +1118,17 @@ void LLFloaterBuyLandUI::refreshUI() if (mIsForGroup) { - childSetTextArg("insufficient_land_credits", "[GROUP]", LLString(gAgent.mGroupName)); + LLString::format_map_t string_args; + string_args["[GROUP]"] = LLString(gAgent.mGroupName); - - message += childGetText("insufficient_land_credits"); + message += getString("insufficient_land_credits", string_args); } else { - - childSetTextArg("land_holdings", "[BUYER]", llformat("%d", mAgentCommittedTier)); - message += childGetText("land_holdings"); - + LLString::format_map_t string_args; + string_args["[BUYER]"] = llformat("%d", mAgentCommittedTier); + message += getString("land_holdings", string_args); } if (!mParcelValid) @@ -1147,21 +1137,24 @@ void LLFloaterBuyLandUI::refreshUI() } else if (mParcelBillableArea == mParcelActualArea) { - childSetTextArg("parcel_meters", "[AMOUNT]", llformat("%d", mParcelActualArea)); - message += childGetText("parcel_meters"); + LLString::format_map_t string_args; + string_args["[AMOUNT]"] = llformat("%d", mParcelActualArea); + message += getString("parcel_meters", string_args); } else { if (mParcelBillableArea > mParcelActualArea) { - childSetTextArg("premium_land", "[AMOUNT]", llformat("%d", mParcelBillableArea) ); - message += childGetText("premium_land"); + LLString::format_map_t string_args; + string_args["[AMOUNT]"] = llformat("%d", mParcelBillableArea); + message += getString("premium_land", string_args); } else { - childSetTextArg("discounted_land", "[AMOUNT]", llformat("%d", mParcelBillableArea) ); - message += childGetText("discounted_land"); + LLString::format_map_t string_args; + string_args["[AMOUNT]"] = llformat("%d", mParcelBillableArea); + message += getString("discounted_land", string_args); } } @@ -1208,35 +1201,36 @@ void LLFloaterBuyLandUI::refreshUI() if (haveEnough) { - - childSetTextArg("have_enough_lindens", "[AMOUNT]", llformat("%d", mAgentCashBalance)); - childSetText("currency_reason", childGetText("have_enough_lindens")); + LLString::format_map_t string_args; + string_args["[AMOUNT]"] = llformat("%d", mAgentCashBalance); + + childSetText("currency_reason", getString("have_enough_lindens", string_args)); } else { - childSetTextArg("not_enough_lindens", "[AMOUNT]", llformat("%d", mAgentCashBalance)); - childSetTextArg("not_enough_lindens", "[AMOUNT2]", llformat("%d", mParcelPrice - mAgentCashBalance)); + LLString::format_map_t string_args; + string_args["[AMOUNT]"] = llformat("%d", mAgentCashBalance); + string_args["[AMOUNT2]"] = llformat("%d", mParcelPrice - mAgentCashBalance); - childSetText("currency_reason", childGetText("not_enough_lindens")); + childSetText("currency_reason", getString("not_enough_lindens", string_args)); childSetTextArg("currency_est", "[AMOUNT2]", llformat("%#.2f", mCurrency.getEstimate() / 100.0)); - } if (willHaveEnough) { + LLString::format_map_t string_args; + string_args["[AMOUNT]"] = llformat("%d", finalBalance); - childSetTextArg("balance_left", "[AMOUNT]", llformat("%d", finalBalance)); - - childSetText("currency_balance", childGetText("balance_left")); + childSetText("currency_balance", getString("balance_left", string_args)); } else { + LLString::format_map_t string_args; + string_args["[AMOUNT]"] = llformat("%d", mParcelPrice - mAgentCashBalance); - childSetTextArg("balance_needed", "[AMOUNT]", llformat("%d", mParcelPrice - mAgentCashBalance)); - - childSetText("currency_balance", childGetText("balance_needed")); + childSetText("currency_balance", getString("balance_needed", string_args)); } @@ -1264,7 +1258,7 @@ void LLFloaterBuyLandUI::refreshUI() bool agrees_to_covenant = false; - LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)getChildByName("agree_covenant"); + LLCheckBoxCtrl* check = getChild("agree_covenant"); if (check) { agrees_to_covenant = check->get(); @@ -1298,17 +1292,17 @@ void LLFloaterBuyLandUI::startBuyPreConfirm() } if (mCurrency.getAmount() > 0) { + LLString::format_map_t string_args; + string_args["[AMOUNT]"] = llformat("%d", mCurrency.getAmount()); + string_args["[AMOUNT2]"] = llformat("%#.2f", mCurrency.getEstimate() / 100.0); - childSetTextArg("buy_for_US", "[AMOUNT]", llformat("%d", mCurrency.getAmount())); - childSetTextArg("buy_for_US", "[AMOUNT2]", llformat("%#.2f", mCurrency.getEstimate() / 100.0)); - - action += childGetText("buy_for_US"); + action += getString("buy_for_US", string_args); } - childSetTextArg("pay_to_for_land", "[AMOUNT]", llformat("%d", mParcelPrice)); - childSetTextArg("pay_to_for_land", "[SELLER]", mParcelSellerName); - - action += childGetText("pay_to_for_land"); + LLString::format_map_t string_args; + string_args["[AMOUNT]"] = llformat("%d", mParcelPrice); + string_args["[SELLER]"] = mParcelSellerName; + action += getString("pay_to_for_land", string_args); LLConfirmationManager::confirm(mSiteConfirm, @@ -1322,7 +1316,7 @@ void LLFloaterBuyLandUI::startBuyPostConfirm(const std::string& password) runWebSitePrep(password); mCanBuy = false; - mCannotBuyReason = childGetText("processing"); + mCannotBuyReason = getString("processing"); refreshUI(); } diff --git a/linden/indra/newview/llfloaterbuyland.h b/linden/indra/newview/llfloaterbuyland.h index 3b4d6fe..84ea909 100644 --- a/linden/indra/newview/llfloaterbuyland.h +++ b/linden/indra/newview/llfloaterbuyland.h @@ -40,7 +40,7 @@ class LLFloaterBuyLand { public: static void buyLand(LLViewerRegion* region, - LLHandle parcel, + LLSafeHandle parcel, bool is_for_group); static void updateCovenantText(const std::string& string, const LLUUID& asset_id); static void updateEstateName(const std::string& name); diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp index 89d60ad..f9063ce 100644 --- a/linden/indra/newview/llfloaterchat.cpp +++ b/linden/indra/newview/llfloaterchat.cpp @@ -128,7 +128,7 @@ void LLFloaterChat::draw() childSetValue("toggle_active_speakers_btn", childIsVisible("active_speakers_panel")); - LLChatBar* chat_barp = (LLChatBar*)getChildByName("chat_panel", TRUE); + LLChatBar* chat_barp = getChild("chat_panel", TRUE); if (chat_barp) { chat_barp->refresh(); @@ -142,7 +142,7 @@ BOOL LLFloaterChat::postBuild() { mPanel = (LLPanelActiveSpeakers*)LLUICtrlFactory::getPanelByName(this, "active_speakers_panel"); - LLChatBar* chat_barp = (LLChatBar*)getChildByName("chat_panel", TRUE); + LLChatBar* chat_barp = getChild("chat_panel", TRUE); if (chat_barp) { chat_barp->setGestureCombo(LLUICtrlFactory::getComboBoxByName(this, "Gesture")); @@ -221,8 +221,8 @@ void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file) // could flash the chat button in the status bar here. JC LLFloaterChat* chat_floater = LLFloaterChat::getInstance(LLSD()); - LLViewerTextEditor* history_editor = (LLViewerTextEditor*)chat_floater->getChildByName("Chat History Editor", TRUE); - LLViewerTextEditor* history_editor_with_mute = (LLViewerTextEditor*)chat_floater->getChildByName("Chat History Editor with mute", TRUE); + LLViewerTextEditor* history_editor = chat_floater->getChild("Chat History Editor"); + LLViewerTextEditor* history_editor_with_mute = chat_floater->getChild("Chat History Editor with mute"); history_editor->setParseHTML(TRUE); history_editor_with_mute->setParseHTML(TRUE); @@ -255,8 +255,8 @@ void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file) // static void LLFloaterChat::setHistoryCursorAndScrollToEnd() { - LLViewerTextEditor* history_editor = (LLViewerTextEditor*)LLFloaterChat::getInstance(LLSD())->getChildByName("Chat History Editor", TRUE); - LLViewerTextEditor* history_editor_with_mute = (LLViewerTextEditor*)LLFloaterChat::getInstance(LLSD())->getChildByName("Chat History Editor with mute", TRUE); + LLViewerTextEditor* history_editor = LLFloaterChat::getInstance(LLSD())->getChild("Chat History Editor"); + LLViewerTextEditor* history_editor_with_mute = LLFloaterChat::getInstance(LLSD())->getChild("Chat History Editor with mute"); if (history_editor) { @@ -299,8 +299,8 @@ void LLFloaterChat::onClickToggleShowMute(LLUICtrl* caller, void *data) //LLCheckBoxCtrl* BOOL show_mute = LLUICtrlFactory::getCheckBoxByName(floater,"show mutes")->get(); - LLViewerTextEditor* history_editor = (LLViewerTextEditor*)floater->getChildByName("Chat History Editor", TRUE); - LLViewerTextEditor* history_editor_with_mute = (LLViewerTextEditor*)floater->getChildByName("Chat History Editor with mute", TRUE); + LLViewerTextEditor* history_editor = floater->getChild("Chat History Editor"); + LLViewerTextEditor* history_editor_with_mute = floater->getChild("Chat History Editor with mute"); if (!history_editor || !history_editor_with_mute) return; @@ -455,26 +455,35 @@ void* LLFloaterChat::createChatPanel(void* data) return chatp; } +// static +void LLFloaterChat::onClickToggleActiveSpeakers(void* userdata) +{ + LLFloaterChat* self = (LLFloaterChat*)userdata; + + self->childSetVisible("active_speakers_panel", !self->childIsVisible("active_speakers_panel")); +} + +//static +bool LLFloaterChat::visible(LLFloater* instance, const LLSD& key) +{ + return VisibilityPolicy::visible(instance, key); +} + //static -void LLFloaterChat::hideInstance(const LLSD& id) +void LLFloaterChat::show(LLFloater* instance, const LLSD& key) { - LLFloaterChat* floaterp = LLFloaterChat::getInstance(LLSD()); + VisibilityPolicy::show(instance, key); +} - if(floaterp->getHost()) +//static +void LLFloaterChat::hide(LLFloater* instance, const LLSD& key) +{ + if(instance->getHost()) { - LLFloaterChatterBox::hideInstance(LLSD()); + LLFloaterChatterBox::hideInstance(); } else { - LLUISingleton::hideInstance(id); + VisibilityPolicy::hide(instance, key); } } - -// static -void LLFloaterChat::onClickToggleActiveSpeakers(void* userdata) -{ - LLFloaterChat* self = (LLFloaterChat*)userdata; - - self->childSetVisible("active_speakers_panel", !self->childIsVisible("active_speakers_panel")); -} - diff --git a/linden/indra/newview/llfloaterchat.h b/linden/indra/newview/llfloaterchat.h index 341e925..04eb279 100644 --- a/linden/indra/newview/llfloaterchat.h +++ b/linden/indra/newview/llfloaterchat.h @@ -50,7 +50,7 @@ class LLCheckBoxCtrl; class LLPanelActiveSpeakers; class LLFloaterChat -: public LLFloater, public LLUISingleton + : public LLFloater, public LLUISingleton { public: LLFloaterChat(const LLSD& seed); @@ -78,9 +78,12 @@ public: static void loadHistory(); static void* createSpeakersPanel(void* data); static void* createChatPanel(void* data); - static void hideInstance(const LLSD& id); -protected: + // visibility policy for LLUISingleton + static bool visible(LLFloater* instance, const LLSD& key); + static void show(LLFloater* instance, const LLSD& key); + static void hide(LLFloater* instance, const LLSD& key); + LLPanelActiveSpeakers* mPanel; BOOL mScrolledToEnd; }; diff --git a/linden/indra/newview/llfloaterchatterbox.cpp b/linden/indra/newview/llfloaterchatterbox.cpp index 2d6eeb3..88e0c5d 100644 --- a/linden/indra/newview/llfloaterchatterbox.cpp +++ b/linden/indra/newview/llfloaterchatterbox.cpp @@ -73,42 +73,6 @@ void LLFloaterMyFriends::onClose(bool app_quitting) setVisible(FALSE); } -//static -LLFloaterMyFriends* LLFloaterMyFriends::showInstance(const LLSD& id) -{ - LLFloaterMyFriends* floaterp = LLUIInstanceMgr::showInstance(id); - // garbage values in id will be interpreted as 0, or the friends tab - floaterp->mTabs->selectTab(id); - - return floaterp; -} - -//static -void LLFloaterMyFriends::hideInstance(const LLSD& id) -{ - LLFloaterMyFriends* floaterp = LLFloaterMyFriends::getInstance(); - - if(floaterp->getHost()) - { - LLFloaterChatterBox::hideInstance(); - } - else - { - LLUISingleton::hideInstance(id); - } -} - -// is the specified panel currently visible -//static -BOOL LLFloaterMyFriends::instanceVisible(const LLSD& id) -{ - // if singleton not created yet, trivially return false - if (!findInstance(id)) return FALSE; - - LLFloaterMyFriends* floaterp = getInstance(id); - return floaterp->isInVisibleChain() && floaterp->mTabs->getCurrentPanelIndex() == id.asInteger(); -} - //static void* LLFloaterMyFriends::createFriendsPanel(void* data) { @@ -271,7 +235,7 @@ void LLFloaterChatterBox::removeFloater(LLFloater* floaterp) void LLFloaterChatterBox::addFloater(LLFloater* floaterp, BOOL select_added_floater, - LLTabContainerCommon::eInsertionPoint insertion_point) + LLTabContainer::eInsertionPoint insertion_point) { S32 num_locked_tabs = mTabContainer->getNumLockedTabs(); @@ -322,48 +286,6 @@ void LLFloaterChatterBox::addFloater(LLFloater* floaterp, } } - -//static -LLFloaterChatterBox* LLFloaterChatterBox::showInstance(const LLSD& seed) -{ - LLFloaterChatterBox* chatterbox_floater = LLUISingleton::showInstance(seed); - - // if TRUE, show tab for active voice channel, otherwise, just show last tab - LLFloater* floater_to_show = NULL; - LLUUID session_id = seed.asUUID(); - if (session_id.notNull()) - { - floater_to_show = gIMMgr->findFloaterBySession(session_id); - } - - if (floater_to_show) - { - floater_to_show->open(); - } - else - { - // just open chatterbox to the last selected tab - chatterbox_floater->open(); - } - - return chatterbox_floater; -} - -//static -BOOL LLFloaterChatterBox::instanceVisible(const LLSD &seed) -{ - if (seed.asBoolean()) - { - LLFloater* floater_to_show = getCurrentVoiceFloater(); - if (floater_to_show) - { - return floater_to_show->isInVisibleChain(); - } - } - - return LLUISingleton::instanceVisible(seed); -} - //static LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater() { diff --git a/linden/indra/newview/llfloaterchatterbox.h b/linden/indra/newview/llfloaterchatterbox.h index 185cea3..93601ea 100644 --- a/linden/indra/newview/llfloaterchatterbox.h +++ b/linden/indra/newview/llfloaterchatterbox.h @@ -36,32 +36,12 @@ #include "llfloater.h" #include "llstring.h" +#include "llimview.h" +#include "llimpanel.h" -class LLTabContainerCommon; +class LLTabContainer; -class LLFloaterMyFriends : public LLFloater, public LLUISingleton -{ -public: - LLFloaterMyFriends(const LLSD& seed); - virtual ~LLFloaterMyFriends(); - - virtual BOOL postBuild(); - - void onClose(bool app_quitting); - - // override LLUISingleton behavior - static LLFloaterMyFriends* showInstance(const LLSD& id = LLSD()); - static void hideInstance(const LLSD& id); - static BOOL instanceVisible(const LLSD& id); - - static void* createFriendsPanel(void* data); - static void* createGroupsPanel(void* data); - -protected: - LLTabContainerCommon* mTabs; -}; - -class LLFloaterChatterBox : public LLMultiFloater, public LLUISingleton +class LLFloaterChatterBox : public LLMultiFloater, public LLUISingleton { public: LLFloaterChatterBox(const LLSD& seed); @@ -75,16 +55,103 @@ public: /*virtual*/ void removeFloater(LLFloater* floaterp); /*virtual*/ void addFloater(LLFloater* floaterp, BOOL select_added_floater, - LLTabContainerCommon::eInsertionPoint insertion_point = LLTabContainerCommon::END); - - static LLFloaterChatterBox* showInstance(const LLSD& seed = LLSD()); - static BOOL instanceVisible(const LLSD& seed); + LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END); static LLFloater* getCurrentVoiceFloater(); + + // visibility policy for LLUISingleton + static bool visible(LLFloater* instance, const LLSD& key) + { + LLFloater* floater_to_check = ((LLFloaterChatterBox*)instance)->getFloater(key); + + if (floater_to_check) + { + return floater_to_check->isInVisibleChain(); + } + + // otherwise use default visibility rule for chatterbox + return VisibilityPolicy::visible(instance, key); + } + + static void show(LLFloater* instance, const LLSD& key) + { + LLFloater* floater_to_show = ((LLFloaterChatterBox*)instance)->getFloater(key); + VisibilityPolicy::show(instance, key); + + if (floater_to_show) + { + floater_to_show->open(); + } + } + + static void hide(LLFloater* instance, const LLSD& key) + { + VisibilityPolicy::hide(instance, key); + } + +private: + LLFloater* getFloater(const LLSD& key) + { + LLFloater* floater = NULL; + + //try to show requested session + LLUUID session_id = key.asUUID(); + if (session_id.notNull()) + { + floater = LLIMMgr::getInstance()->findFloaterBySession(session_id); + } + + // if TRUE, show tab for active voice channel, otherwise, just show last tab + if (key.asBoolean()) + { + floater = getCurrentVoiceFloater(); + } + + return floater; + } protected: LLFloater* mActiveVoiceFloater; }; +class LLFloaterMyFriends : public LLFloater, public LLUISingleton +{ +public: + LLFloaterMyFriends(const LLSD& seed); + virtual ~LLFloaterMyFriends(); + + virtual BOOL postBuild(); + + void onClose(bool app_quitting); + + static void* createFriendsPanel(void* data); + static void* createGroupsPanel(void* data); + + // visibility policy for LLUISingleton + static bool visible(LLFloater* instance, const LLSD& key) + { + LLFloaterMyFriends* floaterp = (LLFloaterMyFriends*)instance; + return floaterp->isInVisibleChain() && floaterp->mTabs->getCurrentPanelIndex() == key.asInteger(); + } + + static void show(LLFloater* instance, const LLSD& key) + { + VisibilityPolicy::show(instance, key); + // garbage values in id will be interpreted as 0, or the friends tab + ((LLFloaterMyFriends*)instance)->mTabs->selectTab(key); + } + + static void hide(LLFloater* instance, const LLSD& key) + { + if (visible(instance, key)) + { + LLFloaterChatterBox::hideInstance(); + } + } + +protected: + LLTabContainer* mTabs; +}; + #endif // LL_LLFLOATERCHATTERBOX_H diff --git a/linden/indra/newview/llfloaterclassified.cpp b/linden/indra/newview/llfloaterclassified.cpp index 811cd3a..914b202 100644 --- a/linden/indra/newview/llfloaterclassified.cpp +++ b/linden/indra/newview/llfloaterclassified.cpp @@ -104,7 +104,7 @@ void LLFloaterClassifiedInfo::displayClassifiedInfo(const LLUUID& classified_id) void* LLFloaterClassifiedInfo::createClassifiedDetail(void* userdata) { LLFloaterClassifiedInfo *self = (LLFloaterClassifiedInfo*)userdata; - self->mClassifiedPanel = new LLPanelClassified(TRUE, TRUE); + self->mClassifiedPanel = new LLPanelClassified(true, true); self->mClassifiedPanel->childSetValue("classified_url", self->mClassifiedID); return self->mClassifiedPanel; } diff --git a/linden/indra/newview/llfloatercolorpicker.cpp b/linden/indra/newview/llfloatercolorpicker.cpp index 3787590..260db21 100644 --- a/linden/indra/newview/llfloatercolorpicker.cpp +++ b/linden/indra/newview/llfloatercolorpicker.cpp @@ -39,6 +39,7 @@ #include "llfontgl.h" #include "llsys.h" #include "llgl.h" +#include "llglimmediate.h" #include "v3dmath.h" #include "lldir.h" #include "llui.h" @@ -544,40 +545,40 @@ void LLFloaterColorPicker::draw() { LLGLSNoTexture no_texture; LLGLEnable(GL_CULL_FACE); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); - glVertex2i(swatch_rect.mLeft, swatch_rect.mTop); - glVertex2i(swatch_rect.mRight, swatch_rect.mTop); - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); - glVertex2i(local_rect.mRight, local_rect.mTop); - glVertex2i(local_rect.mLeft, local_rect.mTop); - - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); - glVertex2i(local_rect.mLeft, local_rect.mTop); - glVertex2i(local_rect.mLeft, local_rect.mBottom); - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); - glVertex2i(swatch_rect.mLeft, swatch_rect.mBottom); - glVertex2i(swatch_rect.mLeft, swatch_rect.mTop); - - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); - glVertex2i(local_rect.mRight, local_rect.mBottom); - glVertex2i(local_rect.mRight, local_rect.mTop); - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); - glVertex2i(swatch_rect.mRight, swatch_rect.mTop); - glVertex2i(swatch_rect.mRight, swatch_rect.mBottom); - - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); - glVertex2i(local_rect.mLeft, local_rect.mBottom); - glVertex2i(local_rect.mRight, local_rect.mBottom); - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); - glVertex2i(swatch_rect.mRight, swatch_rect.mBottom); - glVertex2i(swatch_rect.mLeft, swatch_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); + gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop); + gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop); + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); + gGL.vertex2i(local_rect.mRight, local_rect.mTop); + gGL.vertex2i(local_rect.mLeft, local_rect.mTop); + + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); + gGL.vertex2i(local_rect.mLeft, local_rect.mTop); + gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); + gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom); + gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop); + + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); + gGL.vertex2i(local_rect.mRight, local_rect.mBottom); + gGL.vertex2i(local_rect.mRight, local_rect.mTop); + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); + gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop); + gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom); + + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); + gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); + gGL.vertex2i(local_rect.mRight, local_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); + gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom); + gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom); } - glEnd(); + gGL.end(); } - if (gFocusMgr.childHasMouseCapture(mDragHandle)) + if (gFocusMgr.childHasMouseCapture(getDragHandle())) { mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); } @@ -672,9 +673,9 @@ void LLFloaterColorPicker::draw() ////////////////////////////////////////////////////////////////////////////// // find a complimentary color to the one passed in that can be used to highlight -LLColor4& +const LLColor4& LLFloaterColorPicker:: -getComplimentaryColor ( LLColor4& backgroundColor ) +getComplimentaryColor ( const LLColor4& backgroundColor ) { // going to base calculation on luminance F32 hVal, sVal, lVal; @@ -902,104 +903,103 @@ BOOL LLFloaterColorPicker:: handleMouseDown ( S32 x, S32 y, MASK mask ) { - // if this window is in the foreground - if ( mForeground ) - { + BOOL ret = LLFloater::handleMouseDown ( x, y, mask ); + // make it the frontmost - gFloaterView->bringToFront(this); + gFloaterView->bringToFront(this); - // rect containing RGB area - LLRect rgbAreaRect ( mRGBViewerImageLeft, - mRGBViewerImageTop, - mRGBViewerImageLeft + mRGBViewerImageWidth, - mRGBViewerImageTop - mRGBViewerImageHeight ); + // rect containing RGB area + LLRect rgbAreaRect ( mRGBViewerImageLeft, + mRGBViewerImageTop, + mRGBViewerImageLeft + mRGBViewerImageWidth, + mRGBViewerImageTop - mRGBViewerImageHeight ); - if ( rgbAreaRect.pointInRect ( x, y ) ) - { - gViewerWindow->setMouseCapture(this); - // mouse button down - setMouseDownInHueRegion ( TRUE ); + if ( rgbAreaRect.pointInRect ( x, y ) ) + { + gViewerWindow->setMouseCapture(this); + // mouse button down + setMouseDownInHueRegion ( TRUE ); - // update all values based on initial click - updateRgbHslFromPoint ( x, y ); + // update all values based on initial click + updateRgbHslFromPoint ( x, y ); - // required by base class - return TRUE; - } + // required by base class + return TRUE; + } - // rect containing RGB area - LLRect lumAreaRect ( mLumRegionLeft, - mLumRegionTop, - mLumRegionLeft + mLumRegionWidth + mLumMarkerSize, - mLumRegionTop - mLumRegionHeight ); + // rect containing RGB area + LLRect lumAreaRect ( mLumRegionLeft, + mLumRegionTop, + mLumRegionLeft + mLumRegionWidth + mLumMarkerSize, + mLumRegionTop - mLumRegionHeight ); - if ( lumAreaRect.pointInRect ( x, y ) ) - { - gViewerWindow->setMouseCapture(this); - // mouse button down - setMouseDownInLumRegion ( TRUE ); + if ( lumAreaRect.pointInRect ( x, y ) ) + { + gViewerWindow->setMouseCapture(this); + // mouse button down + setMouseDownInLumRegion ( TRUE ); - // required by base class - return TRUE; - } + // required by base class + return TRUE; + } - // rect containing swatch area - LLRect swatchRect ( mSwatchRegionLeft, - mSwatchRegionTop, - mSwatchRegionLeft + mSwatchRegionWidth, - mSwatchRegionTop - mSwatchRegionHeight ); + // rect containing swatch area + LLRect swatchRect ( mSwatchRegionLeft, + mSwatchRegionTop, + mSwatchRegionLeft + mSwatchRegionWidth, + mSwatchRegionTop - mSwatchRegionHeight ); - setMouseDownInSwatch( FALSE ); - if ( swatchRect.pointInRect ( x, y ) ) - { - setMouseDownInSwatch( TRUE ); + setMouseDownInSwatch( FALSE ); + if ( swatchRect.pointInRect ( x, y ) ) + { + setMouseDownInSwatch( TRUE ); - // required - dont drag windows here. - return TRUE; - } + // required - dont drag windows here. + return TRUE; + } - // rect containing palette area - LLRect paletteRect ( mPaletteRegionLeft, - mPaletteRegionTop, - mPaletteRegionLeft + mPaletteRegionWidth, - mPaletteRegionTop - mPaletteRegionHeight ); + // rect containing palette area + LLRect paletteRect ( mPaletteRegionLeft, + mPaletteRegionTop, + mPaletteRegionLeft + mPaletteRegionWidth, + mPaletteRegionTop - mPaletteRegionHeight ); - if ( paletteRect.pointInRect ( x, y ) ) + if ( paletteRect.pointInRect ( x, y ) ) + { + // release keyboard focus so we can change text values + if (gFocusMgr.childHasKeyboardFocus(this)) { - // release keyboard focus so we can change text values - if (gFocusMgr.childHasKeyboardFocus(this)) - { - mSelectBtn->setFocus(TRUE); - } - - // calculate which palette index we selected - S32 c = ( ( x - mPaletteRegionLeft ) * numPaletteColumns ) / mPaletteRegionWidth; - S32 r = ( ( y - ( mPaletteRegionTop - mPaletteRegionHeight ) ) * numPaletteRows ) / mPaletteRegionHeight; + mSelectBtn->setFocus(TRUE); + } - U32 index = ( numPaletteRows - r - 1 ) * numPaletteColumns + c; + // calculate which palette index we selected + S32 c = ( ( x - mPaletteRegionLeft ) * numPaletteColumns ) / mPaletteRegionWidth; + S32 r = ( ( y - ( mPaletteRegionTop - mPaletteRegionHeight ) ) * numPaletteRows ) / mPaletteRegionHeight; - if ( index <= mPalette.size () ) - { - LLColor4 selected = *mPalette [ index ]; + U32 index = ( numPaletteRows - r - 1 ) * numPaletteColumns + c; - setCurRgb ( selected [ 0 ], selected [ 1 ], selected [ 2 ] ); + if ( index <= mPalette.size () ) + { + LLColor4 selected = *mPalette [ index ]; - if (mApplyImmediateCheck->get()) - { - LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE ); - } + setCurRgb ( selected [ 0 ], selected [ 1 ], selected [ 2 ] ); - // HACK: turn off the call back wilst we update the text or we recurse ourselves into oblivion - enableTextCallbacks ( FALSE ); - updateTextEntry (); - enableTextCallbacks ( TRUE ); + if (mApplyImmediateCheck->get()) + { + LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE ); } - return TRUE; + // HACK: turn off the call back wilst we update the text or we recurse ourselves into oblivion + enableTextCallbacks ( FALSE ); + updateTextEntry (); + enableTextCallbacks ( TRUE ); } + + return TRUE; } + // dispatch to base class for the rest of things - return LLFloater::handleMouseDown ( x, y, mask ); + return ret; } ////////////////////////////////////////////////////////////////////////////// @@ -1163,7 +1163,7 @@ void LLFloaterColorPicker:: cancelSelection () { - // restore the previous colour selection + // restore the previous color selection setCurRgb ( getOrigR (), getOrigG (), getOrigB () ); // we're going away and when we do and the entry widgets lose focus, they do bad things so turn them off diff --git a/linden/indra/newview/llfloatercolorpicker.h b/linden/indra/newview/llfloatercolorpicker.h index 415f749..601bc83 100644 --- a/linden/indra/newview/llfloatercolorpicker.h +++ b/linden/indra/newview/llfloatercolorpicker.h @@ -134,7 +134,7 @@ class LLFloaterColorPicker void drawPalette (); // find a complimentary color to the one passed in that can be used to highlight - LLColor4& getComplimentaryColor ( LLColor4& backgroundColor ); + const LLColor4& getComplimentaryColor ( const LLColor4& backgroundColor ); // original RGB values F32 origR, origG, origB; diff --git a/linden/indra/newview/llfloatercustomize.cpp b/linden/indra/newview/llfloatercustomize.cpp index 8da5417..923c358 100644 --- a/linden/indra/newview/llfloatercustomize.cpp +++ b/linden/indra/newview/llfloatercustomize.cpp @@ -88,7 +88,7 @@ const F32 PARAM_STEP_TIME_THRESHOLD = 0.25f; // LLUndoWearable class LLUndoWearable -: public LLUndoAction + : public LLUndoBuffer::LLUndoAction { protected: LLAppearance mAppearance; @@ -230,12 +230,13 @@ public: LLVOAvatar* avatar = gAgent.getAvatarObject(); if( avatar ) { - for (LLViewerJointAttachment* attachment = avatar->mAttachmentPoints.getFirstData(); - attachment; - attachment = gAgent.getAvatarObject()->mAttachmentPoints.getNextData()) + for (LLVOAvatar::attachment_map_t::iterator iter = avatar->mAttachmentPoints.begin(); + iter != avatar->mAttachmentPoints.end(); ) { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + S32 attachment_pt = curiter->first; BOOL object_attached = ( attachment->getNumObjects() > 0 ); - S32 attachment_pt = avatar->mAttachmentPoints.getCurrentKeyWithoutIncrement(); LLString name = LLString("checkbox_") + attachment->getName(); mCheckBoxList.push_back(std::make_pair(name,attachment_pt)); childSetEnabled(name, object_attached); @@ -405,10 +406,10 @@ public: virtual void setVisible( BOOL visible ); // Inherted methods from LLEditMenuHandler - virtual void undo(); - virtual BOOL canUndo(); - virtual void redo(); - virtual BOOL canRedo(); + virtual void undo() { mUndoBuffer->undoAction(); } + virtual BOOL canUndo() const { return mUndoBuffer->canUndo(); } + virtual void redo() { mUndoBuffer->redoAction(); } + virtual BOOL canRedo() const { return mUndoBuffer->canRedo(); } // Callbacks static void onBtnSubpart( void* userdata ); @@ -992,26 +993,6 @@ void LLPanelEditWearable::addVisualParamToUndoBuffer( S32 param_id, F32 current_ action->setVisualParam( param_id, current_weight ); } -void LLPanelEditWearable::undo() -{ - mUndoBuffer->undoAction(); -} - -void LLPanelEditWearable::redo() -{ - mUndoBuffer->redoAction(); -} - -BOOL LLPanelEditWearable::canUndo() -{ - return mUndoBuffer->canUndo(); -} - -BOOL LLPanelEditWearable::canRedo() -{ - return mUndoBuffer->canRedo(); -} - void LLPanelEditWearable::switchToDefaultSubpart() { setSubpart( getDefaultSubpart() ); @@ -1294,10 +1275,10 @@ void LLScrollingPanelParam::draw() // Draw labels on top of the buttons childSetVisible( "min param text", TRUE ); - drawChild(getChildByName("min param text"), BTN_BORDER, BTN_BORDER); + drawChild(getChild("min param text"), BTN_BORDER, BTN_BORDER); childSetVisible( "max param text", TRUE ); - drawChild(getChildByName("max param text"), BTN_BORDER, BTN_BORDER); + drawChild(getChild("max param text"), BTN_BORDER, BTN_BORDER); } } @@ -1609,7 +1590,7 @@ BOOL LLFloaterCustomize::postBuild() // Remove underwear panels for teens if (gAgent.isTeen()) { - LLTabContainerCommon* tab_container = LLUICtrlFactory::getTabContainerByName(this, "customize tab container"); + LLTabContainer* tab_container = LLUICtrlFactory::getTabContainerByName(this, "customize tab container"); if (tab_container) { LLPanel* panel; @@ -1666,6 +1647,7 @@ void LLFloaterCustomize::onBtnSnapshot( void* userdata ) gViewerWindow->getWindowWidth(), gViewerWindow->getWindowHeight(), TRUE, // keep window aspect ratio + FALSE, FALSE, // UI in snapshot off FALSE); // do_rebuild off if (!success) return; @@ -2492,13 +2474,14 @@ void LLUndoWearable::applyUndoRedo() ESex old_sex = avatar->getSex(); // Parameters - for( F32* weightp = mAppearance.mParamMap.getFirstData(); weightp; weightp = mAppearance.mParamMap.getNextData() ) + for (LLAppearance::param_map_t::iterator iter = mAppearance.mParamMap.begin(); + iter != mAppearance.mParamMap.end(); ++iter) { - S32 param_id = mAppearance.mParamMap.getCurrentKeyWithoutIncrement(); - + S32 param_id = iter->first; + F32 weight = iter->second; F32 existing_weight = gAgent.getAvatarObject()->getVisualParamWeight( param_id ); - avatar->setVisualParamWeight(param_id, *weightp, TRUE); - *weightp = existing_weight; + avatar->setVisualParamWeight(param_id, weight, TRUE); + iter->second = existing_weight; } // Textures diff --git a/linden/indra/newview/llfloatercustomize.h b/linden/indra/newview/llfloatercustomize.h index bfb4556..96db2d2 100644 --- a/linden/indra/newview/llfloatercustomize.h +++ b/linden/indra/newview/llfloatercustomize.h @@ -38,7 +38,6 @@ #include "llstring.h" #include "v3dmath.h" #include "lltimer.h" -#include "doublelinkedlist.h" #include "llundo.h" #include "llviewermenu.h" #include "llvoavatar.h" diff --git a/linden/indra/newview/llfloaterdaycycle.cpp b/linden/indra/newview/llfloaterdaycycle.cpp new file mode 100644 index 0000000..29e4c37 --- /dev/null +++ b/linden/indra/newview/llfloaterdaycycle.cpp @@ -0,0 +1,612 @@ +/** + * @file llfloaterdaycycle.cpp + * @brief LLFloaterDayCycle class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterdaycycle.h" + +#include "pipeline.h" +#include "llsky.h" + +#include "llsliderctrl.h" +#include "llmultislider.h" +#include "llmultisliderctrl.h" +#include "llspinctrl.h" +#include "llcheckboxctrl.h" +#include "llvieweruictrlfactory.h" +#include "llviewercamera.h" +#include "llcombobox.h" +#include "lllineeditor.h" +#include "llwlanimator.h" + +#include "v4math.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" + +#include "llwlparamset.h" +#include "llwlparammanager.h" +#include "llpostprocess.h" +#include "llfloaterwindlight.h" + + +LLFloaterDayCycle* LLFloaterDayCycle::sDayCycle = NULL; +std::map LLFloaterDayCycle::sSliderToKey; +const F32 LLFloaterDayCycle::sHoursPerDay = 24.0f; + +LLFloaterDayCycle::LLFloaterDayCycle() : LLFloater("Day Cycle Floater") +{ + gUICtrlFactory->buildFloater(this, "floater_day_cycle_options.xml"); + + // add the combo boxes + LLComboBox* keyCombo = LLUICtrlFactory::getComboBoxByName(this, "WLKeyPresets"); + + if(keyCombo != NULL) + { + std::map::iterator mIt = + LLWLParamManager::instance()->mParamList.begin(); + for(; mIt != LLWLParamManager::instance()->mParamList.end(); mIt++) + { + keyCombo->add(LLString(mIt->first)); + } + + // set defaults on combo boxes + keyCombo->selectFirstItem(); + } + + // add the time slider + LLMultiSliderCtrl* sldr = LLUICtrlFactory::getMultiSliderByName(this, + "WLTimeSlider"); + + sldr->addSlider(); + + // load it up + initCallbacks(); +} + +LLFloaterDayCycle::~LLFloaterDayCycle() +{ +} + +void LLFloaterDayCycle::onClickHelp(void* data) +{ + + LLFloaterDayCycle* self = LLFloaterDayCycle::instance(); + + const char* xml_alert = (const char*) data; + LLAlertDialog* dialogp = gViewerWindow->alertXml(xml_alert); + if (dialogp) + { + LLFloater* root_floater = gFloaterView->getParentFloater(self); + if (root_floater) + { + root_floater->addDependentFloater(dialogp); + } + } +} + +void LLFloaterDayCycle::initHelpBtn(const char* name, const char* xml_alert) +{ + childSetAction(name, onClickHelp, (void*)xml_alert); +} + +void LLFloaterDayCycle::initCallbacks(void) +{ + initHelpBtn("WLDayCycleHelp", "HelpDayCycle"); + + // WL Day Cycle + childSetCommitCallback("WLTimeSlider", onTimeSliderMoved, NULL); + childSetCommitCallback("WLDayCycleKeys", onKeyTimeMoved, NULL); + childSetCommitCallback("WLCurKeyHour", onKeyTimeChanged, NULL); + childSetCommitCallback("WLCurKeyMin", onKeyTimeChanged, NULL); + childSetCommitCallback("WLKeyPresets", onKeyPresetChanged, NULL); + + childSetCommitCallback("WLLengthOfDayHour", onTimeRateChanged, NULL); + childSetCommitCallback("WLLengthOfDayMin", onTimeRateChanged, NULL); + childSetCommitCallback("WLLengthOfDaySec", onTimeRateChanged, NULL); + childSetAction("WLUseLindenTime", onUseLindenTime, NULL); + childSetAction("WLAnimSky", onRunAnimSky, NULL); + childSetAction("WLStopAnimSky", onStopAnimSky, NULL); + + childSetAction("WLLoadDayCycle", onLoadDayCycle, NULL); + childSetAction("WLSaveDayCycle", onSaveDayCycle, NULL); + + childSetAction("WLAddKey", onAddKey, NULL); + childSetAction("WLDeleteKey", onDeleteKey, NULL); +} + +void LLFloaterDayCycle::syncMenu() +{ +// std::map & currentParams = LLWLParamManager::instance()->mCurParams.mParamValues; + + // set time + LLMultiSliderCtrl* sldr = LLUICtrlFactory::getMultiSliderByName(LLFloaterDayCycle::sDayCycle, + "WLTimeSlider"); + sldr->setCurSliderValue((F32)LLWLParamManager::instance()->mAnimator.getDayTime() * sHoursPerDay); + + LLSpinCtrl* secSpin = LLUICtrlFactory::getSpinnerByName(sDayCycle, + "WLLengthOfDaySec"); + LLSpinCtrl* minSpin = LLUICtrlFactory::getSpinnerByName(sDayCycle, + "WLLengthOfDayMin"); + LLSpinCtrl* hourSpin = LLUICtrlFactory::getSpinnerByName(sDayCycle, + "WLLengthOfDayHour"); + + F32 curRate; + F32 hours, min, sec; + + // get the current rate + curRate = LLWLParamManager::instance()->mDay.mDayRate; + hours = (F32)((int)(curRate / 60 / 60)); + curRate -= (hours * 60 * 60); + min = (F32)((int)(curRate / 60)); + curRate -= (min * 60); + sec = curRate; + + hourSpin->setValue(hours); + minSpin->setValue(min); + secSpin->setValue(sec); + + // turn off Use Estate Time button if it's already being used + if( LLWLParamManager::instance()->mAnimator.mUseLindenTime == true) + { + LLFloaterDayCycle::sDayCycle->childDisable("WLUseLindenTime"); + } + else + { + LLFloaterDayCycle::sDayCycle->childEnable("WLUseLindenTime"); + } +} + +void LLFloaterDayCycle::syncSliderTrack() +{ + // clear the slider + LLMultiSliderCtrl* kSldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLDayCycleKeys"); + + kSldr->clear(); + sSliderToKey.clear(); + + // add sliders + std::map::iterator mIt = + LLWLParamManager::instance()->mDay.mTimeMap.begin(); + for(; mIt != LLWLParamManager::instance()->mDay.mTimeMap.end(); mIt++) + { + addSliderKey(mIt->first * sHoursPerDay, mIt->second.c_str()); + } +} + +void LLFloaterDayCycle::syncTrack() +{ + // if no keys, do nothing + if(sSliderToKey.size() == 0) + { + return; + } + + LLMultiSliderCtrl* sldr; + sldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLDayCycleKeys"); + llassert_always(sSliderToKey.size() == sldr->getValue().size()); + + LLMultiSliderCtrl* tSldr; + tSldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLTimeSlider"); + + // create a new animation track + LLWLParamManager::instance()->mDay.clearKeys(); + + // add the keys one by one + std::map::iterator mIt = sSliderToKey.begin(); + for(; mIt != sSliderToKey.end(); mIt++) + { + LLWLParamManager::instance()->mDay.addKey(mIt->second.time / sHoursPerDay, + mIt->second.presetName); + } + + // set the param manager's track to the new one + LLWLParamManager::instance()->resetAnimator( + tSldr->getCurSliderValue() / sHoursPerDay, false); + + LLWLParamManager::instance()->mAnimator.update( + LLWLParamManager::instance()->mCurParams); +} + +// static +LLFloaterDayCycle* LLFloaterDayCycle::instance() +{ + if (!sDayCycle) + { + sDayCycle = new LLFloaterDayCycle(); + sDayCycle->open(); + sDayCycle->setFocus(TRUE); + } + return sDayCycle; +} + +bool LLFloaterDayCycle::isOpen() +{ + if (sDayCycle != NULL) + { + return true; + } + return false; +} + +void LLFloaterDayCycle::show() +{ + LLFloaterDayCycle* dayCycle = instance(); + dayCycle->syncMenu(); + syncSliderTrack(); + + // comment in if you want the menu to rebuild each time + //gUICtrlFactory->buildFloater(dayCycle, "floater_day_cycle_options.xml"); + //dayCycle->initCallbacks(); + + dayCycle->open(); +} + +// virtual +void LLFloaterDayCycle::onClose(bool app_quitting) +{ + if (sDayCycle) + { + sDayCycle->setVisible(FALSE); + } +} + +void LLFloaterDayCycle::onRunAnimSky(void* userData) +{ + // if no keys, do nothing + if(sSliderToKey.size() == 0) + { + return; + } + + LLMultiSliderCtrl* sldr; + sldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLDayCycleKeys"); + llassert_always(sSliderToKey.size() == sldr->getValue().size()); + + LLMultiSliderCtrl* tSldr; + tSldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLTimeSlider"); + + // turn off linden time + LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + + // set the param manager's track to the new one + LLWLParamManager::instance()->resetAnimator( + tSldr->getCurSliderValue() / sHoursPerDay, true); + + llassert_always(LLWLParamManager::instance()->mAnimator.mTimeTrack.size() == sldr->getValue().size()); +} + +void LLFloaterDayCycle::onStopAnimSky(void* userData) +{ + // if no keys, do nothing + if(sSliderToKey.size() == 0) { + return; + } + + // turn off animation and using linden time + LLWLParamManager::instance()->mAnimator.mIsRunning = false; + LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; +} + +void LLFloaterDayCycle::onUseLindenTime(void* userData) +{ + LLFloaterWindLight* wl = LLFloaterWindLight::instance(); + LLComboBox* box = LLUICtrlFactory::getComboBoxByName(wl, "WLPresetsCombo"); + box->selectByValue(""); + + LLWLParamManager::instance()->mAnimator.mIsRunning = true; + LLWLParamManager::instance()->mAnimator.mUseLindenTime = true; +} + +void LLFloaterDayCycle::onLoadDayCycle(void* userData) +{ + LLWLParamManager::instance()->mDay.loadDayCycle("Default.xml"); + + // sync it all up + syncSliderTrack(); + syncMenu(); + + // set the param manager's track to the new one + LLMultiSliderCtrl* tSldr; + tSldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLTimeSlider"); + LLWLParamManager::instance()->resetAnimator( + tSldr->getCurSliderValue() / sHoursPerDay, false); + + // and draw it + LLWLParamManager::instance()->mAnimator.update( + LLWLParamManager::instance()->mCurParams); +} + +void LLFloaterDayCycle::onSaveDayCycle(void* userData) +{ + LLWLParamManager::instance()->mDay.saveDayCycle("Default.xml"); +} + + +void LLFloaterDayCycle::onTimeSliderMoved(LLUICtrl* ctrl, void* userData) +{ + LLMultiSliderCtrl* sldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLTimeSlider"); + + /// get the slider value + F32 val = sldr->getCurSliderValue() / sHoursPerDay; + + // set the value, turn off animation + LLWLParamManager::instance()->mAnimator.setDayTime((F64)val); + LLWLParamManager::instance()->mAnimator.mIsRunning = false; + LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + + // then call update once + LLWLParamManager::instance()->mAnimator.update( + LLWLParamManager::instance()->mCurParams); +} + +void LLFloaterDayCycle::onKeyTimeMoved(LLUICtrl* ctrl, void* userData) +{ + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(sDayCycle, + "WLKeyPresets"); + LLMultiSliderCtrl* sldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLDayCycleKeys"); + LLSpinCtrl* hourSpin = LLUICtrlFactory::getSpinnerByName(sDayCycle, + "WLCurKeyHour"); + LLSpinCtrl* minSpin = LLUICtrlFactory::getSpinnerByName(sDayCycle, + "WLCurKeyMin"); + + if(sldr->getValue().size() == 0) { + return; + } + + // make sure we have a slider + const LLString& curSldr = sldr->getCurSlider(); + if(curSldr == "") { + return; + } + + F32 time = sldr->getCurSliderValue(); + + // check to see if a key exists + LLString presetName = sSliderToKey[curSldr].presetName; + sSliderToKey[curSldr].time = time; + + // if it exists, turn on check box + comboBox->selectByValue(presetName); + + // now set the spinners + F32 hour = (F32)((S32)time); + F32 min = (time - hour) * 60; + + // handle imprecision + if(min >= 59) { + min = 0; + hour += 1; + } + + hourSpin->set(hour); + minSpin->set(min); + + syncTrack(); + +} + +void LLFloaterDayCycle::onKeyTimeChanged(LLUICtrl* ctrl, void* userData) +{ + // if no keys, skipped + if(sSliderToKey.size() == 0) { + return; + } + + LLMultiSliderCtrl* sldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLDayCycleKeys"); + LLSpinCtrl* hourSpin = LLUICtrlFactory::getSpinnerByName(sDayCycle, + "WLCurKeyHour"); + LLSpinCtrl* minSpin = LLUICtrlFactory::getSpinnerByName(sDayCycle, + "WLCurKeyMin"); + + F32 hour = hourSpin->get(); + F32 min = minSpin->get(); + F32 val = hour + min / 60.0f; + + const LLString& curSldr = sldr->getCurSlider(); + sldr->setCurSliderValue(val, TRUE); + F32 time = sldr->getCurSliderValue() / sHoursPerDay; + + // now set the key's time in the sliderToKey map + LLString presetName = sSliderToKey[curSldr].presetName; + sSliderToKey[curSldr].time = time; + + syncTrack(); +} + +void LLFloaterDayCycle::onKeyPresetChanged(LLUICtrl* ctrl, void* userData) +{ + // get the time + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(sDayCycle, + "WLKeyPresets"); + LLMultiSliderCtrl* sldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLDayCycleKeys"); + + // do nothing if no sliders + if(sldr->getValue().size() == 0) { + return; + } + + // change the map + LLString newPreset(comboBox->getSelectedValue().asString()); + const LLString& curSldr = sldr->getCurSlider(); + + // if null, don't use + if(curSldr == "") { + return; + } + + sSliderToKey[curSldr].presetName = newPreset; + + syncTrack(); +} + +void LLFloaterDayCycle::onTimeRateChanged(LLUICtrl* ctrl, void* userData) +{ + // get the time + LLSpinCtrl* secSpin = LLUICtrlFactory::getSpinnerByName(sDayCycle, + "WLLengthOfDaySec"); + + LLSpinCtrl* minSpin = LLUICtrlFactory::getSpinnerByName(sDayCycle, + "WLLengthOfDayMin"); + + LLSpinCtrl* hourSpin = LLUICtrlFactory::getSpinnerByName(sDayCycle, + "WLLengthOfDayHour"); + + F32 hour; + hour = (F32)hourSpin->getValue().asReal(); + F32 min; + min = (F32)minSpin->getValue().asReal(); + F32 sec; + sec = (F32)secSpin->getValue().asReal(); + + F32 time = 60.0f * 60.0f * hour + 60.0f * min + sec; + if(time <= 0) { + time = 1; + } + LLWLParamManager::instance()->mDay.mDayRate = time; + + syncTrack(); +} + +void LLFloaterDayCycle::onAddKey(void* userData) +{ + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(sDayCycle, + "WLKeyPresets"); + LLMultiSliderCtrl* kSldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLDayCycleKeys"); + LLMultiSliderCtrl* tSldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLTimeSlider"); + + llassert_always(sSliderToKey.size() == kSldr->getValue().size()); + + // get the values + LLString newPreset(comboBox->getSelectedValue().asString()); + + // add the slider key + addSliderKey(tSldr->getCurSliderValue(), newPreset); + + syncTrack(); +} + +void LLFloaterDayCycle::addSliderKey(F32 time, const LLString & presetName) +{ + LLMultiSliderCtrl* kSldr = LLUICtrlFactory::getMultiSliderByName(sDayCycle, + "WLDayCycleKeys"); + + // make a slider + const LLString& sldrName = kSldr->addSlider(time); + if(sldrName == "") { + return; + } + + // set the key + LLWLSkyKey newKey; + newKey.presetName = presetName; + newKey.time = kSldr->getCurSliderValue(); + + llassert_always(sldrName != LLString::null); + + // add to map + sSliderToKey.insert(std::pair(sldrName, newKey)); + + llassert_always(sSliderToKey.size() == kSldr->getValue().size()); + +} + +void LLFloaterDayCycle::deletePreset(LLString& presetName) +{ + LLMultiSliderCtrl* sldr = LLUICtrlFactory::getMultiSliderByName( + sDayCycle, "WLDayCycleKeys"); + + /// delete any reference + std::map::iterator curr_preset, next_preset; + for(curr_preset = sSliderToKey.begin(); curr_preset != sSliderToKey.end(); curr_preset = next_preset) + { + next_preset = curr_preset; + ++next_preset; + if (curr_preset->second.presetName == presetName) + { + sldr->deleteSlider(curr_preset->first); + sSliderToKey.erase(curr_preset); + } + } +} + +void LLFloaterDayCycle::onDeleteKey(void* userData) +{ + if(sSliderToKey.size() == 0) { + return; + } + + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(sDayCycle, + "WLKeyPresets"); + LLMultiSliderCtrl* sldr = LLUICtrlFactory::getMultiSliderByName( + sDayCycle, "WLDayCycleKeys"); + + // delete from map + const LLString& sldrName = sldr->getCurSlider(); + std::map::iterator mIt = sSliderToKey.find(sldrName); + sSliderToKey.erase(mIt); + + sldr->deleteCurSlider(); + + if(sSliderToKey.size() == 0) { + return; + } + + const LLString& name = sldr->getCurSlider(); + comboBox->selectByValue(sSliderToKey[name].presetName); + F32 time = sSliderToKey[name].time; + + LLSpinCtrl* hourSpin = LLUICtrlFactory::getSpinnerByName(sDayCycle, + "WLCurKeyHour"); + LLSpinCtrl* minSpin = LLUICtrlFactory::getSpinnerByName(sDayCycle, + "WLCurKeyMin"); + + // now set the spinners + F32 hour = (F32)((S32)time); + F32 min = (time - hour) / 60; + hourSpin->set(hour); + minSpin->set(min); + + syncTrack(); + +} diff --git a/linden/indra/newview/llfloaterdaycycle.h b/linden/indra/newview/llfloaterdaycycle.h new file mode 100644 index 0000000..edddbb5 --- /dev/null +++ b/linden/indra/newview/llfloaterdaycycle.h @@ -0,0 +1,146 @@ +/** + * @file llfloaterdaycycle.h + * @brief LLFloaterDayCycle class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERDAYCYCLE_H +#define LL_LLFLOATERDAYCYCLE_H + +#include "llfloater.h" + +#include +#include "llwlparamset.h" +#include "llwlanimator.h" + +struct WLColorControl; +struct WLFloatControl; + +/// convenience class for holding keys mapped to sliders +struct LLWLSkyKey +{ +public: + LLString presetName; + F32 time; +}; + +/// Menu for all of windlight's functionality. +/// Menuing system for adjusting the atmospheric settings of the world. +class LLFloaterDayCycle : public LLFloater +{ +public: + + LLFloaterDayCycle(); + virtual ~LLFloaterDayCycle(); + + /// help button stuff + static void onClickHelp(void* data); + void initHelpBtn(const char* name, const char* xml_alert); + + /// initialize all + void initCallbacks(void); + + /// one and one instance only + static LLFloaterDayCycle* instance(); + + /// on time slider moved + static void onTimeSliderMoved(LLUICtrl* ctrl, void* userData); + + /// what happens when you move the key frame + static void onKeyTimeMoved(LLUICtrl* ctrl, void* userData); + + /// what happens when you change the key frame's time + static void onKeyTimeChanged(LLUICtrl* ctrl, void* userData); + + /// if you change the combo box, change the frame + static void onKeyPresetChanged(LLUICtrl* ctrl, void* userData); + + /// run this when user says to run the sky animation + static void onRunAnimSky(void* userData); + + /// run this when user says to stop the sky animation + static void onStopAnimSky(void* userData); + + /// if you change the combo box, change the frame + static void onTimeRateChanged(LLUICtrl* ctrl, void* userData); + + /// add a new key on slider + static void onAddKey(void* userData); + + /// delete any and all reference to a preset + void deletePreset(LLString& presetName); + + /// delete a key frame + static void onDeleteKey(void* userData); + + /// button to load day + static void onLoadDayCycle(void* userData); + + /// button to save day + static void onSaveDayCycle(void* userData); + + /// toggle for Linden time + static void onUseLindenTime(void* userData); + + + //// menu management + + /// show off our menu + static void show(); + + /// return if the menu exists or not + static bool isOpen(); + + /// stuff to do on exit + virtual void onClose(bool app_quitting); + + /// sync up sliders with day cycle structure + static void syncMenu(); + + // makes sure key slider has what's in day cycle + static void syncSliderTrack(); + + /// makes sure day cycle data structure has what's in menu + static void syncTrack(); + + /// add a slider to the track + static void addSliderKey(F32 time, const LLString& presetName); + +private: + + // one instance on the inside + static LLFloaterDayCycle* sDayCycle; + + // map of sliders to parameters + static std::map sSliderToKey; + + static const F32 sHoursPerDay; +}; + + +#endif diff --git a/linden/indra/newview/llfloaterdirectory.cpp b/linden/indra/newview/llfloaterdirectory.cpp index ce5a7e6..7ac491e 100644 --- a/linden/indra/newview/llfloaterdirectory.cpp +++ b/linden/indra/newview/llfloaterdirectory.cpp @@ -223,7 +223,7 @@ void *LLFloaterDirectory::createFindAllOld(void* userdata) void* LLFloaterDirectory::createClassifiedDetail(void* userdata) { LLFloaterDirectory *self = (LLFloaterDirectory*)userdata; - self->mPanelClassifiedp = new LLPanelClassified(TRUE); + self->mPanelClassifiedp = new LLPanelClassified(true, false); self->mPanelClassifiedp->setVisible(FALSE); return self->mPanelClassifiedp; } @@ -378,7 +378,7 @@ void LLFloaterDirectory::refreshGroup(const LLUUID& group_id) void LLFloaterDirectory::focusCurrentPanel() { - LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName(this, "Directory Tabs"); + LLTabContainer* tabs = LLUICtrlFactory::getTabContainerByName(this, "Directory Tabs"); if (!tabs) return; LLPanel* panel = tabs->getCurrentPanel(); diff --git a/linden/indra/newview/llfloaterenvsettings.cpp b/linden/indra/newview/llfloaterenvsettings.cpp new file mode 100644 index 0000000..6a0400c --- /dev/null +++ b/linden/indra/newview/llfloaterenvsettings.cpp @@ -0,0 +1,384 @@ +/** + * @file llfloaterenvsettings.cpp + * @brief LLFloaterEnvSettings class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterenvsettings.h" + +#include "llfloaterwindlight.h" +#include "llfloaterwater.h" +#include "llvieweruictrlfactory.h" +#include "llsliderctrl.h" +#include "llcombobox.h" +#include "llcolorswatch.h" +#include "llwlanimator.h" + +#include "llwlparamset.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" +#include "llmath.h" +#include "llviewerwindow.h" + +#include "pipeline.h" + +#include + +LLFloaterEnvSettings* LLFloaterEnvSettings::sEnvSettings = NULL; + +LLFloaterEnvSettings::LLFloaterEnvSettings() : LLFloater("Environment Settings Floater") +{ + gUICtrlFactory->buildFloater(this, "floater_env_settings.xml"); + + // load it up + initCallbacks(); +} + +LLFloaterEnvSettings::~LLFloaterEnvSettings() +{ +} + +void LLFloaterEnvSettings::onClickHelp(void* data) +{ + LLFloaterEnvSettings* self = static_cast(data); + + const char* xml_alert = "EnvSettingsHelpButton"; + LLAlertDialog* dialogp = gViewerWindow->alertXml(xml_alert); + if (dialogp) + { + LLFloater* root_floater = gFloaterView->getParentFloater(self); + if (root_floater) + { + root_floater->addDependentFloater(dialogp); + } + } +} + +void LLFloaterEnvSettings::initCallbacks(void) +{ + // our three sliders + childSetCommitCallback("EnvTimeSlider", onChangeDayTime, NULL); + childSetCommitCallback("EnvCloudSlider", onChangeCloudCoverage, NULL); + childSetCommitCallback("EnvWaterFogSlider", onChangeWaterFogDensity, + &LLWaterParamManager::instance()->mFogDensity); + + // color picker + childSetCommitCallback("EnvWaterColor", onChangeWaterColor, + &LLWaterParamManager::instance()->mFogColor); + + // WL Top + childSetAction("EnvAdvancedSkyButton", onOpenAdvancedSky, NULL); + childSetAction("EnvAdvancedWaterButton", onOpenAdvancedWater, NULL); + childSetAction("EnvUseEstateTimeButton", onUseEstateTime, NULL); + childSetAction("EnvSettingsHelpButton", onClickHelp, this); +} + + +// menu maintenance functions + +void LLFloaterEnvSettings::syncMenu() +{ + LLSliderCtrl* sldr; + sldr = LLUICtrlFactory::getSliderByName(sEnvSettings, + "EnvTimeSlider"); + if(NULL == sldr) + { + return; + } + + // sync the clock + F32 val = (F32)LLWLParamManager::instance()->mAnimator.getDayTime(); + LLString timeStr = timeToString(val); + + LLTextBox* textBox; + textBox = LLUICtrlFactory::getTextBoxByName(sEnvSettings, + "EnvTimeText"); + if(NULL == textBox) + { + return; + } + + textBox->setValue(timeStr); + + // sync time slider which starts at 6 AM + val -= 0.25; + if(val < 0) + { + val++; + } + sldr->setValue(val); + + // sync cloud coverage + bool err; + childSetValue("EnvCloudSlider", LLWLParamManager::instance()->mCurParams.getFloat("cloud_shadow", err)); + + LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + // sync water params + LLColor4 col = param_mgr->getFogColor(); + LLColorSwatchCtrl* colCtrl = sEnvSettings->getChild("EnvWaterColor"); + col.mV[3] = 1.0f; + colCtrl->set(col); + + childSetValue("EnvWaterFogSlider", param_mgr->mFogDensity.mExp); + param_mgr->setDensitySliderValue(param_mgr->mFogDensity.mExp); + + // turn off Use Estate Time button if it's already being used + if(LLWLParamManager::instance()->mAnimator.mUseLindenTime) + { + childDisable("EnvUseEstateTimeButton"); + } else { + childEnable("EnvUseEstateTimeButton"); + } + + if(!gPipeline.canUseVertexShaders()) + { + childDisable("EnvWaterColor"); + childDisable("EnvWaterColorText"); + //childDisable("EnvAdvancedWaterButton"); + } + else + { + childEnable("EnvWaterColor"); + childEnable("EnvWaterColorText"); + //childEnable("EnvAdvancedWaterButton"); + } + + // only allow access to these if they are using windlight + if(!gPipeline.canUseWindLightShaders()) + { + + childDisable("EnvCloudSlider"); + childDisable("EnvCloudText"); + //childDisable("EnvAdvancedSkyButton"); + } + else + { + childEnable("EnvCloudSlider"); + childEnable("EnvCloudText"); + //childEnable("EnvAdvancedSkyButton"); + } +} + + +// static instance of it +LLFloaterEnvSettings* LLFloaterEnvSettings::instance() +{ + if (!sEnvSettings) + { + sEnvSettings = new LLFloaterEnvSettings(); + sEnvSettings->open(); + sEnvSettings->setFocus(TRUE); + } + return sEnvSettings; +} +void LLFloaterEnvSettings::show() +{ + LLFloaterEnvSettings* envSettings = instance(); + envSettings->syncMenu(); + + // comment in if you want the menu to rebuild each time + //gUICtrlFactory->buildFloater(envSettings, "floater_env_settings.xml"); + //envSettings->initCallbacks(); + + envSettings->open(); +} + +bool LLFloaterEnvSettings::isOpen() +{ + if (sEnvSettings != NULL) + { + return true; + } + return false; +} + +// virtual +void LLFloaterEnvSettings::onClose(bool app_quitting) +{ + if (sEnvSettings) + { + sEnvSettings->setVisible(FALSE); + } +} + + +void LLFloaterEnvSettings::onChangeDayTime(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldr; + sldr = LLUICtrlFactory::getSliderByName(sEnvSettings, + "EnvTimeSlider"); + + // deactivate animator + LLWLParamManager::instance()->mAnimator.mIsRunning = false; + LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + + F32 val = sldr->getValueF32() + 0.25f; + if(val > 1.0) + { + val--; + } + + LLWLParamManager::instance()->mAnimator.setDayTime((F64)val); + LLWLParamManager::instance()->mAnimator.update( + LLWLParamManager::instance()->mCurParams); +} + +void LLFloaterEnvSettings::onChangeCloudCoverage(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldr; + sldr = LLUICtrlFactory::getSliderByName(sEnvSettings, + "EnvCloudSlider"); + + // deactivate animator + //LLWLParamManager::instance()->mAnimator.mIsRunning = false; + //LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + + F32 val = sldr->getValueF32(); + LLWLParamManager::instance()->mCurParams.set("cloud_shadow", val); +} + +void LLFloaterEnvSettings::onChangeWaterFogDensity(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldr; + sldr = LLUICtrlFactory::getSliderByName(sEnvSettings, + "EnvWaterFogSlider"); + + if(NULL == sldr || NULL == userData) + { + return; + } + + WaterExpFloatControl * expFloatControl = static_cast(userData); + + F32 val = sldr->getValueF32(); + expFloatControl->mExp = val; + LLWaterParamManager::instance()->setDensitySliderValue(val); + + expFloatControl->update(LLWaterParamManager::instance()->mCurParams); + LLWaterParamManager::instance()->propagateParameters(); +} + +void LLFloaterEnvSettings::onChangeWaterColor(LLUICtrl* ctrl, void* userData) +{ + LLColorSwatchCtrl* swatch = static_cast(ctrl); + WaterColorControl * colorControl = static_cast(userData); + *colorControl = swatch->get(); + + colorControl->update(LLWaterParamManager::instance()->mCurParams); + LLWaterParamManager::instance()->propagateParameters(); +} + + +void LLFloaterEnvSettings::onOpenAdvancedSky(void* userData) +{ + LLFloaterWindLight::show(); +} + +void LLFloaterEnvSettings::onOpenAdvancedWater(void* userData) +{ + LLFloaterWater::show(); +} + + +void LLFloaterEnvSettings::onUseEstateTime(void* userData) +{ + if(LLFloaterWindLight::isOpen()) + { + // select the blank value in + LLFloaterWindLight* wl = LLFloaterWindLight::instance(); + LLComboBox* box = LLUICtrlFactory::getComboBoxByName(wl, "WLPresetsCombo"); + box->selectByValue(""); + } + + LLWLParamManager::instance()->mAnimator.mIsRunning = true; + LLWLParamManager::instance()->mAnimator.mUseLindenTime = true; +} + +LLString LLFloaterEnvSettings::timeToString(F32 curTime) +{ + S32 hours; + S32 min; + bool isPM = false; + + // get hours and minutes + hours = (S32) (24.0 * curTime); + curTime -= ((F32) hours / 24.0f); + min = llround(24.0f * 60.0f * curTime); + + // handle case where it's 60 + if(min == 60) + { + hours++; + min = 0; + } + + // set for PM + if(hours >= 12 && hours < 24) + { + isPM = true; + } + + // convert to non-military notation + if(hours >= 24) + { + hours = 12; + } + else if(hours > 12) + { + hours -= 12; + } + else if(hours == 0) + { + hours = 12; + } + + // make the string + std::stringstream newTime; + newTime << hours << ":"; + + // double 0 + if(min < 10) + { + newTime << 0; + } + + // finish it + newTime << min << " "; + if(isPM) + { + newTime << "PM"; + } + else + { + newTime << "AM"; + } + + return newTime.str(); +} diff --git a/linden/indra/newview/llfloaterenvsettings.h b/linden/indra/newview/llfloaterenvsettings.h new file mode 100644 index 0000000..63f6a98 --- /dev/null +++ b/linden/indra/newview/llfloaterenvsettings.h @@ -0,0 +1,106 @@ +/** + * @file llfloaterskysettings.h + * @brief LLFloaterEnvSettings class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* + * Simple menu for adjusting the atmospheric settings of the world + */ + +#ifndef LL_LLFLOATERENVSETTINGS_H +#define LL_LLFLOATERENVSETTINGS_H + +#include "llfloater.h" + + +/// Menuing system for all of windlight's functionality +class LLFloaterEnvSettings : public LLFloater +{ +public: + + LLFloaterEnvSettings(); + virtual ~LLFloaterEnvSettings(); + + /// initialize all the callbacks for the menu + void initCallbacks(void); + + /// one and one instance only + static LLFloaterEnvSettings* instance(); + + /// callback for the menus help button + static void onClickHelp(void* data); + + /// handle if time of day is changed + static void onChangeDayTime(LLUICtrl* ctrl, void* userData); + + /// handle if cloud coverage is changed + static void onChangeCloudCoverage(LLUICtrl* ctrl, void* userData); + + /// handle change in water fog density + static void onChangeWaterFogDensity(LLUICtrl* ctrl, void* userData); + + /// handle change in under water fog density + static void onChangeUnderWaterFogMod(LLUICtrl* ctrl, void* userData); + + /// handle change in water fog color + static void onChangeWaterColor(LLUICtrl* ctrl, void* userData); + + /// open the advanced sky settings menu + static void onOpenAdvancedSky(void* userData); + + /// open the advanced water settings menu + static void onOpenAdvancedWater(void* userData); + + /// sync time with the server + static void onUseEstateTime(void* userData); + + //// menu management + + /// show off our menu + static void show(); + + /// return if the menu exists or not + static bool isOpen(); + + /// stuff to do on exit + virtual void onClose(bool app_quitting); + + /// sync up sliders with parameters + void syncMenu(); + + /// convert the present time to a digital clock time + LLString timeToString(F32 curTime); + +private: + // one instance on the inside + static LLFloaterEnvSettings* sEnvSettings; +}; + + +#endif diff --git a/linden/indra/newview/llfloaterfriends.cpp b/linden/indra/newview/llfloaterfriends.cpp index 0de8698..3d2e60a 100644 --- a/linden/indra/newview/llfloaterfriends.cpp +++ b/linden/indra/newview/llfloaterfriends.cpp @@ -60,6 +60,7 @@ //Maximum number of people you can select to do an operation on at once. #define MAX_FRIEND_SELECT 20 +#define DEFAULT_PERIOD 5.0 #define RIGHTS_CHANGE_TIMEOUT 5.0 #define OBSERVER_TIMEOUT 0.5 @@ -80,7 +81,6 @@ public: // events can arrive quickly in bulk - we need not process EVERY one of them - // so we wait a short while to let others pile-in, and process them in aggregate. mEventTimer.start(); - mEventTimer.reset(); // save-up all the mask-bits which have come-in mMask |= mask; @@ -102,7 +102,7 @@ protected: LLPanelFriends::LLPanelFriends() : LLPanel(), - LLEventTimer(1000000), + LLEventTimer(DEFAULT_PERIOD), mObserver(NULL), mShowMaxSelectWarning(TRUE), mAllowRightsChange(TRUE), @@ -122,7 +122,7 @@ LLPanelFriends::~LLPanelFriends() BOOL LLPanelFriends::tick() { mEventTimer.stop(); - mPeriod = 1000000; + mPeriod = DEFAULT_PERIOD; mAllowRightsChange = TRUE; updateFriends(LLFriendObserver::ADD); return FALSE; @@ -152,7 +152,6 @@ void LLPanelFriends::updateFriends(U32 changed_mask) { mPeriod = RIGHTS_CHANGE_TIMEOUT; mEventTimer.start(); - mEventTimer.reset(); mAllowRightsChange = FALSE; } else @@ -208,17 +207,20 @@ BOOL LLPanelFriends::postBuild() } -void LLPanelFriends::addFriend(const std::string& name, const LLUUID& agent_id) +BOOL LLPanelFriends::addFriend(const LLUUID& agent_id) { LLAvatarTracker& at = LLAvatarTracker::instance(); const LLRelationship* relationInfo = at.getBuddyInfo(agent_id); - if(!relationInfo) return; + if(!relationInfo) return FALSE; BOOL online = relationInfo->isOnline(); + std::string fullname; + BOOL have_name = gCacheName->getFullName(agent_id, fullname); + LLSD element; element["id"] = agent_id; element["columns"][LIST_FRIEND_NAME]["column"] = "friend_name"; - element["columns"][LIST_FRIEND_NAME]["value"] = name.c_str(); + element["columns"][LIST_FRIEND_NAME]["value"] = fullname; element["columns"][LIST_FRIEND_NAME]["font"] = "SANSSERIF"; element["columns"][LIST_FRIEND_NAME]["font-style"] = "NORMAL"; element["columns"][LIST_ONLINE_STATUS]["column"] = "icon_online_status"; @@ -247,30 +249,39 @@ void LLPanelFriends::addFriend(const std::string& name, const LLUUID& agent_id) element["columns"][LIST_EDIT_THEIRS]["value"] = relationInfo->isRightGrantedFrom(LLRelationship::GRANT_MODIFY_OBJECTS); element["columns"][LIST_FRIEND_UPDATE_GEN]["column"] = "friend_last_update_generation"; - element["columns"][LIST_FRIEND_UPDATE_GEN]["value"] = relationInfo->getChangeSerialNum(); + element["columns"][LIST_FRIEND_UPDATE_GEN]["value"] = have_name ? relationInfo->getChangeSerialNum() : -1; mFriendsList->addElement(element, ADD_BOTTOM); + return have_name; } // propagate actual relationship to UI -void LLPanelFriends::updateFriendItem(LLScrollListItem* itemp, const LLRelationship* info) +BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationship* info) { - if (!itemp) return; - if (!info) return; + if (!info) return FALSE; + LLScrollListItem* itemp = mFriendsList->getItem(agent_id); + if (!itemp) return FALSE; + + std::string fullname; + BOOL have_name = gCacheName->getFullName(agent_id, fullname); itemp->getColumn(LIST_ONLINE_STATUS)->setValue(info->isOnline() ? gViewerArt.getString("icon_avatar_online.tga") : LLString()); + itemp->getColumn(LIST_FRIEND_NAME)->setValue(fullname); // render name of online friends in bold text ((LLScrollListText*)itemp->getColumn(LIST_FRIEND_NAME))->setFontStyle(info->isOnline() ? LLFontGL::BOLD : LLFontGL::NORMAL); itemp->getColumn(LIST_VISIBLE_ONLINE)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)); itemp->getColumn(LIST_VISIBLE_MAP)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION)); itemp->getColumn(LIST_EDIT_MINE)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS)); - itemp->getColumn(LIST_FRIEND_UPDATE_GEN)->setValue(info->getChangeSerialNum()); + S32 change_generation = have_name ? info->getChangeSerialNum() : -1; + itemp->getColumn(LIST_FRIEND_UPDATE_GEN)->setValue(change_generation); // enable this item, in case it was disabled after user input itemp->setEnabled(TRUE); // changed item in place, need to request sort mFriendsList->sortItems(); + + return have_name; } void LLPanelFriends::refreshRightsChangeList() @@ -354,7 +365,8 @@ void LLPanelFriends::refreshNames() std::vector::iterator item_it = items.begin(); std::vector::iterator item_end = items.end(); - + + BOOL have_names = TRUE; LLAvatarTracker::buddy_map_t::iterator buddy_it; for (buddy_it = all_buddies.begin() ; buddy_it != all_buddies.end(); ++buddy_it) { @@ -379,24 +391,24 @@ void LLPanelFriends::refreshNames() if (last_change_generation < info->getChangeSerialNum()) { // update existing item in UI - updateFriendItem(mFriendsList->getItem(buddy_it->first), info); + have_names &= updateFriendItem(buddy_it->first, info); } ++item_it; } // add new friend to list else { - const LLUUID& buddy_id = buddy_it->first; - char first_name[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last_name[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - - gCacheName->getName(buddy_id, first_name, last_name); - std::ostringstream fullname; - fullname << first_name << " " << last_name; - addFriend(fullname.str(), buddy_id); + have_names &= addFriend(buddy_it->first); } } + if (!have_names) + { + mEventTimer.start(); + } + // changed item in place, need to request sort and update columns + mFriendsList->sortItems(); + // re-select items mFriendsList->selectMultiple(selected_ids); mFriendsList->setScrollPos(pos); } @@ -412,7 +424,7 @@ void LLPanelFriends::refreshUI() single_selected = TRUE; if(num_selected > 1) { - childSetText("friend_name_label", childGetText("Multiple")); + childSetText("friend_name_label", getString("Multiple")); multiple_selected = TRUE; } else @@ -501,26 +513,17 @@ void LLPanelFriends::onClickIM(void* user_data) { LLUUID agent_id = ids[0]; const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(agent_id); - char first[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - char last[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - if(info && gCacheName->getName(agent_id, first, last)) + std::string fullname; + if(info && gCacheName->getFullName(agent_id, fullname)) { - char buffer[MAX_STRING]; /* Flawfinder: ignore */ - snprintf(buffer, MAX_STRING, "%s %s", first, last); /* Flawfinder: ignore */ gIMMgr->setFloaterOpen(TRUE); - gIMMgr->addSession( - buffer, - IM_NOTHING_SPECIAL, - agent_id); + gIMMgr->addSession(fullname, IM_NOTHING_SPECIAL, agent_id); } } else { gIMMgr->setFloaterOpen(TRUE); - gIMMgr->addSession("Friends Conference", - IM_SESSION_CONFERENCE_START, - ids[0], - ids); + gIMMgr->addSession("Friends Conference", IM_SESSION_CONFERENCE_START, ids[0], ids); } make_ui_sound("UISndStartIM"); } @@ -612,8 +615,7 @@ void LLPanelFriends::onClickRemove(void* user_data) if(ids.size() == 1) { LLUUID agent_id = ids[0]; - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + std::string first, last; if(gCacheName->getName(agent_id, first, last)) { args["[FIRST_NAME]"] = first; @@ -671,8 +673,7 @@ void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command if(ids.size() == 1) { LLUUID agent_id = ids.begin()->first; - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + std::string first, last; if(gCacheName->getName(agent_id, first, last)) { args["[FIRST_NAME]"] = first; @@ -720,9 +721,8 @@ void LLPanelFriends::modifyRightsConfirmation(S32 option, void* user_data) rights_map_t::iterator rights_it; for (rights_it = rights->begin(); rights_it != rights->end(); ++rights_it) { - LLScrollListItem* itemp = panelp->mFriendsList->getItem(rights_it->first); const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(rights_it->first); - panelp->updateFriendItem(itemp, info); + panelp->updateFriendItem(rights_it->first, info); } } panelp->refreshUI(); diff --git a/linden/indra/newview/llfloaterfriends.h b/linden/indra/newview/llfloaterfriends.h index 6e0ce78..6ce57f6 100644 --- a/linden/indra/newview/llfloaterfriends.h +++ b/linden/indra/newview/llfloaterfriends.h @@ -41,7 +41,8 @@ class LLFriendObserver; class LLRelationship; - +class LLScrollListItem; +class LLScrollListCtrl; /** * @class LLPanelFriends @@ -100,8 +101,8 @@ private: void refreshUI(); void refreshRightsChangeList(); void applyRightsToFriends(); - void addFriend(const std::string& name, const LLUUID& agent_id); - void updateFriendItem(LLScrollListItem* itemp, const LLRelationship* relationship); + BOOL addFriend(const LLUUID& agent_id); + BOOL updateFriendItem(const LLUUID& agent_id, const LLRelationship* relationship); typedef enum { @@ -138,7 +139,7 @@ private: LLFriendObserver* mObserver; LLUUID mAddFriendID; LLString mAddFriendName; - LLScrollListCtrl* mFriendsList; + LLScrollListCtrl* mFriendsList; BOOL mShowMaxSelectWarning; BOOL mAllowRightsChange; S32 mNumRightsChanged; diff --git a/linden/indra/newview/llfloatergesture.cpp b/linden/indra/newview/llfloatergesture.cpp index 3ac1e8f..addcf1d 100644 --- a/linden/indra/newview/llfloatergesture.cpp +++ b/linden/indra/newview/llfloatergesture.cpp @@ -99,7 +99,7 @@ LLFloaterGesture::~LLFloaterGesture() // Custom saving rectangle, since load must be done // after postBuild. - gSavedSettings.setRect("FloaterGestureRect", mRect); + gSavedSettings.setRect("FloaterGestureRect", getRect()); } // virtual diff --git a/linden/indra/newview/llfloatergroupinvite.cpp b/linden/indra/newview/llfloatergroupinvite.cpp index 8dd4e24..ba8e650 100644 --- a/linden/indra/newview/llfloatergroupinvite.cpp +++ b/linden/indra/newview/llfloatergroupinvite.cpp @@ -83,7 +83,7 @@ LLFloaterGroupInvite::LLFloaterGroupInvite(const std::string& name, const LLUUID& group_id) : LLFloater(name, rect, title) { - LLRect contents(mRect); + LLRect contents(getRect()); contents.mTop -= LLFLOATER_HEADER_SIZE; mImpl = new impl(group_id); diff --git a/linden/indra/newview/llfloatergroups.h b/linden/indra/newview/llfloatergroups.h index 8d118e4..3ceb1bd 100644 --- a/linden/indra/newview/llfloatergroups.h +++ b/linden/indra/newview/llfloatergroups.h @@ -53,9 +53,9 @@ class LLScrollListCtrl; class LLButton; class LLFloaterGroupPicker; -class LLFloaterGroupPicker : public LLFloater, public LLUIInstanceMgr +class LLFloaterGroupPicker : public LLFloater, public LLUIFactory > { - friend class LLUIInstanceMgr; + friend class LLUIFactory; public: ~LLFloaterGroupPicker(); void setSelectCallback( void (*callback)(LLUUID, void*), @@ -63,11 +63,13 @@ public: void setPowersMask(U64 powers_mask); BOOL postBuild(); + // implementation of factory policy + static LLFloaterGroupPicker* findInstance(const LLSD& seed); + static LLFloaterGroupPicker* createInstance(const LLSD& seed); + protected: LLFloaterGroupPicker(const LLSD& seed); void ok(); - static LLFloaterGroupPicker* findInstance(const LLSD& seed); - static LLFloaterGroupPicker* createInstance(const LLSD& seed); static void onBtnOK(void* userdata); static void onBtnCancel(void* userdata); diff --git a/linden/indra/newview/llfloaterhardwaresettings.cpp b/linden/indra/newview/llfloaterhardwaresettings.cpp new file mode 100644 index 0000000..0d92764 --- /dev/null +++ b/linden/indra/newview/llfloaterhardwaresettings.cpp @@ -0,0 +1,207 @@ +/** + * @file llfloaterhardwaresettings.cpp + * @brief Menu of all the different graphics hardware settings + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterhardwaresettings.h" +#include "llfloaterpreference.h" +#include "llviewerwindow.h" +#include "llviewercontrol.h" +#include "llviewerimagelist.h" +#include "llfeaturemanager.h" +#include "llstartup.h" + +#include "llradiogroup.h" +#include "llvieweruictrlfactory.h" + +#include "llimagegl.h" +#include "pipeline.h" + +LLFloaterHardwareSettings* LLFloaterHardwareSettings::sHardwareSettings = NULL; + +LLFloaterHardwareSettings::LLFloaterHardwareSettings() : LLFloater("Hardware Settings Floater") +{ + gUICtrlFactory->buildFloater(this, "floater_hardware_settings.xml"); + + // load it up + initCallbacks(); +} + +LLFloaterHardwareSettings::~LLFloaterHardwareSettings() +{ +} + +void LLFloaterHardwareSettings::onClickHelp(void* data) +{ + const char* xml_alert = "HardwareSettingsHelpButton"; + gViewerWindow->alertXml(xml_alert); +} + +void LLFloaterHardwareSettings::initCallbacks(void) +{ +} + +// menu maintenance functions + +void LLFloaterHardwareSettings::refresh() +{ + LLPanel::refresh(); + + mUseVBO = gSavedSettings.getBOOL("RenderVBOEnable"); + mUseAniso = gSavedSettings.getBOOL("RenderAnisotropic"); + mGamma = gSavedSettings.getF32("RenderGamma"); + mVideoCardMem = gSavedSettings.getS32("TextureMemory"); + mFogRatio = gSavedSettings.getF32("RenderFogRatio"); + mProbeHardwareOnStartup = gSavedSettings.getBOOL("ProbeHardwareOnStartup"); + + refreshEnabledState(); +} + +void LLFloaterHardwareSettings::refreshEnabledState() +{ + S32 min_tex_mem = LLViewerImageList::getMinVideoRamSetting(); + S32 max_tex_mem = LLViewerImageList::getMaxVideoRamSetting(); + childSetMinValue("GrapicsCardTextureMemory", min_tex_mem); + childSetMaxValue("GrapicsCardTextureMemory", max_tex_mem); + + if (!gFeatureManagerp->isFeatureAvailable("RenderVBOEnable") || + !gGLManager.mHasVertexBufferObject) + { + childSetEnabled("vbo", FALSE); + } + + // if no windlight shaders, turn off nighttime brightness, gamma, and fog distance + childSetEnabled("gamma", !gPipeline.canUseWindLightShaders()); + childSetEnabled("(brightness, lower is brighter)", !gPipeline.canUseWindLightShaders()); + childSetEnabled("fog", !gPipeline.canUseWindLightShaders()); + +} + +// static instance of it +LLFloaterHardwareSettings* LLFloaterHardwareSettings::instance() +{ + if (!sHardwareSettings) + { + sHardwareSettings = new LLFloaterHardwareSettings(); + sHardwareSettings->close(); + } + return sHardwareSettings; +} +void LLFloaterHardwareSettings::show() +{ + LLFloaterHardwareSettings* hardSettings = instance(); + hardSettings->refresh(); + hardSettings->center(); + + // comment in if you want the menu to rebuild each time + //gUICtrlFactory->buildFloater(hardSettings, "floater_hardware_settings.xml"); + //hardSettings->initCallbacks(); + + hardSettings->open(); +} + +bool LLFloaterHardwareSettings::isOpen() +{ + if (sHardwareSettings != NULL) + { + return true; + } + return false; +} + +// virtual +void LLFloaterHardwareSettings::onClose(bool app_quitting) +{ + if (sHardwareSettings) + { + sHardwareSettings->setVisible(FALSE); + } +} + + +//============================================================================ + +BOOL LLFloaterHardwareSettings::postBuild() +{ + requires("ani", WIDGET_TYPE_CHECKBOX); + requires("gamma", WIDGET_TYPE_SPINNER); + requires("vbo", WIDGET_TYPE_CHECKBOX); + requires("GrapicsCardTextureMemory", WIDGET_TYPE_SLIDER); + requires("fog", WIDGET_TYPE_SPINNER); + + if (!checkRequirements()) + { + return FALSE; + } + + childSetAction("OK", onBtnOK, this); + + refresh(); + + return TRUE; +} + + +void LLFloaterHardwareSettings::apply() +{ + // Anisotropic rendering + BOOL old_anisotropic = LLImageGL::sGlobalUseAnisotropic; + LLImageGL::sGlobalUseAnisotropic = childGetValue("ani"); + if (old_anisotropic != LLImageGL::sGlobalUseAnisotropic) + { + BOOL logged_in = (LLStartUp::getStartupState() >= STATE_STARTED); + gViewerWindow->restartDisplay(logged_in); + } + + refresh(); +} + + +void LLFloaterHardwareSettings::cancel() +{ + gSavedSettings.setBOOL("RenderVBOEnable", mUseVBO); + gSavedSettings.setBOOL("RenderAnisotropic", mUseAniso); + gSavedSettings.setF32("RenderGamma", mGamma); + gSavedSettings.setS32("TextureMemory", mVideoCardMem); + gSavedSettings.setF32("RenderFogRatio", mFogRatio); + gSavedSettings.setBOOL("ProbeHardwareOnStartup", mProbeHardwareOnStartup ); + + close(); +} + +// static +void LLFloaterHardwareSettings::onBtnOK( void* userdata ) +{ + LLFloaterHardwareSettings *fp =(LLFloaterHardwareSettings *)userdata; + fp->apply(); + fp->close(false); +} + diff --git a/linden/indra/newview/llfloaterhardwaresettings.h b/linden/indra/newview/llfloaterhardwaresettings.h new file mode 100644 index 0000000..600c30b --- /dev/null +++ b/linden/indra/newview/llfloaterhardwaresettings.h @@ -0,0 +1,102 @@ +/** + * @file llfloaterhardwaresettings.h + * @brief Menu of all the different graphics hardware settings + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATER_HARDWARE_SETTINGS_H +#define LL_LLFLOATER_HARDWARE_SETTINGS_H + +#include "llfloater.h" + +class LLSliderCtrl; + +/// Menuing system for all of windlight's functionality +class LLFloaterHardwareSettings : public LLFloater +{ + friend class LLPreferenceCore; + +public: + + LLFloaterHardwareSettings(); + virtual ~LLFloaterHardwareSettings(); + + virtual BOOL postBuild(); + + /// initialize all the callbacks for the menu + void initCallbacks(void); + + /// one and one instance only + static LLFloaterHardwareSettings* instance(); + + /// callback for the menus help button + static void onClickHelp(void* data); + + /// OK button + static void onBtnOK( void* userdata ); + + //// menu management + + /// show off our menu + static void show(); + + /// return if the menu exists or not + static bool isOpen(); + + /// stuff to do on exit + virtual void onClose(bool app_quitting); + + /// sync up menu with parameters + void refresh(); + + /// Apply the changed values. + void apply(); + + /// don't apply the changed values + void cancel(); + + /// refresh the enabled values + void refreshEnabledState(); + +protected: + LLSliderCtrl* mCtrlVideoCardMem; + + BOOL mUseVBO; + BOOL mUseAniso; + F32 mGamma; + S32 mVideoCardMem; + F32 mFogRatio; + BOOL mProbeHardwareOnStartup; + +private: + // one instance on the inside + static LLFloaterHardwareSettings* sHardwareSettings; +}; + +#endif + diff --git a/linden/indra/newview/llfloaterhtml.cpp b/linden/indra/newview/llfloaterhtml.cpp index 2f7bc14..596202a 100644 --- a/linden/indra/newview/llfloaterhtml.cpp +++ b/linden/indra/newview/llfloaterhtml.cpp @@ -43,7 +43,6 @@ #include "llwebbrowserctrl.h" LLFloaterHtml* LLFloaterHtml::sInstance = 0; -LLViewerHtmlHelp gViewerHtmlHelp; //////////////////////////////////////////////////////////////////////////////// // @@ -60,10 +59,8 @@ LLFloaterHtml* LLFloaterHtml::getInstance() LLFloaterHtml::LLFloaterHtml() : LLFloater( "HTML Floater" ) -#if LL_LIBXUL_ENABLED , mWebBrowser( 0 ) -#endif // LL_LIBXUL_ENABLED { // create floater from its XML definition gUICtrlFactory->buildFloater( this, "floater_html.xml" ); @@ -80,14 +77,12 @@ LLFloaterHtml::LLFloaterHtml() reshape( rect.getWidth(), rect.getHeight(), FALSE ); setRect( rect ); -#if LL_LIBXUL_ENABLED mWebBrowser = LLViewerUICtrlFactory::getWebBrowserByName(this, "html_floater_browser" ); if ( mWebBrowser ) { // open links in internal browser mWebBrowser->setOpenInExternalBrowser( false ); } -#endif // LL_LIBXUL_ENABLED } //////////////////////////////////////////////////////////////////////////////// @@ -95,7 +90,7 @@ LLFloaterHtml::LLFloaterHtml() LLFloaterHtml::~LLFloaterHtml() { // save position of floater - gSavedSettings.setRect( "HtmlFloaterRect", mRect ); + gSavedSettings.setRect( "HtmlFloaterRect", getRect() ); sInstance = 0; } @@ -104,7 +99,6 @@ LLFloaterHtml::~LLFloaterHtml() // virtual void LLFloaterHtml::draw() { -#if LL_LIBXUL_ENABLED // enable/disable buttons depending on state if ( mWebBrowser ) { @@ -114,39 +108,37 @@ void LLFloaterHtml::draw() bool enable_forward = mWebBrowser->canNavigateForward(); childSetEnabled( "forward_btn", enable_forward ); }; -#endif // LL_LIBXUL_ENABLED LLFloater::draw(); } //////////////////////////////////////////////////////////////////////////////// // -void LLFloaterHtml::show( LLString content_id, bool open_app_slurls ) +void LLFloaterHtml::show( LLString content_id, bool open_app_slurls, bool open_link_external ) { // calculate the XML labels we'll need (if only XML folders worked) LLString title_str = content_id + "_title"; LLString url_str = content_id + "_url"; - std::string title = childGetValue( title_str ).asString(); - std::string url = childGetValue( url_str ).asString(); - show( url, title, open_app_slurls ); + std::string title = getString( title_str ); + std::string url = getString( url_str ); + show( url, title, open_app_slurls, open_link_external ); } //////////////////////////////////////////////////////////////////////////////// // -void LLFloaterHtml::show( std::string start_url, std::string title, bool open_app_slurls ) +void LLFloaterHtml::show( std::string start_url, std::string title, bool open_app_slurls, bool open_link_external ) { // set the title setTitle( title ); -#if LL_LIBXUL_ENABLED // navigate to the URL if ( mWebBrowser ) { mWebBrowser->setOpenAppSLURLs( open_app_slurls ); + mWebBrowser->setOpenInExternalBrowser( open_link_external ); mWebBrowser->navigateTo( start_url ); } -#endif // LL_LIBXUL_ENABLED // make floater appear setVisibleAndFrontmost(); @@ -172,7 +164,6 @@ void LLFloaterHtml::onClickClose( void* data ) // static void LLFloaterHtml::onClickBack( void* data ) { -#if LL_LIBXUL_ENABLED LLFloaterHtml* self = ( LLFloaterHtml* )data; if ( self ) { @@ -181,7 +172,6 @@ void LLFloaterHtml::onClickBack( void* data ) self->mWebBrowser->navigateBack(); }; }; -#endif // LL_LIBXUL_ENABLED } //////////////////////////////////////////////////////////////////////////////// @@ -191,10 +181,9 @@ void LLFloaterHtml::onClickHome( void* data ) LLFloaterHtml* self = ( LLFloaterHtml* )data; if ( self ) { -#if LL_LIBXUL_ENABLED if ( self->mWebBrowser ) { - std::string home_url = self->childGetText("home_page_url"); + std::string home_url = self->getString("home_page_url"); if ( home_url.length() > 4 ) { self->mWebBrowser->navigateTo( home_url ); @@ -205,7 +194,6 @@ void LLFloaterHtml::onClickHome( void* data ) self->mWebBrowser->navigateTo( "http://secondlife.com" ); } }; -#endif // LL_LIBXUL_ENABLED }; } @@ -216,12 +204,10 @@ void LLFloaterHtml::onClickForward( void* data ) LLFloaterHtml* self = ( LLFloaterHtml* )data; if ( self ) { -#if LL_LIBXUL_ENABLED if ( self->mWebBrowser ) { self->mWebBrowser->navigateForward(); }; -#endif // LL_LIBXUL_ENABLED }; } @@ -229,7 +215,6 @@ void LLFloaterHtml::onClickForward( void* data ) // static void LLFloaterHtml::onCommitUrlEdit(LLUICtrl* ctrl, void* user_data) { -#if LL_LIBXUL_ENABLED LLFloaterHtml* self = (LLFloaterHtml*)user_data; LLLineEditor* editor = (LLLineEditor*)ctrl; @@ -239,7 +224,6 @@ void LLFloaterHtml::onCommitUrlEdit(LLUICtrl* ctrl, void* user_data) { self->mWebBrowser->navigateTo( url ); }; -#endif // LL_LIBXUL_ENABLED } //////////////////////////////////////////////////////////////////////////////// @@ -252,56 +236,11 @@ void LLFloaterHtml::onClickGo( void* data ) std::string url = self->childGetValue( "url_edit" ).asString(); if ( url.length() ) { -#if LL_LIBXUL_ENABLED if ( self->mWebBrowser ) { self->mWebBrowser->navigateTo( url ); - }; -#endif // LL_LIBXUL_ENABLED - }; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -static void onClickF1HelpLoadURL(S32 option, void* userdata) -{ - if (option == 0) - { - // choose HELP url based on selected language - default to english language support page - LLString lang = LLUI::sConfigGroup->getString("Language"); - - // *TODO:Translate - // this sucks but there isn't a way to grab an arbitrary string from an XML file - // (using llcontroldef strings causes problems if string don't exist) - LLString help_url( "http://secondlife.com/support" ); - if ( lang == "ja" ) - help_url = "http://help.secondlife.com/jp"; - else - if ( lang == "ko" ) - help_url = "http://help.secondlife.com/kr"; - else - if ( lang == "pt" ) - help_url = "http://help.secondlife.com/pt"; - else - if ( lang == "de" ) - help_url = "http://de.secondlife.com/support"; - - LLWeb::loadURL( help_url ); + } + } } } -LLViewerHtmlHelp::LLViewerHtmlHelp() -{ - LLUI::setHtmlHelp(this); -} - -LLViewerHtmlHelp::~LLViewerHtmlHelp() -{ - LLUI::setHtmlHelp(NULL); -} - -void LLViewerHtmlHelp::show(std::string url, std::string title) -{ - gViewerWindow->alertXml("ClickOpenF1Help", onClickF1HelpLoadURL, (void*) NULL); -} diff --git a/linden/indra/newview/llfloaterhtml.h b/linden/indra/newview/llfloaterhtml.h index 2f6164c..ffefdf4 100644 --- a/linden/indra/newview/llfloaterhtml.h +++ b/linden/indra/newview/llfloaterhtml.h @@ -1,4 +1,4 @@ -/** + /** * @file llfloaterhtml.h * @author James Cook * @brief In-world HTML dialog @@ -49,12 +49,12 @@ class LLFloaterHtml : virtual void onClose( bool app_quitting ); // Pass string like "in-world_help" or "additional help" - void show( LLString content_id, bool open_app_slurls ); + void show( LLString content_id, bool open_app_slurls, bool open_link_external ); // Pass raw URL and window title // Can be set to handle secondlife:///app/ URLs, but this should // usually be false. - void show( std::string start_url, std::string title, bool open_app_slurls ); + void show( std::string start_url, std::string title, bool open_app_slurls, bool open_link_external ); static void onClickClose( void* data ); static void onClickBack( void* data ); @@ -65,22 +65,10 @@ class LLFloaterHtml : private: LLFloaterHtml(); -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* mWebBrowser; -#endif // LL_LIBXUL_ENABLED static LLFloaterHtml* sInstance; LLButton* mCloseButton; }; -class LLViewerHtmlHelp : public LLHtmlHelp -{ -public: - LLViewerHtmlHelp(); - virtual ~LLViewerHtmlHelp(); - - /*virtual*/ void show(std::string start_url = "", std::string title = ""); -}; - -extern LLViewerHtmlHelp gViewerHtmlHelp; #endif diff --git a/linden/indra/newview/llfloaterhtmlhelp.cpp b/linden/indra/newview/llfloaterhtmlhelp.cpp new file mode 100644 index 0000000..9a5ba0e --- /dev/null +++ b/linden/indra/newview/llfloaterhtmlhelp.cpp @@ -0,0 +1,528 @@ +/** + * @file llfloaterhtmlhelp.cpp + * @brief HTML Help floater - uses embedded web browser control + * + * $LicenseInfo:firstyear=2006&license=viewergpl$ + * + * Copyright (c) 2006-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterhtmlhelp.h" + +#include "llparcel.h" +#include "llvieweruictrlfactory.h" +#include "llwebbrowserctrl.h" +#include "llviewerwindow.h" +#include "llviewercontrol.h" +#include "llviewerparcelmgr.h" +#include "llweb.h" +#include "llui.h" +#include "roles_constants.h" + +#include "llurlhistory.h" +#include "llwebbrowserctrl.h" +#include "llviewermedia.h" +#include "llviewerparcelmedia.h" +#include "llcombobox.h" + + +LLFloaterMediaBrowser::LLFloaterMediaBrowser(const LLSD& media_data) +{ + gUICtrlFactory->buildFloater(this, "floater_media_browser.xml"); +} + +void LLFloaterMediaBrowser::draw() +{ + childSetEnabled("go", !mAddressCombo->getValue().asString().empty()); + if ( gParcelMgr ) // this code can be called at login screen where gParcelMgr is NULL + { + LLParcel* parcel = gParcelMgr->getAgentParcel(); + if(parcel) + { + childSetVisible("parcel_owner_controls", LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA)); + childSetEnabled("assign", !mAddressCombo->getValue().asString().empty()); + } + }; + LLFloater::draw(); +} + +BOOL LLFloaterMediaBrowser::postBuild() +{ + mBrowser = LLViewerUICtrlFactory::getWebBrowserByName(this, "browser"); + mBrowser->addObserver(this); + + mAddressCombo = LLUICtrlFactory::getComboBoxByName(this, "address"); + mAddressCombo->setCommitCallback(onEnterAddress); + mAddressCombo->setCallbackUserData(this); + + childSetAction("back", onClickBack, this); + childSetAction("forward", onClickForward, this); + childSetAction("reload", onClickRefresh, this); + childSetAction("go", onClickGo, this); + childSetAction("close", onClickClose, this); + childSetAction("open_browser", onClickOpenWebBrowser, this); + childSetAction("assign", onClickAssign, this); + + buildURLHistory(); + return TRUE; +} + +void LLFloaterMediaBrowser::buildURLHistory() +{ + LLCtrlListInterface* url_list = childGetListInterface("address"); + if (url_list) + { + url_list->operateOnAll(LLCtrlListInterface::OP_DELETE); + } + + // Get all of the entries in the "parcel" collection + LLSD parcel_history = LLURLHistory::getURLHistory("browser"); + + LLSD::array_iterator iter_history = + parcel_history.beginArray(); + LLSD::array_iterator end_history = + parcel_history.endArray(); + for(; iter_history != end_history; ++iter_history) + { + std::string url = (*iter_history).asString(); + if(! url.empty()) + url_list->addSimpleElement(url); + } +} + +void LLFloaterMediaBrowser::onClose(bool app_quitting) +{ + //setVisible(FALSE); + destroy(); +} + +void LLFloaterMediaBrowser::onLocationChange( const EventType& eventIn ) +{ + // hitting the refresh button will navigate to same URL, so don't add to address history + mCurrentURL = eventIn.getStringValue(); + std::string::size_type string_start = mCurrentURL.find("://"); + LLString truncated_url; + if ((string_start == std::string::npos) || (1)) // NOTE: this conditional is forced true to disable truncation DEV-9834 + { + truncated_url = mCurrentURL; + } + else + { + truncated_url = mCurrentURL.substr(string_start + 3); + } + // redirects will navigate momentarily to about:blank, don't add to history + if (truncated_url != "about:blank") + { + mAddressCombo->remove(truncated_url); + mAddressCombo->add(truncated_url, ADD_SORTED); + mAddressCombo->selectByValue(truncated_url); + + // Serialize url history + LLURLHistory::removeURL("browser", truncated_url); + LLURLHistory::addURL("browser", truncated_url); + } + childSetEnabled("back", mBrowser->canNavigateBack()); + childSetEnabled("forward", mBrowser->canNavigateForward()); + childSetEnabled("reload", TRUE); +} + +LLFloaterMediaBrowser* LLFloaterMediaBrowser::showInstance(const LLSD& media_url) +{ + LLFloaterMediaBrowser* floaterp = LLUISingleton >::showInstance(media_url); + + floaterp->openMedia(media_url.asString()); + return floaterp; +} + +//static +void LLFloaterMediaBrowser::onEnterAddress(LLUICtrl* ctrl, void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + self->mBrowser->navigateTo(self->mAddressCombo->getValue().asString()); +} + +//static +void LLFloaterMediaBrowser::onClickRefresh(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + self->mAddressCombo->remove(0); + self->mBrowser->navigateTo(self->mCurrentURL); +} + +//static +void LLFloaterMediaBrowser::onClickForward(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + self->mBrowser->navigateForward(); +} + +//static +void LLFloaterMediaBrowser::onClickBack(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + self->mBrowser->navigateBack(); +} + +//static +void LLFloaterMediaBrowser::onClickGo(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + self->mBrowser->navigateTo(self->mAddressCombo->getValue().asString()); +} + +//static +void LLFloaterMediaBrowser::onClickClose(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + self->close(); +} + +//static +void LLFloaterMediaBrowser::onClickOpenWebBrowser(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + LLWeb::loadURLExternal(self->mCurrentURL); +} + +void LLFloaterMediaBrowser::onClickAssign(void* user_data) +{ + LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data; + + LLParcel* parcel = gParcelMgr->getAgentParcel(); + if (!parcel) + { + return; + } + std::string media_url = self->mAddressCombo->getValue().asString(); + LLString::trim(media_url); + + parcel->setMediaURL(media_url.c_str()); + parcel->setMediaType("text/html"); + + // Send current parcel data upstream to server + gParcelMgr->sendParcelPropertiesUpdate( parcel, true ); + // now check for video + LLViewerParcelMedia::update( parcel ); + + +} + +void LLFloaterMediaBrowser::openMedia(const std::string& media_url) +{ + mBrowser->setHomePageUrl(media_url); + mBrowser->navigateTo(media_url); +} + +LLViewerHtmlHelp gViewerHtmlHelp; + +class LLFloaterHtmlHelp : + public LLFloater, + public LLWebBrowserCtrlObserver +{ +public: + LLFloaterHtmlHelp(std::string start_url, std::string title); + virtual ~LLFloaterHtmlHelp(); + + virtual void onClose( bool app_quitting ); + virtual void draw(); + + static void show(std::string url, std::string title); + static void onClickBack( void* data ); + static void onClickHome( void* data ); + static void onClickForward( void* data ); + static void onClickClose( void* data ); + + // browser observer impls + virtual void onStatusTextChange( const EventType& eventIn ); + virtual void onLocationChange( const EventType& eventIn ); + + // used for some stats logging - will be removed at some point + static BOOL sFloaterOpened; + + static void onClickF1HelpLoadURL(S32 option, void* userdata); + +protected: + LLWebBrowserCtrl* mWebBrowser; + static LLFloaterHtmlHelp* sInstance; + LLButton* mBackButton; + LLButton* mForwardButton; + LLButton* mCloseButton; + LLTextBox* mStatusText; + LLString mStatusTextContents; + LLString mCurrentUrl; +}; + +LLFloaterHtmlHelp* LLFloaterHtmlHelp::sInstance = 0; + +BOOL LLFloaterHtmlHelp::sFloaterOpened = FALSE; + +//////////////////////////////////////////////////////////////////////////////// +// +LLFloaterHtmlHelp::LLFloaterHtmlHelp(std::string start_url, std::string title) +: LLFloater( "HTML Help" ), + mWebBrowser( 0 ), + mStatusTextContents( "" ), + mCurrentUrl( "" ) +{ + sInstance = this; + + // create floater from its XML definition + gUICtrlFactory->buildFloater( this, "floater_html_help.xml" ); + + childSetAction("back_btn", onClickBack, this); + childSetAction("home_btn", onClickHome, this); + childSetAction("forward_btn", onClickForward, this); + + if (!title.empty()) + { + setTitle(title); + } + + mWebBrowser = LLViewerUICtrlFactory::getWebBrowserByName(this, "html_help_browser" ); + if ( mWebBrowser ) + { + // observe browser control events + mWebBrowser->addObserver( this ); + + if (start_url != "") + { + mWebBrowser->navigateTo( start_url ); + } + else + { + // if the last page we were at before the client was closed is valid, go there and + // override what is in the XML file + // (not when the window was closed - it's only ever hidden - not closed) + LLString lastPageUrl = gSavedSettings.getString( "HtmlHelpLastPage" ); + if ( lastPageUrl != "" ) + { + mWebBrowser->navigateTo( lastPageUrl ); + }; + } + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +LLFloaterHtmlHelp::~LLFloaterHtmlHelp() +{ + // stop observing browser events + if ( mWebBrowser ) + { + mWebBrowser->remObserver( this ); + }; + + // save position of floater + gSavedSettings.setRect( "HtmlHelpRect", getRect() ); + + // save the location we were at when SL closed + gSavedSettings.setString( "HtmlHelpLastPage", mCurrentUrl ); + + sInstance = 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void LLFloaterHtmlHelp::draw() +{ + // enable/disable buttons depending on state + if ( mWebBrowser ) + { + bool enable_back = mWebBrowser->canNavigateBack(); + childSetEnabled( "back_btn", enable_back ); + + bool enable_forward = mWebBrowser->canNavigateForward(); + childSetEnabled( "forward_btn", enable_forward ); + }; + + LLFloater::draw(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterHtmlHelp::show(std::string url, std::string title) +{ + gViewerWindow->alertXml("ClickOpenF1Help", onClickF1HelpLoadURL, (void*) NULL); + + // switching this out for the moment - will come back later + // want it still to be compiled so not using comments of #if 0 + if ( false ) + { + sFloaterOpened = true; + + if ( sInstance ) + { + if (sInstance->mWebBrowser) + { + sInstance->mWebBrowser->navigateTo(url); + } + sInstance->setVisibleAndFrontmost(); + return; + } + + LLFloaterHtmlHelp* self = new LLFloaterHtmlHelp(url, title); + + // reposition floater from saved settings + LLRect rect = gSavedSettings.getRect( "HtmlHelpRect" ); + self->reshape( rect.getWidth(), rect.getHeight(), FALSE ); + self->setRect( rect ); + }; +} + +// static +void LLFloaterHtmlHelp::onClickF1HelpLoadURL(S32 option, void* userdata) +{ + if (option == 0) + { + // choose HELP url based on selected language - default to english language support page + LLString lang = LLUI::sConfigGroup->getString("Language"); + + // this sucks but there isn't a way to grab an arbitrary string from an XML file + // (using llcontroldef strings causes problems if string don't exist) + LLString help_url( "http://secondlife.com/support" ); + if ( lang == "ja" ) + help_url = "http://help.secondlife.com/jp"; + else + if ( lang == "ko" ) + help_url = "http://help.secondlife.com/kr"; + else + if ( lang == "pt" ) + help_url = "http://help.secondlife.com/pt"; + else + if ( lang == "de" ) + help_url = "http://de.secondlife.com/support"; + + LLWeb::loadURL( help_url ); + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterHtmlHelp::onClose( bool app_quitting ) +{ + setVisible( false ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterHtmlHelp::onClickClose( void* data ) +{ + LLFloaterHtmlHelp* self = ( LLFloaterHtmlHelp* )data; + + self->setVisible( false ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterHtmlHelp::onClickBack( void* data ) +{ + LLFloaterHtmlHelp* self = ( LLFloaterHtmlHelp* )data; + if ( self ) + { + if ( self->mWebBrowser ) + { + self->mWebBrowser->navigateBack(); + }; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterHtmlHelp::onClickHome( void* data ) +{ + LLFloaterHtmlHelp* self = ( LLFloaterHtmlHelp* )data; + if ( self ) + { + // get the home page URL (which can differ from the start URL) from XML and go there + LLWebBrowserCtrl* web_browser = LLViewerUICtrlFactory::getWebBrowserByName( self, "html_help_browser" ); + if ( web_browser ) + { + web_browser->navigateHome(); + }; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterHtmlHelp::onClickForward( void* data ) +{ + LLFloaterHtmlHelp* self = ( LLFloaterHtmlHelp* )data; + if ( self ) + { + if ( self->mWebBrowser ) + { + self->mWebBrowser->navigateForward(); + }; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterHtmlHelp::onStatusTextChange( const EventType& eventIn ) +{ + mStatusTextContents = LLString( eventIn.getStringValue() ); + + childSetText("status_text", mStatusTextContents); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterHtmlHelp::onLocationChange( const EventType& eventIn ) +{ + llinfos << "MOZ> Location changed to " << eventIn.getStringValue() << llendl; + mCurrentUrl = LLString( eventIn.getStringValue() ); +} + +//////////////////////////////////////////////////////////////////////////////// +// +LLViewerHtmlHelp::LLViewerHtmlHelp() +{ + LLUI::setHtmlHelp(this); +} + +LLViewerHtmlHelp::~LLViewerHtmlHelp() +{ + LLUI::setHtmlHelp(NULL); +} + +void LLViewerHtmlHelp::show(std::string url, std::string title) +{ + LLFloaterHtmlHelp::show(url, title); +} + +BOOL LLViewerHtmlHelp::getFloaterOpened() +{ + return LLFloaterHtmlHelp::sFloaterOpened; +} + + diff --git a/linden/indra/newview/llfloaterhtmlhelp.h b/linden/indra/newview/llfloaterhtmlhelp.h new file mode 100644 index 0000000..65ec093 --- /dev/null +++ b/linden/indra/newview/llfloaterhtmlhelp.h @@ -0,0 +1,87 @@ +/** + * @file llfloaterhtmlhelp.h + * @brief HTML Help floater - uses embedded web browser control + * + * $LicenseInfo:firstyear=2006&license=viewergpl$ + * + * Copyright (c) 2006-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERHTMLHELP_H +#define LL_LLFLOATERHTMLHELP_H + +#include "llhtmlhelp.h" +#include "llfloater.h" +#include "llwebbrowserctrl.h" + +class LLViewerHtmlHelp : public LLHtmlHelp +{ +public: + LLViewerHtmlHelp(); + virtual ~LLViewerHtmlHelp(); + + /*virtual*/ void show(std::string start_url, std::string title); + void show() { show("", ""); } + /*virtual*/ BOOL getFloaterOpened(); +}; + +class LLComboBox; +class LLWebBrowserCtrl; + +class LLFloaterMediaBrowser : public LLFloater, public LLUISingleton >, public LLWebBrowserCtrlObserver +{ + friend class LLUISingleton >; +public: + LLFloaterMediaBrowser(const LLSD& media_data); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onClose(bool app_quitting); + /*virtual*/ void onLocationChange( const EventType& eventIn ); + + /*virtual*/ void draw(); + + void openMedia(const std::string& media_url); + void buildURLHistory(); + + static LLFloaterMediaBrowser* showInstance(const LLSD& id); + static void onEnterAddress(LLUICtrl* ctrl, void* user_data); + static void onClickRefresh(void* user_data); + static void onClickBack(void* user_data); + static void onClickForward(void* user_data); + static void onClickGo(void* user_data); + static void onClickClose(void* user_data); + static void onClickOpenWebBrowser(void* user_data); + static void onClickAssign(void* user_data); + +private: + LLWebBrowserCtrl* mBrowser; + LLComboBox* mAddressCombo; + std::string mCurrentURL; +}; + +extern LLViewerHtmlHelp gViewerHtmlHelp; + +#endif // LL_LLFLOATERHTMLHELP_H + diff --git a/linden/indra/newview/llfloaterimagepreview.cpp b/linden/indra/newview/llfloaterimagepreview.cpp index 4c0b096..551ae95 100644 --- a/linden/indra/newview/llfloaterimagepreview.cpp +++ b/linden/indra/newview/llfloaterimagepreview.cpp @@ -43,6 +43,7 @@ #include "llcombobox.h" #include "lldrawable.h" #include "lldrawpoolavatar.h" +#include "llglimmediate.h" #include "llface.h" #include "lltextbox.h" #include "lltoolmgr.h" @@ -258,19 +259,19 @@ void LLFloaterImagePreview::draw() } } - glColor3f(1.f, 1.f, 1.f); - glBegin( GL_QUADS ); + gGL.color3f(1.f, 1.f, 1.f); + gGL.begin( GL_QUADS ); { - glTexCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop); - glVertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); - glTexCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mBottom); - glVertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - glTexCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom); - glVertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - glTexCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mTop); - glVertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); + gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); + gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mBottom); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mTop); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); } - glEnd(); + gGL.end(); LLImageGL::unbindTexture(0, GL_TEXTURE_2D); @@ -280,25 +281,25 @@ void LLFloaterImagePreview::draw() { if ((mAvatarPreview) && (mSculptedPreview)) { - glColor3f(1.f, 1.f, 1.f); + gGL.color3f(1.f, 1.f, 1.f); if (selected == 9) mSculptedPreview->bindTexture(); else mAvatarPreview->bindTexture(); - glBegin( GL_QUADS ); + gGL.begin( GL_QUADS ); { - glTexCoord2f(0.f, 1.f); - glVertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); - glTexCoord2f(0.f, 0.f); - glVertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - glTexCoord2f(1.f, 0.f); - glVertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - glTexCoord2f(1.f, 1.f); - glVertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT); } - glEnd(); + gGL.end(); if (selected == 9) mSculptedPreview->unbindTexture(); @@ -615,7 +616,7 @@ LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLDynamicTex mDummyAvatar->slamPosition(); mDummyAvatar->updateJointLODs(); mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable); - gPipeline.markVisible(mDummyAvatar->mDrawable, *gCamera); + // gPipeline.markVisible(mDummyAvatar->mDrawable, *gCamera); mTextureName = 0; } @@ -669,25 +670,26 @@ BOOL LLImagePreviewAvatar::render() LLVOAvatar* avatarp = mDummyAvatar; glMatrixMode(GL_PROJECTION); - glPushMatrix(); + gGL.pushMatrix(); glLoadIdentity(); glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gGL.pushMatrix(); glLoadIdentity(); LLGLSUIDefault def; - glColor4f(0.15f, 0.2f, 0.3f, 1.f); + gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); gl_rect_2d_simple( mWidth, mHeight ); glMatrixMode(GL_PROJECTION); - glPopMatrix(); + gGL.popMatrix(); glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gGL.popMatrix(); + gGL.stop(); LLVector3 target_pos = mTargetJoint->getWorldPosition(); LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * @@ -720,6 +722,8 @@ BOOL LLImagePreviewAvatar::render() avatarPoolp->renderAvatars(avatarp); // renders only one avatar } + gGL.start(); + return TRUE; } @@ -826,23 +830,23 @@ BOOL LLImagePreviewSculpted::render() LLGLDepthTest depth(GL_TRUE); glMatrixMode(GL_PROJECTION); - glPushMatrix(); + gGL.pushMatrix(); glLoadIdentity(); glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gGL.pushMatrix(); glLoadIdentity(); - glColor4f(0.15f, 0.2f, 0.3f, 1.f); + gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); gl_rect_2d_simple( mWidth, mHeight ); glMatrixMode(GL_PROJECTION); - glPopMatrix(); + gGL.popMatrix(); glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gGL.popMatrix(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -863,31 +867,55 @@ BOOL LLImagePreviewSculpted::render() gCamera->setView(gCamera->getDefaultFOV() / mCameraZoom); gCamera->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); - gPipeline.enableLightsAvatar(0.0); - + gPipeline.enableLightsAvatar(); - glPushMatrix(); + gGL.pushMatrix(); glScalef(0.5, 0.5, 0.5); - glBegin(GL_TRIANGLES); - glColor3f(0.8f, 0.8f, 0.8f); - const LLVolumeFace &vf = mVolume->getVolumeFace(0); - S32 num_indices = (S32)vf.mIndices.size(); - for (U32 i = 0; (S32)i < num_indices; i++) + U32 num_indices = vf.mIndices.size(); + U32 num_vertices = vf.mVertices.size(); + + if (num_vertices > 0 && num_indices > 0) { - LLVector3 normal = vf.mVertices[vf.mIndices[i]].mNormal; - normal.normVec(); - glNormal3f(normal.mV[VX], normal.mV[VY], normal.mV[VZ]); + glEnableClientState(GL_NORMAL_ARRAY); + // build vertices and normals + F32* vertices = new F32[num_vertices * 3]; + F32* normals = new F32[num_vertices * 3]; - LLVector3 position = vf.mVertices[vf.mIndices[i]].mPosition; - glVertex3f(position.mV[VX], position.mV[VY], position.mV[VZ]); - } + for (U32 i = 0; (S32)i < num_vertices; i++) + { + LLVector3 position = vf.mVertices[i].mPosition; + vertices[i*3] = position.mV[VX]; + vertices[i*3+1] = position.mV[VY]; + vertices[i*3+2] = position.mV[VZ]; + + LLVector3 normal = vf.mVertices[i].mNormal; + normals[i*3] = normal.mV[VX]; + normals[i*3+1] = normal.mV[VY]; + normals[i*3+2] = normal.mV[VZ]; + } + + // build indices + U16* indices = new U16[num_indices]; + for (U16 i = 0; i < num_indices; i++) + { + indices[i] = vf.mIndices[i]; + } + + gGL.color3f(0.4f, 0.4f, 0.4f); + glVertexPointer(3, GL_FLOAT, 0, (void *)vertices); + glNormalPointer(GL_FLOAT, 0, (void *)normals); + glDrawRangeElements(GL_TRIANGLES, 0, num_indices-1, num_indices, GL_UNSIGNED_SHORT, (void *)indices); - glEnd(); - - glPopMatrix(); - + gGL.popMatrix(); + glDisableClientState(GL_NORMAL_ARRAY); + + delete [] indices; + delete [] vertices; + delete [] normals; + } + return TRUE; } diff --git a/linden/indra/newview/llfloaterimport.cpp b/linden/indra/newview/llfloaterimport.cpp deleted file mode 100644 index 77f1206..0000000 --- a/linden/indra/newview/llfloaterimport.cpp +++ /dev/null @@ -1,669 +0,0 @@ -/** - * @file llfloaterimport.cpp - * @brief LLFloaterImport class implementation - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfloaterimport.h" - -#include "llapr.h" - -#include "llimagebmp.h" -#include "llimagetga.h" -#include "llimagejpeg.h" - -#include "llagent.h" -#include "llbutton.h" -#include "llcombobox.h" -#include "lldrawable.h" -#include "lldrawpoolavatar.h" -#include "llface.h" -#include "llinventorymodel.h" -#include "lllineeditor.h" -#include "llresourcedata.h" -#include "lltextbox.h" -#include "lltoolmgr.h" -#include "llui.h" -#include "lluploaddialog.h" -#include "llviewercamera.h" -#include "llviewermenufile.h" // upload_new_resource() -#include "llviewerwindow.h" -#include "llvoavatar.h" -#include "pipeline.h" -#include "llvieweruictrlfactory.h" -#include "llmd5.h" - -extern LLInventoryModel gInventory; - -//statics -//LLUploadDialog *LLFloaterImport::sImportDialog = NULL; -LLUUID LLFloaterImport::sImportRequestID; -LLString LLFloaterImport::sOKText = LLString(); - -const S32 PREVIEW_BORDER_WIDTH = 2; -const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH; -const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE; -const S32 PREF_BUTTON_HEIGHT = 16; -const S32 PREVIEW_TEXTURE_HEIGHT = 300; - -//----------------------------------------------------------------------------- -// LLFloaterImport() -//----------------------------------------------------------------------------- -LLFloaterImport::LLFloaterImport(const std::string filename) - : LLFloater("Import") -{ - mFilenameAndPath = filename; - - char file_path[256]; /*Flawfinder: ignore*/ - strncpy(file_path, mFilenameAndPath.c_str(), sizeof(file_path) -1); /*Flawfinder: ignore*/ - file_path[sizeof(file_path) -1] = '\0'; - char *file_name = strrchr( file_path, gDirUtilp->getDirDelimiter()[0]); - file_name[0] = 0; - - mFilename.assign(file_name + 1); - mFilePath.assign(file_path); - - //LLString::toLower(mFilename); - - LLXMLNode::parseFile(filename, mObjectFile, NULL); -} - -//----------------------------------------------------------------------------- -// postBuild() -//----------------------------------------------------------------------------- -BOOL LLFloaterImport::postBuild() -{ - LLString asset_name = mFilename; - LLString::replaceNonstandardASCII( asset_name, '?' ); - LLString::replaceChar(asset_name, '|', '?'); - LLString::stripNonprintable(asset_name); - LLString::trim(asset_name); - - char* asset_name_str = (char*)asset_name.c_str(); - char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists - if( !end_p ) - { - end_p = asset_name_str + strlen( asset_name_str ); /*Flawfinder: ignore*/ - } - - S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) ); - - asset_name = asset_name.substr( 0, len ); - - setTitle(mFilename); - - { - // Center the window - LLRect window_rect = gViewerWindow->getRootView()->getRect(); - - S32 dialog_left = window_rect.mLeft + (window_rect.getWidth() - mRect.getWidth()) / 2; - S32 dialog_bottom = window_rect.mBottom + (window_rect.getHeight() - mRect.getHeight()) / 2; - - translate( dialog_left - mRect.mLeft, dialog_bottom - mRect.mBottom ); - } - - mNameEditor = LLViewerUICtrlFactory::getLineEditorByName(this, "name_form"); - mNameEditor->setMaxTextLength(DB_INV_ITEM_NAME_STR_LEN); - //mNameEditor->setCommitCallback(onCommit); - mNameEditor->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe); - - mNameEditor->setText(asset_name); - - mDescEditor = LLViewerUICtrlFactory::getLineEditorByName(this, "description_form"); - mDescEditor->setMaxTextLength(DB_INV_ITEM_DESC_STR_LEN); - //mDescEditor->setCommitCallback(onCommit); - mDescEditor->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe); - - // Cancel button - mCancelBtn = LLViewerUICtrlFactory::getButtonByName(this, "cancel_btn"); - mCancelBtn->setClickedCallback(onBtnCancel); - mCancelBtn->setCallbackUserData(this); - - // OK button - mOKBtn = LLViewerUICtrlFactory::getButtonByName(this, "ok_btn"); - mOKBtn->setClickedCallback(onBtnOK); - mOKBtn->setCallbackUserData(this); - setDefaultBtn(mOKBtn); - - mImageLabel = LLViewerUICtrlFactory::getTextBoxByName(this, "preview_label"); - mImportList = LLViewerUICtrlFactory::getScrollListByName(this, "upload_list"); - - bool object_file_read = false; - int object_count = 0, image_count = 0; - if (mObjectFile) - { - LLXMLNodeList object_list; - mObjectFile->findName("object", object_list); - LLXMLNodeList::iterator itor; - LLXMLNodeList::iterator itor2; - for (itor = object_list.begin(); itor != object_list.end(); ++itor) - { - LLXMLNode *object = itor->second; - LLXMLNodeList tasks_list; - object->getChildren("task", tasks_list, FALSE); - for (itor2 = tasks_list.begin(); itor2 != tasks_list.end(); ++itor2) - { - LLXMLNode *task = itor2->second; - LLXMLNodePtr temp_node; - if (!task->getChild("root", temp_node, FALSE)) - { - // This task is a root - LLString task_name = "(unnamed object)"; - LLXMLNodePtr task_name_node; - if (task->getChild("name", task_name_node, FALSE)) - { - task_name_node->getStringValue(1, &task_name); - } - { - LLString output_line; - char buffer[20]; /*Flawfinder: ignore*/ - snprintf(buffer, sizeof(buffer), "%d", (S32)tasks_list.size()); /* Flawfinder: ignore */ - output_line.append(buffer); - output_line.append(" prims"); - - LLSD row; - row["columns"][0]["value"] = "OBJECT"; - row["columns"][0]["width"] = 60; - row["columns"][1]["value"] = output_line; - row["columns"][1]["width"] = 80; - row["columns"][2]["value"] = task_name; - row["enabled"] = false; - mImportList->addElement(row); - } - mImportList->setCanSelect(TRUE); - mImportList->setAllowMultipleSelection(TRUE); - object_file_read = true; - object_count++; - break; - } - } - } - - if (object_count > 0) - { - std::string::size_type pos = mFilenameAndPath.rfind("."); - if (pos != mFilenameAndPath.npos) - { - mInventoryPath = mFilenameAndPath.substr(0, pos); - } - else - { - mInventoryPath = mFilenameAndPath; - } - mInventoryPath.append("_inventory"); - - LLXMLNodeList image_list; - mObjectFile->findName("sl:image", image_list); - std::vector unique_images; - std::vector unique_ids; - std::vector image_changed; - for (itor = image_list.begin(); itor != image_list.end(); ++itor) - { - LLXMLNode *image_node = itor->second; - LLString image_id = image_node->getID(); - - LLUUID image_uuid; - image_node->getUUIDValue(1, &image_uuid); - - bool found_image = false; - for (U32 image_num=0; image_numgetChild("checksum", image_hash_node)) - { - image_hash_node->getStringValue(1, &node_hash); - } - - llinfos << "Node hash: " << node_hash << llendl; - - // Try to find image and get checksum - LLString image_path = mInventoryPath; - image_path.append(gDirUtilp->getDirDelimiter()); - image_path.append(image_id); - image_path.append(".tga"); - - llinfos << "Getting hash for " << image_path << llendl; - - char md5_hash_string[33]; /*Flawfinder: ignore*/ - strcpy(md5_hash_string, "00000000000000000000000000000000"); /*Flawfinder: ignore*/ - FILE* fCheck = LLFile::fopen(image_path.c_str(), "rb"); /*Flawfinder: ignore*/ - if (fCheck) - { - LLMD5 my_md5_hash(fCheck); // this fclose()s fCheck too - my_md5_hash.hex_digest(md5_hash_string); - - llinfos << "hash: " << md5_hash_string << llendl; - } - - LoadPreviewImage(image_path, image_uuid); - - if (memcmp(md5_hash_string, node_hash.c_str(), 32) == 0) - { - // Image has not changed - image_changed.push_back(false); - } - else - { - // Image has changed - image_changed.push_back(true); - } - } - } - for (U32 image_num=0; image_numaddElement(row); - mImportList->setCanSelect(TRUE); - image_count++; - } - } - } - - if (!object_file_read) - { - mImportList->addCommentText("Error: Invalid object file."); - mImportList->setCanSelect(FALSE); - mOKBtn->setEnabled(FALSE); - } - else - { - recalcCost(); - } - - return TRUE; -} - -void LLFloaterImport::LoadPreviewImage(LLString image_path, LLUUID image_uuid) -{ - LLPointer raw_image = new LLImageRaw; - LLPointer tga_image = new LLImageTGA; - - if (!tga_image->load(image_path)) - { - return; - } - - if (!tga_image->decode(raw_image)) - { - return; - } - - if( (tga_image->getComponents() != 3) && - (tga_image->getComponents() != 4) ) - { - tga_image->setLastError( "Image files with less than 3 or more than 4 components are not supported." ); - return; - } - - raw_image->biasedScaleToPowerOfTwo(256); - - mPreviewImages[image_uuid] = raw_image; -} - -//----------------------------------------------------------------------------- -// LLFloaterImport() -//----------------------------------------------------------------------------- -LLFloaterImport::~LLFloaterImport() -{ - if (mGLName) - { - glDeleteTextures(1, &mGLName ); - } -} - -//----------------------------------------------------------------------------- -// recalcCost() -//----------------------------------------------------------------------------- -void LLFloaterImport::recalcCost() -{ - /*S32 cost = 0; - LLScrollListItem *item = mImportList->getFirstData(); - while (item) - { - LLString item_type = item->getColumn(0)->getText(); - - if (item_type == "IMAGE" && item->getSelected()) - { - cost += 10; // hypothetical image cost - } - if (item_type == "OBJECT") - { - cost += 10; // hypothetical object cost - } - item = mImportList->getNextData(); - } - - char buffer[20]; - sOKText = "Upload (L$"; - sprintf(buffer, "%d", cost); - sOKText.append(buffer); - sOKText.append(")"); - mOKBtn->setLabelSelected(sOKText.c_str()); - mOKBtn->setLabelUnselected(sOKText.c_str()); - mOKBtn->setEnabled(TRUE);*/ -} - -//----------------------------------------------------------------------------- -// draw() -//----------------------------------------------------------------------------- -void LLFloaterImport::draw() -{ - LLFloater::draw(); - - LLRect PreviewImageRect; - BOOL has_rect = childGetRect("dummy_preview", PreviewImageRect); - - if (mCurrentPreviewImage.notNull() && has_rect) - { - gl_rect_2d_checkerboard(PreviewImageRect); - - GLenum format_options[4] = { GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA }; - GLenum format = format_options[mCurrentPreviewImage->getComponents()-1]; - - GLenum internal_format_options[4] = { GL_LUMINANCE8, GL_LUMINANCE8_ALPHA8, GL_RGB8, GL_RGBA8 }; - GLenum internal_format = internal_format_options[mCurrentPreviewImage->getComponents()-1]; - - if (mGLName) - { - LLImageGL::bindExternalTexture( mGLName, 0, GL_TEXTURE_2D ); - } - else - { - glGenTextures(1, &mGLName ); - stop_glerror(); - - LLImageGL::bindExternalTexture( mGLName, 0, GL_TEXTURE_2D ); - stop_glerror(); - - glTexImage2D( - GL_TEXTURE_2D, 0, internal_format, - mCurrentPreviewImage->getWidth(), mCurrentPreviewImage->getHeight(), - 0, format, GL_UNSIGNED_BYTE, mCurrentPreviewImage->getData()); - stop_glerror(); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - - glColor3f(1.f, 1.f, 1.f); - glBegin( GL_QUADS ); - { - glTexCoord2f(0, 1); - glVertex2i(PreviewImageRect.mLeft, PreviewImageRect.mTop); - glTexCoord2f(0, 0); - glVertex2i(PreviewImageRect.mLeft, PreviewImageRect.mBottom); - glTexCoord2f(1, 0); - glVertex2i(PreviewImageRect.mRight, PreviewImageRect.mBottom); - glTexCoord2f(1, 1); - glVertex2i(PreviewImageRect.mRight, PreviewImageRect.mTop); - } - glEnd(); - - LLImageGL::unbindTexture(0, GL_TEXTURE_2D); - - stop_glerror(); - } -} - -// static -void LLFloaterImport::finishImport(ImportAssetInfo *info) -{ - // Commenting this code out and removing - // ObjectImport message from the message template - /* - llinfos << "Uploading object " << info->FilenameAndPath << "..." << llendl; - - LLUUID new_file_id; - new_file_id.generate(); - bool generated_file = false; - - { - // Copy file into a local directory - LLString new_file = "TEMP"; - new_file.append(new_file_id.asString()); - new_file.append(".slobject"); - - S32 length; - apr_file_t* fIn = ll_apr_file_open(info->FilenameAndPath.c_str(), LL_APR_RB, &length); - if (fIn) - { - apr_file_t* fOut = ll_apr_file_open(new_file, LL_APR_WB); - if (fOut) - { - char *buffer = new char[length]; - ll_apr_file_read(fIn, buffer, length); - ll_apr_file_write(fOut, buffer, length); - delete[] buffer; - generated_file = true; - apr_file_close(fOut); - } - apr_file_close(fIn); - } - } - - if (generated_file) - { - LLMessageSystem *msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ObjectImport); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_FolderID, gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT)); - msg->nextBlockFast(_PREHASH_AssetData); - msg->addUUIDFast(_PREHASH_FileID, new_file_id); - msg->addStringFast(_PREHASH_ObjectName, info->Name); - msg->addStringFast(_PREHASH_Description, info->Desc); - msg->sendReliable(gAgent.getRegionHost()); - - LLUploadDialog::modalUploadDialog("Importing geometry..."); - - sImportRequestID = new_file_id; - } - else - { - llinfos << "Failed to copy file." << llendl; - }*/ -} - -// static -void LLFloaterImport::asset_uploaded_callback(const LLUUID& uuid, void* user_data, S32 result, LLExtStat ext_status) -{ - llinfos << "LLFloaterImport: Finished uploading image." << llendl; - LLResourceData *resource_data = (LLResourceData*)user_data; - ImportAssetInfo *info = (ImportAssetInfo*)resource_data->mUserData; - - info->NewImageIDList.push_back(resource_data->mAssetInfo.mUuid.asString()); - - LLUploadDialog::modalUploadFinished(); - if (info->ImageFileQueue.size() == 0) - { - finishImport(info); - } - else - { - // Start the next download - LLString current_image = info->ImageFileQueue[0].c_str(); - info->ImageFileQueue.erase(info->ImageFileQueue.begin()); - - upload_new_resource(current_image, info->Name, // file - info->Desc, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE, - PERM_NONE, LLString::null, asset_uploaded_callback, info); - } -} - -//----------------------------------------------------------------------------- -// static onBtnOK() -//----------------------------------------------------------------------------- -void LLFloaterImport::onBtnOK(void*userdata) -{ - LLFloaterImport *fp =(LLFloaterImport*)userdata; - - ImportAssetInfo *asset_info = new ImportAssetInfo(); - asset_info->Name = fp->mNameEditor->getText(); - asset_info->Desc = fp->mDescEditor->getText(); - asset_info->FilenameAndPath = fp->mFilenameAndPath; - asset_info->SourcePath = fp->mInventoryPath; - - std::vector items = fp->mImportList->getAllSelected(); - std::vector::iterator itor; - if (items.size() > 0) - { - for (itor = items.begin(); itor != items.end(); ++itor) - { - LLUUID id = (*itor)->getUUID(); - - //if (!id->isNull()) - LLString *image_id = (LLString *)(*itor)->getUserdata(); - if (image_id) - { - asset_info->OldImageIDList.push_back(id.asString()); - LLString image_file = fp->mInventoryPath; - image_file.append(gDirUtilp->getDirDelimiter()); - image_file.append(*image_id); - image_file.append(".tga"); - llinfos << "Uploading image " << image_file << "..." << llendl; - asset_info->ImageFileQueue.push_back(image_file); - } - } - if (asset_info->ImageFileQueue.size() == 0) - { - finishImport(asset_info); - } - else - { - // Start the first download - LLString current_image = asset_info->ImageFileQueue[0].c_str(); - asset_info->ImageFileQueue.erase(asset_info->ImageFileQueue.begin()); - - upload_new_resource(current_image, asset_info->Name, // file - asset_info->Desc, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE, - PERM_NONE, LLString::null, asset_uploaded_callback, asset_info); - } - } - else - { - finishImport(asset_info); - } - - fp->close(false); -} - -//----------------------------------------------------------------------------- -// static onBtnCancel() -//----------------------------------------------------------------------------- -void LLFloaterImport::onBtnCancel(void*userdata) -{ - LLFloaterImport *fp =(LLFloaterImport*)userdata; - fp->close(false); -} - - -//----------------------------------------------------------------------------- -// virtual handleMouseDown() -//----------------------------------------------------------------------------- -BOOL LLFloaterImport::handleMouseDown(S32 x, S32 y, MASK mask) -{ - BOOL ret = LLFloater::handleMouseDown(x, y, mask); - recalcCost(); - - LLUUID current_preview_uuid; - LLString current_preview_name = "none"; - - LLScrollListItem *item; - - // Did we just select something? - item = mImportList->getLastSelectedItem(); - if (item) - { - current_preview_uuid = item->getUUID(); - current_preview_name = item->getColumn(2)->getValue().asString(); - } - else - { - // If not, see if exactly one object is selected - std::vector items = mImportList->getAllSelected(); - std::vector::iterator itor; - for (itor = items.begin(); itor != items.end(); ++itor) - { - if (current_preview_uuid.isNull()) - { - current_preview_uuid = (*itor)->getUUID(); - current_preview_name = (*itor)->getColumn(2)->getValue().asString(); - } - else - { - // More than one item is selected. Turn off preview - current_preview_uuid.setNull(); - current_preview_name = "none"; - break; - } - } - } - - mCurrentPreviewImage = NULL; - if (current_preview_uuid.notNull()) - { - image_map_t::iterator itor; - itor = mPreviewImages.find(current_preview_uuid); - if (itor != mPreviewImages.end()) - { - mCurrentPreviewImage = itor->second; - if (mGLName) - { - glDeleteTextures(1, &mGLName ); - } - mGLName = 0; - } - } - LLString label_text = "Image Preview: "; - label_text.append(current_preview_name); - mImageLabel->setText(label_text); - - return ret; -} diff --git a/linden/indra/newview/llfloaterimport.h b/linden/indra/newview/llfloaterimport.h deleted file mode 100644 index f633196..0000000 --- a/linden/indra/newview/llfloaterimport.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @file llfloaterimport.h - * @brief LLFloaterImport class definition - * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -// llfloaterimport.h -// -// copyright 2005, linden research inc - -#ifndef LL_LLFLOATERIMPORT_H -#define LL_LLFLOATERIMPORT_H - -#include "lldynamictexture.h" -#include "llfloater.h" -#include "llresizehandle.h" -#include "llscrolllistctrl.h" -#include "lluploaddialog.h" -#include "llxmlnode.h" -#include "llquaternion.h" - -class LLComboBox; -class LLJoint; -class LLViewerJointMesh; -class LLVOAvatar; -class LLTextBox; - -struct ImportAssetInfo -{ - LLString Name; - LLString Desc; - LLString FilenameAndPath; - LLString SourcePath; - std::vector ImageFileQueue; - std::vector OldImageIDList; - std::vector NewImageIDList; -}; - -class LLFloaterImport : public LLFloater -{ -public: - LLFloaterImport(const std::string filename); - virtual ~LLFloaterImport(); - - virtual BOOL postBuild(); - - static void setOKText(const char* text) { sOKText = text; } - - void recalcCost(); - - static LLUUID sImportRequestID; - -protected: - LLXMLNodePtr mObjectFile; - - LLScrollListCtrl* mImportList; - LLLineEditor* mNameEditor; - LLLineEditor* mDescEditor; - LLButton* mOKBtn; - LLButton* mCancelBtn; - LLTextBox* mImageLabel; - - LLString mFilenameAndPath; - LLString mFilename; - LLString mFilePath; - LLString mInventoryPath; - - typedef std::map > image_map_t; - image_map_t mPreviewImages; - LLPointer mCurrentPreviewImage; - GLuint mGLName; - - LLUploadDialog* mImportDialog; - -protected: - static LLString sOKText; - - static void onBtnOK(void*); - static void onBtnCancel(void*); - - static void asset_uploaded_callback(const LLUUID& uuid, void* user_data, S32 result, LLExtStat ext_status); - static void finishImport(ImportAssetInfo *fp); - - void draw(); - void LoadPreviewImage(LLString image_path, LLUUID image_uuid); - BOOL handleMouseDown(S32 x, S32 y, MASK mask); -}; - -#endif // LL_LLFLOATERIMPORT_H diff --git a/linden/indra/newview/llfloaterinspect.cpp b/linden/indra/newview/llfloaterinspect.cpp index 70b7a29..cdca428 100644 --- a/linden/indra/newview/llfloaterinspect.cpp +++ b/linden/indra/newview/llfloaterinspect.cpp @@ -211,18 +211,13 @@ void LLFloaterInspect::refresh() { LLSelectNode* obj = *iter; LLSD row; - char owner_first_name[MAX_STRING], owner_last_name[MAX_STRING]; - char creator_first_name[MAX_STRING], creator_last_name[MAX_STRING]; char time[MAX_STRING]; - std::ostringstream owner_name, creator_name, date; + std::string owner_name, creator_name; time_t timestamp = (time_t) (obj->mCreationDate/1000000); LLString::copy(time, ctime(×tamp), MAX_STRING); time[24] = '\0'; - date << obj->mCreationDate; - gCacheName->getName(obj->mPermissions->getOwner(), owner_first_name, owner_last_name); - owner_name << owner_first_name << " " << owner_last_name; - gCacheName->getName(obj->mPermissions->getCreator(), creator_first_name, creator_last_name); - creator_name << creator_first_name << " " << creator_last_name; + gCacheName->getFullName(obj->mPermissions->getOwner(), owner_name); + gCacheName->getFullName(obj->mPermissions->getCreator(), creator_name); row["id"] = obj->getObject()->getID(); row["columns"][0]["column"] = "object_name"; row["columns"][0]["type"] = "text"; @@ -238,10 +233,10 @@ void LLFloaterInspect::refresh() } row["columns"][1]["column"] = "owner_name"; row["columns"][1]["type"] = "text"; - row["columns"][1]["value"] = owner_name.str().c_str(); + row["columns"][1]["value"] = owner_name; row["columns"][2]["column"] = "creator_name"; row["columns"][2]["type"] = "text"; - row["columns"][2]["value"] = creator_name.str().c_str(); + row["columns"][2]["value"] = creator_name; row["columns"][3]["column"] = "creation_date"; row["columns"][3]["type"] = "text"; row["columns"][3]["value"] = time; diff --git a/linden/indra/newview/llfloaterinspect.h b/linden/indra/newview/llfloaterinspect.h index 31ca2fc..5db1dae 100644 --- a/linden/indra/newview/llfloaterinspect.h +++ b/linden/indra/newview/llfloaterinspect.h @@ -67,7 +67,7 @@ private: // static data static LLFloaterInspect* sInstance; - LLHandle mObjectSelection; + LLSafeHandle mObjectSelection; }; #endif //LL_LLFLOATERINSPECT_H diff --git a/linden/indra/newview/llfloaterlagmeter.cpp b/linden/indra/newview/llfloaterlagmeter.cpp index 2d4f65d..4acc524 100644 --- a/linden/indra/newview/llfloaterlagmeter.cpp +++ b/linden/indra/newview/llfloaterlagmeter.cpp @@ -72,49 +72,49 @@ LLFloaterLagMeter::LLFloaterLagMeter() mServerText = LLUICtrlFactory::getTextBoxByName(this, "server_text"); mServerCause = LLUICtrlFactory::getTextBoxByName(this, "server_lag_cause"); - LLString config_string = childGetText("client_frame_rate_critical_fps"); + LLString config_string = getString("client_frame_rate_critical_fps", mStringArgs); mClientFrameTimeCritical = 1.0f / (float)atof( config_string.c_str() ); - config_string = childGetText("client_frame_rate_warning_fps"); + config_string = getString("client_frame_rate_warning_fps", mStringArgs); mClientFrameTimeWarning = 1.0f / (float)atof( config_string.c_str() ); - config_string = childGetText("network_packet_loss_critical_pct"); + config_string = getString("network_packet_loss_critical_pct", mStringArgs); mNetworkPacketLossCritical = (float)atof( config_string.c_str() ); - config_string = childGetText("network_packet_loss_warning_pct"); + config_string = getString("network_packet_loss_warning_pct", mStringArgs); mNetworkPacketLossWarning = (float)atof( config_string.c_str() ); - config_string = childGetText("network_ping_critical_ms"); + config_string = getString("network_ping_critical_ms", mStringArgs); mNetworkPingCritical = (float)atof( config_string.c_str() ); - config_string = childGetText("network_ping_warning_ms"); + config_string = getString("network_ping_warning_ms", mStringArgs); mNetworkPingWarning = (float)atof( config_string.c_str() ); - config_string = childGetText("server_frame_rate_critical_fps"); + config_string = getString("server_frame_rate_critical_fps", mStringArgs); mServerFrameTimeCritical = 1000.0f / (float)atof( config_string.c_str() ); - config_string = childGetText("server_frame_rate_warning_fps"); + config_string = getString("server_frame_rate_warning_fps", mStringArgs); mServerFrameTimeWarning = 1000.0f / (float)atof( config_string.c_str() ); - config_string = childGetText("server_single_process_max_time_ms"); + config_string = getString("server_single_process_max_time_ms", mStringArgs); mServerSingleProcessMaxTime = (float)atof( config_string.c_str() ); mShrunk = false; - config_string = childGetText("max_width_px"); + config_string = getString("max_width_px", mStringArgs); mMaxWidth = atoi( config_string.c_str() ); - config_string = childGetText("min_width_px"); + config_string = getString("min_width_px", mStringArgs); mMinWidth = atoi( config_string.c_str() ); - childSetTextArg("client_frame_time_critical_msg", "[CLIENT_FRAME_RATE_CRITICAL]", childGetText("client_frame_rate_critical_fps")); - childSetTextArg("client_frame_time_warning_msg", "[CLIENT_FRAME_RATE_CRITICAL]", childGetText("client_frame_rate_critical_fps")); - childSetTextArg("client_frame_time_warning_msg", "[CLIENT_FRAME_RATE_WARNING]", childGetText("client_frame_rate_warning_fps")); + mStringArgs["[CLIENT_FRAME_RATE_CRITICAL]"] = getString("client_frame_rate_critical_fps"); + mStringArgs["[CLIENT_FRAME_RATE_CRITICAL]"] = getString("client_frame_rate_critical_fps"); + mStringArgs["[CLIENT_FRAME_RATE_WARNING]"] = getString("client_frame_rate_warning_fps"); - childSetTextArg("network_packet_loss_critical_msg", "[NETWORK_PACKET_LOSS_CRITICAL]", childGetText("network_packet_loss_critical_pct")); - childSetTextArg("network_packet_loss_warning_msg", "[NETWORK_PACKET_LOSS_CRITICAL]", childGetText("network_packet_loss_critical_pct")); - childSetTextArg("network_packet_loss_warning_msg", "[NETWORK_PACKET_LOSS_WARNING]", childGetText("network_packet_loss_warning_pct")); + mStringArgs["[NETWORK_PACKET_LOSS_CRITICAL]"] = getString("network_packet_loss_critical_pct"); + mStringArgs["[NETWORK_PACKET_LOSS_CRITICAL]"] = getString("network_packet_loss_critical_pct"); + mStringArgs["[NETWORK_PACKET_LOSS_WARNING]"] = getString("network_packet_loss_warning_pct"); - childSetTextArg("network_ping_critical_msg", "[NETWORK_PING_CRITICAL]", childGetText("network_ping_critical_ms")); - childSetTextArg("network_ping_warning_msg", "[NETWORK_PING_CRITICAL]", childGetText("network_ping_critical_ms")); - childSetTextArg("network_ping_warning_msg", "[NETWORK_PING_WARNING]", childGetText("network_ping_warning_ms")); + mStringArgs["[NETWORK_PING_CRITICAL]"] = getString("network_ping_critical_ms"); + mStringArgs["[NETWORK_PING_CRITICAL]"] = getString("network_ping_critical_ms"); + mStringArgs["[NETWORK_PING_WARNING]"] = getString("network_ping_warning_ms"); - childSetTextArg("server_frame_time_critical_msg", "[SERVER_FRAME_RATE_CRITICAL]", childGetText("server_frame_rate_critical_fps")); - childSetTextArg("server_frame_time_warning_msg", "[SERVER_FRAME_RATE_CRITICAL]", childGetText("server_frame_rate_critical_fps")); - childSetTextArg("server_frame_time_warning_msg", "[SERVER_FRAME_RATE_WARNING]", childGetText("server_frame_rate_warning_fps")); + mStringArgs["[SERVER_FRAME_RATE_CRITICAL]"] = getString("server_frame_rate_critical_fps"); + mStringArgs["[SERVER_FRAME_RATE_CRITICAL]"] = getString("server_frame_rate_critical_fps"); + mStringArgs["[SERVER_FRAME_RATE_WARNING]"] = getString("server_frame_rate_warning_fps"); childSetAction("minimize", onClickShrink, this); @@ -162,25 +162,25 @@ void LLFloaterLagMeter::determineClient() if (!gFocusMgr.getAppHasFocus()) { mClientButton->setImageUnselected(LAG_GOOD_IMAGE_NAME); - mClientText->setText( childGetText("client_frame_time_window_bg_msg") ); + mClientText->setText( getString("client_frame_time_window_bg_msg", mStringArgs) ); mClientCause->setText( LLString::null ); } else if(client_frame_time >= mClientFrameTimeCritical) { mClientButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME); - mClientText->setText( childGetText("client_frame_time_critical_msg") ); + mClientText->setText( getString("client_frame_time_critical_msg", mStringArgs) ); find_cause = true; } else if(client_frame_time >= mClientFrameTimeWarning) { mClientButton->setImageUnselected(LAG_WARNING_IMAGE_NAME); - mClientText->setText( childGetText("client_frame_time_warning_msg") ); + mClientText->setText( getString("client_frame_time_warning_msg", mStringArgs) ); find_cause = true; } else { mClientButton->setImageUnselected(LAG_GOOD_IMAGE_NAME); - mClientText->setText( childGetText("client_frame_time_normal_msg") ); + mClientText->setText( getString("client_frame_time_normal_msg", mStringArgs) ); mClientCause->setText( LLString::null ); } @@ -188,19 +188,19 @@ void LLFloaterLagMeter::determineClient() { if(gSavedSettings.getF32("RenderFarClip") > 128) { - mClientCause->setText( childGetText("client_draw_distance_cause_msg") ); + mClientCause->setText( getString("client_draw_distance_cause_msg", mStringArgs) ); } else if(LLAppViewer::instance()->getTextureFetch()->getNumRequests() > 2) { - mClientCause->setText( childGetText("client_texture_loading_cause_msg") ); + mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) ); } else if(LLViewerImage::sBoundTextureMemory > LLViewerImage::sMaxBoundTextureMem) { - mClientCause->setText( childGetText("client_texture_memory_cause_msg") ); + mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) ); } else { - mClientCause->setText( childGetText("client_complex_objects_cause_msg") ); + mClientCause->setText( getString("client_complex_objects_cause_msg", mStringArgs) ); } } } @@ -215,40 +215,40 @@ void LLFloaterLagMeter::determineNetwork() if(packet_loss >= mNetworkPacketLossCritical) { mNetworkButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME); - mNetworkText->setText( childGetText("network_packet_loss_critical_msg") ); + mNetworkText->setText( getString("network_packet_loss_critical_msg", mStringArgs) ); find_cause_loss = true; } else if(ping_time >= mNetworkPingCritical) { mNetworkButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME); - mNetworkText->setText( childGetText("network_ping_critical_msg") ); + mNetworkText->setText( getString("network_ping_critical_msg", mStringArgs) ); find_cause_ping = true; } else if(packet_loss >= mNetworkPacketLossWarning) { mNetworkButton->setImageUnselected(LAG_WARNING_IMAGE_NAME); - mNetworkText->setText( childGetText("network_packet_loss_warning_msg") ); + mNetworkText->setText( getString("network_packet_loss_warning_msg", mStringArgs) ); find_cause_loss = true; } else if(ping_time >= mNetworkPingWarning) { mNetworkButton->setImageUnselected(LAG_WARNING_IMAGE_NAME); - mNetworkText->setText( childGetText("network_ping_warning_msg") ); + mNetworkText->setText( getString("network_ping_warning_msg", mStringArgs) ); find_cause_ping = true; } else { mNetworkButton->setImageUnselected(LAG_GOOD_IMAGE_NAME); - mNetworkText->setText( childGetText("network_performance_normal_msg") ); + mNetworkText->setText( getString("network_performance_normal_msg", mStringArgs) ); } if(find_cause_loss) { - mNetworkCause->setText( childGetText("network_packet_loss_cause_msg") ); + mNetworkCause->setText( getString("network_packet_loss_cause_msg", mStringArgs) ); } else if(find_cause_ping) { - mNetworkCause->setText( childGetText("network_ping_cause_msg") ); + mNetworkCause->setText( getString("network_ping_cause_msg", mStringArgs) ); } else { @@ -264,19 +264,19 @@ void LLFloaterLagMeter::determineServer() if(sim_frame_time >= mServerFrameTimeCritical) { mServerButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME); - mServerText->setText( childGetText("server_frame_time_critical_msg") ); + mServerText->setText( getString("server_frame_time_critical_msg", mStringArgs) ); find_cause = true; } else if(sim_frame_time >= mServerFrameTimeWarning) { mServerButton->setImageUnselected(LAG_WARNING_IMAGE_NAME); - mServerText->setText( childGetText("server_frame_time_warning_msg") ); + mServerText->setText( getString("server_frame_time_warning_msg", mStringArgs) ); find_cause = true; } else { mServerButton->setImageUnselected(LAG_GOOD_IMAGE_NAME); - mServerText->setText( childGetText("server_frame_time_normal_msg") ); + mServerText->setText( getString("server_frame_time_normal_msg", mStringArgs) ); mServerCause->setText( LLString::null ); } @@ -284,27 +284,27 @@ void LLFloaterLagMeter::determineServer() { if(gViewerStats->mSimSimPhysicsMsec.getCurrent() > mServerSingleProcessMaxTime) { - mServerCause->setText( childGetText("server_physics_cause_msg") ); + mServerCause->setText( getString("server_physics_cause_msg", mStringArgs) ); } else if(gViewerStats->mSimScriptMsec.getCurrent() > mServerSingleProcessMaxTime) { - mServerCause->setText( childGetText("server_scripts_cause_msg") ); + mServerCause->setText( getString("server_scripts_cause_msg", mStringArgs) ); } else if(gViewerStats->mSimNetMsec.getCurrent() > mServerSingleProcessMaxTime) { - mServerCause->setText( childGetText("server_net_cause_msg") ); + mServerCause->setText( getString("server_net_cause_msg", mStringArgs) ); } else if(gViewerStats->mSimAgentMsec.getCurrent() > mServerSingleProcessMaxTime) { - mServerCause->setText( childGetText("server_agent_cause_msg") ); + mServerCause->setText( getString("server_agent_cause_msg", mStringArgs) ); } else if(gViewerStats->mSimImagesMsec.getCurrent() > mServerSingleProcessMaxTime) { - mServerCause->setText( childGetText("server_images_cause_msg") ); + mServerCause->setText( getString("server_images_cause_msg", mStringArgs) ); } else { - mServerCause->setText( childGetText("server_generic_cause_msg") ); + mServerCause->setText( getString("server_generic_cause_msg", mStringArgs) ); } } } @@ -314,38 +314,38 @@ void LLFloaterLagMeter::onClickShrink(void * data) { LLFloaterLagMeter * self = (LLFloaterLagMeter*)data; - LLButton * button = (LLButton*)self->getChildByName("minimize"); + LLButton * button = self->getChild("minimize"); S32 delta_width = self->mMaxWidth - self->mMinWidth; LLRect r = self->getRect(); if(self->mShrunk) { - self->setTitle( self->childGetText("max_title_msg") ); + self->setTitle( self->getString("max_title_msg", self->mStringArgs) ); // make left edge appear to expand r.translate(-delta_width, 0); self->setRect(r); self->reshape(self->mMaxWidth, self->getRect().getHeight()); - self->childSetText("client", self->childGetText("client_text_msg") + ":"); - self->childSetText("network", self->childGetText("network_text_msg") + ":"); - self->childSetText("server", self->childGetText("server_text_msg") + ":"); + self->childSetText("client", self->getString("client_text_msg", self->mStringArgs) + ":"); + self->childSetText("network", self->getString("network_text_msg", self->mStringArgs) + ":"); + self->childSetText("server", self->getString("server_text_msg", self->mStringArgs) + ":"); // usually "<<" - button->setLabel( self->childGetText("smaller_label") ); + button->setLabel( self->getString("smaller_label", self->mStringArgs) ); } else { - self->setTitle( self->childGetText("min_title_msg") ); + self->setTitle( self->getString("min_title_msg", self->mStringArgs) ); // make left edge appear to collapse r.translate(delta_width, 0); self->setRect(r); self->reshape(self->mMinWidth, self->getRect().getHeight()); - self->childSetText("client", self->childGetText("client_text_msg") ); - self->childSetText("network", self->childGetText("network_text_msg") ); - self->childSetText("server", self->childGetText("server_text_msg") ); + self->childSetText("client", self->getString("client_text_msg", self->mStringArgs) ); + self->childSetText("network", self->getString("network_text_msg", self->mStringArgs) ); + self->childSetText("server", self->getString("server_text_msg", self->mStringArgs) ); // usually ">>" - button->setLabel( self->childGetText("bigger_label") ); + button->setLabel( self->getString("bigger_label", self->mStringArgs) ); } // Don't put keyboard focus on the button button->setFocus(FALSE); diff --git a/linden/indra/newview/llfloaterlagmeter.h b/linden/indra/newview/llfloaterlagmeter.h index dc6d92b..ab29193 100644 --- a/linden/indra/newview/llfloaterlagmeter.h +++ b/linden/indra/newview/llfloaterlagmeter.h @@ -74,6 +74,8 @@ private: LLTextBox * mServerText; LLTextBox * mServerCause; + LLString::format_map_t mStringArgs; + static LLFloaterLagMeter * sInstance; }; diff --git a/linden/indra/newview/llfloaterland.cpp b/linden/indra/newview/llfloaterland.cpp index 447571d..c75917b 100644 --- a/linden/indra/newview/llfloaterland.cpp +++ b/linden/indra/newview/llfloaterland.cpp @@ -31,8 +31,6 @@ #include "llviewerprecompiledheaders.h" -#include - #include "llfloaterland.h" #include "llcachename.h" @@ -53,6 +51,7 @@ #include "lllineeditor.h" #include "llnamelistctrl.h" #include "llnotify.h" +#include "llpanellandmedia.h" #include "llradiogroup.h" #include "llscrolllistctrl.h" #include "llselectmgr.h" @@ -68,10 +67,39 @@ #include "llviewerstats.h" #include "llviewertexteditor.h" #include "llviewerwindow.h" -#include "llmediaengine.h" #include "llviewercontrol.h" #include "roles_constants.h" +#include +#include + +static const S32 EDIT_HEIGHT = 16; +static const S32 LEFT = HPAD; +static const S32 BOTTOM = VPAD; +static const S32 RULER0 = LEFT; +static const S32 RULER05 = RULER0 + 24; +static const S32 RULER1 = RULER05 + 16; +static const S32 RULER15 = RULER1 + 20; +static const S32 RULER2 = RULER1 + 32; +static const S32 RULER205= RULER2 + 32; +static const S32 RULER20 = RULER2 + 64; +static const S32 RULER21 = RULER20 + 16; +static const S32 RULER22 = RULER21 + 32; +static const S32 RULER225 = RULER20 + 64; +static const S32 RULER23 = RULER22 + 64; +static const S32 RULER24 = RULER23 + 26; +static const S32 RULER3 = RULER2 + 102; +static const S32 RULER4 = RULER3 + 8; +static const S32 RULER5 = RULER4 + 50; +static const S32 RULER6 = RULER5 + 52; +static const S32 RULER7 = RULER6 + 24; +static const S32 RIGHT = LEFT + 278; +static const S32 FAR_RIGHT = LEFT + 324 + 40; + +static const char PRICE[] = "Price:"; +static const char NO_PRICE[] = ""; +static const char AREA[] = "Area:"; + static const char OWNER_ONLINE[] = "0"; static const char OWNER_OFFLINE[] = "1"; static const char OWNER_GROUP[] = "2"; @@ -80,20 +108,11 @@ static const char OWNER_GROUP[] = "2"; static const BOOL BUY_GROUP_LAND = TRUE; static const BOOL BUY_PERSONAL_LAND = FALSE; -// Values for the parcel voice settings radio group -enum -{ - kRadioVoiceChatEstate = 0, - kRadioVoiceChatPrivate = 1, - kRadioVoiceChatDisable = 2 -}; - // Statics -LLFloaterLand* LLFloaterLand::sInstance = NULL; LLParcelSelectionObserver* LLFloaterLand::sObserver = NULL; S32 LLFloaterLand::sLastTab = 0; -LLViewHandle LLPanelLandGeneral::sBuyPassDialogHandle; +LLHandle LLPanelLandGeneral::sBuyPassDialogHandle; // Local classes class LLParcelSelectionObserver : public LLParcelObserver @@ -150,64 +169,38 @@ void send_parcel_select_objects(S32 parcel_local_id, S32 return_type, } -// static -void LLFloaterLand::show() -{ - if (!sInstance) - { - sInstance = new LLFloaterLand(); - - // Select tab from last view - sInstance->mTabLand->selectTab(sLastTab); - - sObserver = new LLParcelSelectionObserver(); - gParcelMgr->addObserver( sObserver ); - } - - sInstance->open(); /*Flawfinder: ignore*/ - - // Done automatically when the selected parcel's properties arrive - // (and hence we have the local id). - // gParcelMgr->sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_RENTER); - - sInstance->mParcel = gParcelMgr->getFloatingParcelSelection(); - - // Refresh even if not over a region so we don't get an - // uninitialized dialog. The dialog is 0-region aware. - sInstance->refresh(); -} - //static LLPanelLandObjects* LLFloaterLand::getCurrentPanelLandObjects() { - if (!sInstance) - { - return NULL; - } - - return sInstance->mPanelObjects; + return LLFloaterLand::getInstance()->mPanelObjects; } //static LLPanelLandCovenant* LLFloaterLand::getCurrentPanelLandCovenant() { - if (!sInstance) - { - return NULL; - } - - return sInstance->mPanelCovenant; + return LLFloaterLand::getInstance()->mPanelCovenant; } // static void LLFloaterLand::refreshAll() { - if (sInstance) - { - sInstance->refresh(); - } + LLFloaterLand::getInstance()->refresh(); } +void LLFloaterLand::onOpen() +{ + // Done automatically when the selected parcel's properties arrive + // (and hence we have the local id). + // gParcelMgr->sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_RENTER); + + mParcel = gParcelMgr->getFloatingParcelSelection(); + + // Refresh even if not over a region so we don't get an + // uninitialized dialog. The dialog is 0-region aware. + refresh(); +} + + // virtual void LLFloaterLand::onClose(bool app_quitting) { @@ -225,7 +218,7 @@ void LLFloaterLand::onClose(bool app_quitting) } -LLFloaterLand::LLFloaterLand() +LLFloaterLand::LLFloaterLand(const LLSD& seed) : LLFloater("floaterland", "FloaterLandRect5", "About Land") { @@ -240,10 +233,15 @@ LLFloaterLand::LLFloaterLand() factory_map["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this); factory_map["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this); - gUICtrlFactory->buildFloater(this, "floater_about_land.xml", &factory_map); + gUICtrlFactory->buildFloater(this, "floater_about_land.xml", &factory_map, false); + sObserver = new LLParcelSelectionObserver(); + gParcelMgr->addObserver( sObserver ); +} - LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(this, "landtab"); +BOOL LLFloaterLand::postBuild() +{ + LLTabContainer* tab = LLUICtrlFactory::getTabContainerByName(this, "landtab"); mTabLand = (LLTabContainer*) tab; @@ -252,16 +250,16 @@ LLFloaterLand::LLFloaterLand() { tab->selectTab(sLastTab); } + + return TRUE; } // virtual LLFloaterLand::~LLFloaterLand() { - sInstance = NULL; } - // public void LLFloaterLand::refresh() { @@ -481,7 +479,7 @@ void LLPanelLandGeneral::refresh() mCheckContributeWithDeed->setEnabled(FALSE); mTextOwner->setText(LLString::null); - mBtnProfile->setLabel(childGetText("profile_text")); + mBtnProfile->setLabel(getString("profile_text")); mBtnProfile->setEnabled(FALSE); mTextClaimDate->setText(LLString::null); @@ -535,12 +533,12 @@ void LLPanelLandGeneral::refresh() { mTextSalePending->setText(LLString::null); mTextSalePending->setEnabled(FALSE); - mTextOwner->setText(childGetText("public_text")); + mTextOwner->setText(getString("public_text")); mTextOwner->setEnabled(FALSE); mBtnProfile->setEnabled(FALSE); mTextClaimDate->setText(LLString::null); mTextClaimDate->setEnabled(FALSE); - mTextGroup->setText(childGetText("none_text")); + mTextGroup->setText(getString("none_text")); mTextGroup->setEnabled(FALSE); mBtnStartAuction->setEnabled(FALSE); } @@ -548,12 +546,12 @@ void LLPanelLandGeneral::refresh() { if(!is_leased && (owner_id == gAgent.getID())) { - mTextSalePending->setText(childGetText("need_tier_to_modify")); + mTextSalePending->setText(getString("need_tier_to_modify")); mTextSalePending->setEnabled(TRUE); } else if(parcel->getAuctionID()) { - mTextSalePending->setText(childGetText("auction_id_text")); + mTextSalePending->setText(getString("auction_id_text")); mTextSalePending->setTextArg("[ID]", llformat("%u", parcel->getAuctionID())); mTextSalePending->setEnabled(TRUE); } @@ -572,15 +570,15 @@ void LLPanelLandGeneral::refresh() if (parcel->getGroupID().isNull()) { // Not group owned, so "Profile" - mBtnProfile->setLabel(childGetText("profile_text")); + mBtnProfile->setLabel(getString("profile_text")); - mTextGroup->setText(childGetText("none_text")); + mTextGroup->setText(getString("none_text")); mTextGroup->setEnabled(FALSE); } else { // Group owned, so "Info" - mBtnProfile->setLabel(childGetText("info_text")); + mBtnProfile->setLabel(getString("info_text")); //mTextGroup->setText("HIPPOS!");//parcel->getGroupName()); mTextGroup->setEnabled(TRUE); @@ -690,9 +688,9 @@ void LLPanelLandGeneral::refresh() &dwell); // Area - LLUIString price = childGetText("area_size_text"); + LLUIString price = getString("area_size_text"); price.setArg("[AREA]", llformat("%d",area)); - mTextPriceLabel->setText(childGetText("area_text")); + mTextPriceLabel->setText(getString("area_text")); mTextPrice->setText(price.getString()); mTextDwell->setText(llformat("%.0f", dwell)); @@ -730,29 +728,24 @@ void LLPanelLandGeneral::refreshNames() LLString owner; if (parcel->getIsGroupOwned()) { - owner = childGetText("group_owned_text"); + owner = getString("group_owned_text"); } else { // Figure out the owner's name - char owner_first[MAX_STRING]; /*Flawfinder: ignore*/ - char owner_last[MAX_STRING]; /*Flawfinder: ignore*/ - gCacheName->getName(parcel->getOwnerID(), owner_first, owner_last); - owner = llformat("%s %s", owner_first, owner_last); + gCacheName->getFullName(parcel->getOwnerID(), owner); } if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus()) { - owner += childGetText("sale_pending_text"); + owner += getString("sale_pending_text"); } mTextOwner->setText(owner); LLString group; if(!parcel->getGroupID().isNull()) { - char buffer[MAX_STRING]; /*Flawfinder: ignore*/ - gCacheName->getGroupName(parcel->getGroupID(), buffer); - group = buffer; + gCacheName->getGroupName(parcel->getGroupID(), group); } mTextGroup->setText(group); @@ -760,18 +753,12 @@ void LLPanelLandGeneral::refreshNames() if(auth_buyer_id.notNull()) { LLString name; - char firstname[MAX_STRING]; /*Flawfinder: ignore*/ - char lastname[MAX_STRING]; /*Flawfinder: ignore*/ - gCacheName->getName(auth_buyer_id, firstname, lastname); - name.assign(firstname); - name.append(" "); - name.append(lastname); - + gCacheName->getFullName(auth_buyer_id, name); mSaleInfoForSale2->setTextArg("[BUYER]", name); } else { - mSaleInfoForSale2->setTextArg("[BUYER]", childGetText("anyone")); + mSaleInfoForSale2->setTextArg("[BUYER]", getString("anyone")); } } @@ -947,7 +934,7 @@ void LLPanelLandGeneral::cbBuyPass(S32 option, void* data) //static BOOL LLPanelLandGeneral::buyPassDialogVisible() { - return LLFloater::getFloaterByHandle(sBuyPassDialogHandle) != NULL; + return sBuyPassDialogHandle.get() != NULL; } // static @@ -1069,7 +1056,7 @@ BOOL LLPanelLandObjects::postBuild() image_id.set( gViewerArt.getString("icon_group.tga") ); mIconGroup = gImageList.getImage(image_id, MIPMAP_FALSE, TRUE); - mOwnerList = LLUICtrlFactory::getNameListByName(this, "owner list"); + mOwnerList = getChild("owner list"); mOwnerList->sortByColumn(3, FALSE); childSetCommitCallback("owner list", onCommitList, this); mOwnerList->setDoubleClickCallback(onDoubleClickOwner); @@ -1179,12 +1166,12 @@ void LLPanelLandObjects::refresh() if (sw_total > sw_max) { - mSWTotalObjects->setText(childGetText("objects_deleted_text")); + mSWTotalObjects->setText(getString("objects_deleted_text")); mSWTotalObjects->setTextArg("[DELETED]", llformat("%d", sw_total - sw_max)); } else { - mSWTotalObjects->setText(childGetText("objects_available_text")); + mSWTotalObjects->setText(getString("objects_available_text")); mSWTotalObjects->setTextArg("[AVAILABLE]", llformat("%d", sw_max - sw_total)); } mSWTotalObjects->setTextArg("[COUNT]", llformat("%d", sw_total)); @@ -1309,8 +1296,7 @@ void LLPanelLandObjects::callbackReturnOwnerObjects(S32 option, void* userdata) } else { - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + std::string first, last; gCacheName->getName(owner_id, first, last); args["[FIRST]"] = first; args["[LAST]"] = last; @@ -1334,7 +1320,7 @@ void LLPanelLandObjects::callbackReturnGroupObjects(S32 option, void* userdata) { if (parcel) { - char group_name[MAX_STRING]; /*Flawfinder: ignore*/ + std::string group_name; gCacheName->getGroupName(parcel->getGroupID(), group_name); LLString::format_map_t args; args["[GROUPNAME]"] = group_name; @@ -1637,12 +1623,8 @@ void LLPanelLandObjects::onClickReturnOwnerObjects(void* userdata) } else { - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - gCacheName->getName(owner_id, first, last); - std::string name = first; - name += " "; - name += last; + std::string name; + gCacheName->getFullName(owner_id, name); args["[NAME]"] = name; gViewerWindow->alertXml("ReturnObjectsOwnedByUser", args, callbackReturnOwnerObjects, userdata); } @@ -1657,7 +1639,7 @@ void LLPanelLandObjects::onClickReturnGroupObjects(void* userdata) send_parcel_select_objects(parcel->getLocalID(), RT_GROUP); - char group_name[MAX_STRING]; /*Flawfinder: ignore*/ + std::string group_name; gCacheName->getGroupName(parcel->getGroupID(), group_name); LLStringBase::format_map_t args; @@ -1686,7 +1668,7 @@ void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata) if (parcel->getIsGroupOwned()) { - char group_name[MAX_STRING]; /*Flawfinder: ignore*/ + std::string group_name; gCacheName->getGroupName(parcel->getGroupID(), group_name); args["[NAME]"] = group_name; @@ -1702,13 +1684,8 @@ void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata) } else { - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - gCacheName->getName(owner_id, first, last); std::string name; - name += first; - name += " "; - name += last; + gCacheName->getFullName(owner_id, name); args["[NAME]"] = name; gViewerWindow->alertXml("ReturnObjectsNotOwnedByUser", args, callbackReturnOtherObjects, userdata); @@ -1855,7 +1832,7 @@ BOOL LLPanelLandOptions::postBuild() }*/ - mSnapshotCtrl = LLUICtrlFactory::getTexturePickerByName(this, "snapshot_ctrl"); + mSnapshotCtrl = getChild("snapshot_ctrl"); if (mSnapshotCtrl) { mSnapshotCtrl->setCommitCallback( onCommitAny ); @@ -1946,7 +1923,7 @@ void LLPanelLandOptions::refresh() mSnapshotCtrl->setImageAssetID(LLUUID::null); mSnapshotCtrl->setEnabled(FALSE); - mLocationText->setTextArg("[LANDING]", childGetText("landing_point_none")); + mLocationText->setTextArg("[LANDING]", getString("landing_point_none")); mSetBtn->setEnabled(FALSE); mClearBtn->setEnabled(FALSE); @@ -1993,13 +1970,13 @@ void LLPanelLandOptions::refresh() mPushRestrictionCtrl->set( parcel->getRestrictPushObject() ); if(parcel->getRegionPushOverride()) { - mPushRestrictionCtrl->setLabel(childGetText("push_restrict_region_text")); + mPushRestrictionCtrl->setLabel(getString("push_restrict_region_text")); mPushRestrictionCtrl->setEnabled(false); mPushRestrictionCtrl->set(TRUE); } else { - mPushRestrictionCtrl->setLabel(childGetText("push_restrict_text")); + mPushRestrictionCtrl->setLabel(getString("push_restrict_text")); mPushRestrictionCtrl->setEnabled(can_change_options); } @@ -2023,7 +2000,7 @@ void LLPanelLandOptions::refresh() LLVector3 pos = parcel->getUserLocation(); if (pos.isExactlyZero()) { - mLocationText->setTextArg("[LANDING]", childGetText("landing_point_none")); + mLocationText->setTextArg("[LANDING]", getString("landing_point_none")); } else { @@ -2214,240 +2191,8 @@ void LLPanelLandOptions::onClickPublishHelp(void*) } } -//--------------------------------------------------------------------------- -// LLPanelLandMedia -//--------------------------------------------------------------------------- - -LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel) -: LLPanel("land_media_panel"), mParcel(parcel) -{ -} - - -BOOL LLPanelLandMedia::postBuild() -{ - - mCheckSoundLocal = LLUICtrlFactory::getCheckBoxByName(this, "check sound local"); - childSetCommitCallback("check sound local", onCommitAny, this); - - mRadioVoiceChat = LLUICtrlFactory::getRadioGroupByName(this, "parcel_voice_channel"); - childSetCommitCallback("parcel_voice_channel", onCommitAny, this); - - mMusicURLEdit = LLUICtrlFactory::getLineEditorByName(this, "music_url"); - childSetCommitCallback("music_url", onCommitAny, this); - - - mMediaTextureCtrl = LLUICtrlFactory::getTexturePickerByName(this, "media texture"); - if (mMediaTextureCtrl) - { - mMediaTextureCtrl->setCommitCallback( onCommitAny ); - mMediaTextureCtrl->setCallbackUserData( this ); - mMediaTextureCtrl->setAllowNoTexture ( TRUE ); - mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); - mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); - } - else - { - llwarns << "LLUICtrlFactory::getTexturePickerByName() returned NULL for 'media texure'" << llendl; - } - - mMediaAutoScaleCheck = LLUICtrlFactory::getCheckBoxByName(this, "media_auto_scale"); - childSetCommitCallback("media_auto_scale", onCommitAny, this); - - mMediaURLEdit = LLUICtrlFactory::getLineEditorByName(this, "media_url"); - childSetCommitCallback("media_url", onCommitAny, this); - - return TRUE; -} - - -// virtual -LLPanelLandMedia::~LLPanelLandMedia() -{ } - - -// public -void LLPanelLandMedia::refresh() -{ - LLParcel *parcel = mParcel->getParcel(); - - if (!parcel) - { - mCheckSoundLocal->set(FALSE); - mCheckSoundLocal->setEnabled(FALSE); - - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate); - mRadioVoiceChat->setEnabled(FALSE); - - mMusicURLEdit->setText(LLString::null); - mMusicURLEdit->setEnabled(FALSE); - - mMediaURLEdit->setText(LLString::null); - mMediaURLEdit->setEnabled(FALSE); - - mMediaAutoScaleCheck->set ( FALSE ); - mMediaAutoScaleCheck->setEnabled(FALSE); - - mMediaTextureCtrl->clear(); - mMediaTextureCtrl->setEnabled(FALSE); - - #if 0 - mMediaStopButton->setEnabled ( FALSE ); - mMediaStartButton->setEnabled ( FALSE ); - #endif - } - else - { - // something selected, hooray! - - // Display options - BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA); - - mCheckSoundLocal->set( parcel->getSoundLocal() ); - mCheckSoundLocal->setEnabled( can_change_media ); - - LLViewerRegion* selection_region = gParcelMgr->getSelectionRegion(); - BOOL region_allows_voice = FALSE; - if (selection_region) - { - region_allows_voice = selection_region->isVoiceEnabled(); - } - - if(parcel->getVoiceEnabled()) - { - if(parcel->getVoiceUseEstateChannel()) - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate); - else - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatPrivate); - } - else - { - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable); - } - - mRadioVoiceChat->setEnabled( can_change_media && region_allows_voice ); - - // don't display urls if you're not able to change it - // much requested change in forums so people can't 'steal' urls - // NOTE: bug#2009 means this is still vunerable - however, bug - // should be closed since this bug opens up major security issues elsewhere. - if ( can_change_media ) - { - mMusicURLEdit->setDrawAsterixes ( FALSE ); - mMediaURLEdit->setDrawAsterixes ( FALSE ); - } - else - { - mMusicURLEdit->setDrawAsterixes ( TRUE ); - mMediaURLEdit->setDrawAsterixes ( TRUE ); - } - - mMusicURLEdit->setText(parcel->getMusicURL()); - mMusicURLEdit->setEnabled( can_change_media ); - - mMediaURLEdit->setText(parcel->getMediaURL()); - mMediaURLEdit->setEnabled( can_change_media ); - - mMediaAutoScaleCheck->set ( parcel->getMediaAutoScale () ); - mMediaAutoScaleCheck->setEnabled ( can_change_media ); - - LLUUID tmp = parcel->getMediaID(); - mMediaTextureCtrl->setImageAssetID ( parcel->getMediaID() ); - mMediaTextureCtrl->setEnabled( can_change_media ); - - #if 0 - // there is a media url and a media texture selected - if ( ( ! ( std::string ( parcel->getMediaURL() ).empty () ) ) && ( ! ( parcel->getMediaID ().isNull () ) ) ) - { - // turn on transport controls if allowed for this parcel - mMediaStopButton->setEnabled ( editable ); - mMediaStartButton->setEnabled ( editable ); - } - else - { - // no media url or no media texture - mMediaStopButton->setEnabled ( FALSE ); - mMediaStartButton->setEnabled ( FALSE ); - }; - #endif - } -} - -// static -void LLPanelLandMedia::onCommitAny(LLUICtrl *ctrl, void *userdata) -{ - LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; - - LLParcel* parcel = self->mParcel->getParcel(); - if (!parcel) - { - return; - } - - // Extract data from UI - BOOL sound_local = self->mCheckSoundLocal->get(); - int voice_setting = self->mRadioVoiceChat->getSelectedIndex(); - std::string music_url = self->mMusicURLEdit->getText(); - std::string media_url = self->mMediaURLEdit->getText(); - U8 media_auto_scale = self->mMediaAutoScaleCheck->get(); - LLUUID media_id = self->mMediaTextureCtrl->getImageAssetID(); - - BOOL voice_enabled; - BOOL voice_estate_chan; - - switch(voice_setting) - { - default: - case kRadioVoiceChatEstate: - voice_enabled = TRUE; - voice_estate_chan = TRUE; - break; - case kRadioVoiceChatPrivate: - voice_enabled = TRUE; - voice_estate_chan = FALSE; - break; - case kRadioVoiceChatDisable: - voice_enabled = FALSE; - voice_estate_chan = FALSE; - break; - } - - // Remove leading/trailing whitespace (common when copying/pasting) - LLString::trim(music_url); - LLString::trim(media_url); - - // Push data into current parcel - parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, voice_enabled); - parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, voice_estate_chan); - parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local); - parcel->setMusicURL(music_url.c_str()); - parcel->setMediaURL(media_url.c_str()); - parcel->setMediaID(media_id); - parcel->setMediaAutoScale ( media_auto_scale ); - - // Send current parcel data upstream to server - gParcelMgr->sendParcelPropertiesUpdate( parcel ); - - // Might have changed properties, so let's redraw! - self->refresh(); -} - -void LLPanelLandMedia::onClickStopMedia ( void* data ) -{ - LLMediaEngine::getInstance ()->stop (); -} - -void LLPanelLandMedia::onClickStartMedia ( void* data ) -{ - // force a commit - gFocusMgr.setKeyboardFocus ( NULL ); - - // force a reload - LLMediaEngine::getInstance ()->convertImageAndLoadUrl ( true, false, std::string()); -} - //--------------------------------------------------------------------------- // LLPanelLandAccess //--------------------------------------------------------------------------- @@ -2475,11 +2220,11 @@ BOOL LLPanelLandAccess::postBuild() childSetAction("add_banned", onClickAddBanned, this); childSetAction("remove_banned", onClickRemoveBanned, this); - mListAccess = LLUICtrlFactory::getNameListByName(this, "AccessList"); + mListAccess = getChild("AccessList"); if (mListAccess) mListAccess->sortByColumn(0, TRUE); // ascending - mListBanned = LLUICtrlFactory::getNameListByName(this, "BannedList"); + mListBanned = getChild("BannedList"); if (mListBanned) mListBanned->sortByColumn(0, TRUE); // ascending @@ -2510,9 +2255,9 @@ void LLPanelLandAccess::refresh() childSetValue("public_access", public_access ); childSetValue("GroupCheck", use_group ); - char group_name[MAX_STRING]; /*Flawfinder: ignore*/ + std::string group_name; gCacheName->getGroupName(parcel->getGroupID(), group_name); - childSetLabelArg("GroupCheck", "[GROUP]", LLString(group_name) ); + childSetLabelArg("GroupCheck", "[GROUP]", group_name ); // Allow list { @@ -2733,13 +2478,12 @@ void LLPanelLandAccess::refresh_ui() void LLPanelLandAccess::refreshNames() { LLParcel* parcel = mParcel->getParcel(); - char group_name[DB_GROUP_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - group_name[0] = '\0'; + std::string group_name; if(parcel) { gCacheName->getGroupName(parcel->getGroupID(), group_name); } - childSetLabelArg("GroupCheck", "[GROUP]", LLString(group_name)); + childSetLabelArg("GroupCheck", "[GROUP]", group_name); } @@ -2791,7 +2535,7 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata) BOOL use_access_group = self->childGetValue("GroupCheck").asBoolean(); if (use_access_group) { - char group_name[MAX_STRING]; /*Flawfinder: ignore*/ + std::string group_name; if (!gCacheName->getGroupName(parcel->getGroupID(), group_name)) { use_access_group = FALSE; @@ -2968,35 +2712,35 @@ void LLPanelLandCovenant::refresh() LLViewerRegion* region = gParcelMgr->getSelectionRegion(); if(!region) return; - LLTextBox* region_name = (LLTextBox*)getChildByName("region_name_text"); + LLTextBox* region_name = getChild("region_name_text"); if (region_name) { region_name->setText(region->getName()); } - LLTextBox* resellable_clause = (LLTextBox*)getChildByName("resellable_clause"); + LLTextBox* resellable_clause = getChild("resellable_clause"); if (resellable_clause) { if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) { - resellable_clause->setText(childGetText("can_not_resell")); + resellable_clause->setText(getString("can_not_resell")); } else { - resellable_clause->setText(childGetText("can_resell")); + resellable_clause->setText(getString("can_resell")); } } - LLTextBox* changeable_clause = (LLTextBox*)getChildByName("changeable_clause"); + LLTextBox* changeable_clause = getChild("changeable_clause"); if (changeable_clause) { if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) { - changeable_clause->setText(childGetText("can_change")); + changeable_clause->setText(getString("can_change")); } else { - changeable_clause->setText(childGetText("can_not_change")); + changeable_clause->setText(getString("can_not_change")); } } @@ -3015,7 +2759,7 @@ void LLPanelLandCovenant::updateCovenantText(const std::string &string) LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant(); if (self) { - LLViewerTextEditor* editor = (LLViewerTextEditor*)self->getChildByName("covenant_editor"); + LLViewerTextEditor* editor = self->getChild("covenant_editor"); if (editor) { editor->setHandleEditKeysDirectly(TRUE); @@ -3030,7 +2774,7 @@ void LLPanelLandCovenant::updateEstateName(const std::string& name) LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant(); if (self) { - LLTextBox* editor = (LLTextBox*)self->getChildByName("estate_name_text"); + LLTextBox* editor = self->getChild("estate_name_text"); if (editor) editor->setText(name); } } @@ -3041,7 +2785,7 @@ void LLPanelLandCovenant::updateLastModified(const std::string& text) LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant(); if (self) { - LLTextBox* editor = (LLTextBox*)self->getChildByName("covenant_timestamp_text"); + LLTextBox* editor = self->getChild("covenant_timestamp_text"); if (editor) editor->setText(text); } } @@ -3052,7 +2796,7 @@ void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name) LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant(); if (self) { - LLTextBox* editor = (LLTextBox*)self->getChildByName("estate_owner_text"); + LLTextBox* editor = self->getChild("estate_owner_text"); if (editor) editor->setText(name); } } diff --git a/linden/indra/newview/llfloaterland.h b/linden/indra/newview/llfloaterland.h index 551c7e3..e9198cb 100644 --- a/linden/indra/newview/llfloaterland.h +++ b/linden/indra/newview/llfloaterland.h @@ -68,13 +68,10 @@ class LLPanelLandRenters; class LLPanelLandCovenant; class LLFloaterLand -: public LLFloater +: public LLFloater, public LLUISingleton > { + friend class LLUISingleton >; public: - // Call show() to open a land floater. - // Will query the viewer parcel manager to see what is selected. - static void show(); - static BOOL floaterVisible() { return sInstance && sInstance->getVisible(); } static void refreshAll(); static LLPanelLandObjects* getCurrentPanelLandObjects(); @@ -82,11 +79,14 @@ public: // Destroys itself on close. virtual void onClose(bool app_quitting); + virtual void onOpen(); + virtual BOOL postBuild(); protected: + // Does its own instance management, so clients not allowed // to allocate or destroy. - LLFloaterLand(); + LLFloaterLand(const LLSD& seed); virtual ~LLFloaterLand(); void refresh(); @@ -102,7 +102,6 @@ protected: protected: - static LLFloaterLand* sInstance; static LLParcelSelectionObserver* sObserver; static S32 sLastTab; @@ -114,7 +113,7 @@ protected: LLPanelLandAccess* mPanelAccess; LLPanelLandCovenant* mPanelCovenant; - LLHandle mParcel; + LLSafeHandle mParcel; public: // When closing the dialog, we want to deselect the land. But when @@ -129,7 +128,7 @@ class LLPanelLandGeneral : public LLPanel { public: - LLPanelLandGeneral(LLHandle& parcelp); + LLPanelLandGeneral(LLSafeHandle& parcelp); virtual ~LLPanelLandGeneral(); void refresh(); void refreshNames(); @@ -221,16 +220,16 @@ protected: LLButton* mBtnBuyPass; LLButton* mBtnStartAuction; - LLHandle& mParcel; + LLSafeHandle& mParcel; - static LLViewHandle sBuyPassDialogHandle; + static LLHandle sBuyPassDialogHandle; }; class LLPanelLandObjects : public LLPanel { public: - LLPanelLandObjects(LLHandle& parcelp); + LLPanelLandObjects(LLSafeHandle& parcelp); virtual ~LLPanelLandObjects(); void refresh(); virtual void draw(); @@ -293,7 +292,7 @@ protected: S32 mSelectedCount; BOOL mSelectedIsGroup; - LLHandle& mParcel; + LLSafeHandle& mParcel; }; @@ -301,7 +300,7 @@ class LLPanelLandOptions : public LLPanel { public: - LLPanelLandOptions(LLHandle& parcelp); + LLPanelLandOptions(LLSafeHandle& parcelp); virtual ~LLPanelLandOptions(); void refresh(); @@ -340,44 +339,15 @@ protected: LLCheckBoxCtrl *mPushRestrictionCtrl; LLButton *mPublishHelpButton; - LLHandle& mParcel; -}; - - -class LLPanelLandMedia -: public LLPanel -{ -public: - LLPanelLandMedia(LLHandle& parcelp); - virtual ~LLPanelLandMedia(); - void refresh(); - - static void onCommitAny(LLUICtrl* ctrl, void *userdata); - static void onClickStopMedia ( void* data ); - static void onClickStartMedia ( void* data ); - - virtual BOOL postBuild(); - -protected: - LLCheckBoxCtrl* mCheckSoundLocal; - LLRadioGroup* mRadioVoiceChat; - LLLineEditor* mMusicURLEdit; - LLLineEditor* mMediaURLEdit; - LLTextureCtrl* mMediaTextureCtrl; - LLCheckBoxCtrl* mMediaAutoScaleCheck; - //LLButton* mMediaStopButton; - //LLButton* mMediaStartButton; - - LLHandle& mParcel; + LLSafeHandle& mParcel; }; - class LLPanelLandAccess : public LLPanel { public: - LLPanelLandAccess(LLHandle& parcelp); + LLPanelLandAccess(LLSafeHandle& parcelp); virtual ~LLPanelLandAccess(); void refresh(); void refresh_ui(); @@ -399,7 +369,7 @@ protected: LLNameListCtrl* mListAccess; LLNameListCtrl* mListBanned; - LLHandle& mParcel; + LLSafeHandle& mParcel; }; @@ -407,7 +377,7 @@ class LLPanelLandCovenant : public LLPanel { public: - LLPanelLandCovenant(LLHandle& parcelp); + LLPanelLandCovenant(LLSafeHandle& parcelp); virtual ~LLPanelLandCovenant(); virtual BOOL postBuild(); void refresh(); @@ -417,7 +387,7 @@ public: static void updateEstateOwnerName(const std::string& name); protected: - LLHandle& mParcel; + LLSafeHandle& mParcel; }; #endif diff --git a/linden/indra/newview/llfloaterlandmark.h b/linden/indra/newview/llfloaterlandmark.h index 7d710de..027cf21 100644 --- a/linden/indra/newview/llfloaterlandmark.h +++ b/linden/indra/newview/llfloaterlandmark.h @@ -47,6 +47,7 @@ class LLFolderViewItem; class LLSearchEditor; class LLInventoryPanel; class LLSaveFolderState; +class LLViewerImage; // used for setting drag & drop callbacks. typedef BOOL (*drag_n_drop_callback)(LLUICtrl*, LLInventoryItem*, void*); @@ -55,7 +56,7 @@ typedef BOOL (*drag_n_drop_callback)(LLUICtrl*, LLInventoryItem*, void*); ////////////////////////////////////////////////////////////////////////////////////////// // LLFloaterLandmark -class LLFloaterLandmark: public LLFloater, public LLUISingleton +class LLFloaterLandmark: public LLFloater, public LLFloaterSingleton { public: LLFloaterLandmark(const LLSD& data); diff --git a/linden/indra/newview/llfloatermap.cpp b/linden/indra/newview/llfloatermap.cpp index b60515d..232055a 100644 --- a/linden/indra/newview/llfloatermap.cpp +++ b/linden/indra/newview/llfloatermap.cpp @@ -118,7 +118,7 @@ LLFloaterMap *gFloaterMap = NULL; LLFloaterMap::LLFloaterMap(const std::string& name) : LLFloater(name, - "FloaterMapRect", + "FloaterMiniMapRect", MAP_TITLE, TRUE, FLOATERMAP_MIN_WIDTH, @@ -128,7 +128,7 @@ LLFloaterMap::LLFloaterMap(const std::string& name) TRUE) // close button { const S32 LEFT = LLPANEL_BORDER_WIDTH; - const S32 TOP = mRect.getHeight(); + const S32 TOP = getRect().getHeight(); S32 y = 0; @@ -136,7 +136,7 @@ LLFloaterMap::LLFloaterMap(const std::string& name) LLRect map_rect( LEFT, TOP - LLPANEL_BORDER_WIDTH, - mRect.getWidth() - LLPANEL_BORDER_WIDTH, + getRect().getWidth() - LLPANEL_BORDER_WIDTH, y ); LLColor4 bg_color = gColors.getColor( "NetMapBackgroundColor" ); mMap = new LLNetMap("Net Map", map_rect, bg_color); @@ -144,8 +144,7 @@ LLFloaterMap::LLFloaterMap(const std::string& name) addChildAtEnd(mMap); // Get the drag handle all the way in back - removeChild(mDragHandle); - addChildAtEnd(mDragHandle); + sendChildToBack(getDragHandle()); setIsChrome(TRUE); } @@ -191,14 +190,14 @@ void LLFloaterMap::draw() if( gAgent.cameraMouselook()) { setMouseOpaque(FALSE); - mDragHandle->setMouseOpaque(FALSE); + getDragHandle()->setMouseOpaque(FALSE); drawChild(mMap); } else { setMouseOpaque(TRUE); - mDragHandle->setMouseOpaque(TRUE); + getDragHandle()->setMouseOpaque(TRUE); LLFloater::draw(); } diff --git a/linden/indra/newview/llfloatermute.h b/linden/indra/newview/llfloatermute.h index 4d2608a..801392e 100644 --- a/linden/indra/newview/llfloatermute.h +++ b/linden/indra/newview/llfloatermute.h @@ -42,7 +42,7 @@ class LLUUID; class LLScrollListCtrl; class LLFloaterMute -: public LLFloater, public LLUISingleton + : public LLFloater, public LLFloaterSingleton { public: LLFloaterMute(const LLSD& seed); diff --git a/linden/indra/newview/llfloaternamedesc.cpp b/linden/indra/newview/llfloaternamedesc.cpp index 4c0cefa..f49c951 100644 --- a/linden/indra/newview/llfloaternamedesc.cpp +++ b/linden/indra/newview/llfloaternamedesc.cpp @@ -106,10 +106,10 @@ BOOL LLFloaterNameDesc::postBuild() setTitle(mFilename); - centerWindow(); + centerWithin(gViewerWindow->getRootView()->getRect()); - S32 line_width = mRect.getWidth() - 2 * PREVIEW_HPAD; - S32 y = mRect.getHeight() - PREVIEW_LINE_HEIGHT; + S32 line_width = getRect().getWidth() - 2 * PREVIEW_HPAD; + S32 y = getRect().getHeight() - PREVIEW_LINE_HEIGHT; r.setLeftTopAndSize( PREVIEW_HPAD, y, line_width, PREVIEW_LINE_HEIGHT ); y -= PREVIEW_LINE_HEIGHT; @@ -158,19 +158,6 @@ LLFloaterNameDesc::~LLFloaterNameDesc() gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() } -//----------------------------------------------------------------------------- -// centerWindow() -//----------------------------------------------------------------------------- -void LLFloaterNameDesc::centerWindow() -{ - LLRect window_rect = gViewerWindow->getRootView()->getRect(); - - S32 dialog_left = window_rect.mLeft + (window_rect.getWidth() - mRect.getWidth()) / 2; - S32 dialog_bottom = window_rect.mBottom + (window_rect.getHeight() - mRect.getHeight()) / 2; - - translate( dialog_left - mRect.mLeft, dialog_bottom - mRect.mBottom ); -} - // Sub-classes should override this function if they allow editing //----------------------------------------------------------------------------- // onCommit() diff --git a/linden/indra/newview/llfloaternamedesc.h b/linden/indra/newview/llfloaternamedesc.h index 9fee4bf..ac9c894 100644 --- a/linden/indra/newview/llfloaternamedesc.h +++ b/linden/indra/newview/llfloaternamedesc.h @@ -50,7 +50,6 @@ public: static void doCommit(class LLUICtrl *, void* userdata); protected: virtual void onCommit(); - virtual void centerWindow(); protected: BOOL mIsAudio; diff --git a/linden/indra/newview/llfloaternewim.cpp b/linden/indra/newview/llfloaternewim.cpp index c4af6a7..6363b4e 100644 --- a/linden/indra/newview/llfloaternewim.cpp +++ b/linden/indra/newview/llfloaternewim.cpp @@ -68,8 +68,6 @@ BOOL LLFloaterNewIM::postBuild() requires("start_btn", WIDGET_TYPE_BUTTON); requires("close_btn", WIDGET_TYPE_BUTTON); requires("user_list", WIDGET_TYPE_NAME_LIST); - requires("online_descriptor", WIDGET_TYPE_TEXT_BOX); - requires("name_format", WIDGET_TYPE_TEXT_BOX); if (checkRequirements()) { @@ -85,8 +83,8 @@ BOOL LLFloaterNewIM::postBuild() { llwarns << "LLViewerUICtrlFactory::getNameListByName() returned NULL for 'user_list'" << llendl; } - sOnlineDescriptor = childGetValue("online_descriptor").asString(); - sNameFormat = childGetValue("name_format").asString(); + sOnlineDescriptor = getString("online_descriptor"); + sNameFormat = getString("name_format"); setDefaultBtn("start_btn"); return TRUE; } @@ -152,10 +150,7 @@ void LLFloaterNewIM::addGroup(const LLUUID& uuid, void* data, BOOL bold, BOOL on void LLFloaterNewIM::addAgent(const LLUUID& uuid, void* data, BOOL online) { - char first[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - first[0] = '\0'; - char last[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - last[0] = '\0'; + std::string first, last; gCacheName->getName(uuid, first, last); LLUIString fullname = sNameFormat; fullname.setArg("[FIRST]", first); @@ -232,7 +227,7 @@ void LLFloaterNewIM::onClickClose(void *userdata) BOOL LLFloaterNewIM::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) { BOOL handled = LLFloater::handleKeyHere(key, mask, called_from_parent); - if (getVisible() && mEnabled && !called_from_parent) + if (getVisible() && getEnabled() && !called_from_parent) { if ( KEY_ESCAPE == key ) { diff --git a/linden/indra/newview/llfloateropenobject.h b/linden/indra/newview/llfloateropenobject.h index e32f2f4..b431f2c 100644 --- a/linden/indra/newview/llfloateropenobject.h +++ b/linden/indra/newview/llfloateropenobject.h @@ -73,7 +73,7 @@ protected: static LLFloaterOpenObject* sInstance; LLPanelInventory* mPanelInventory; - LLHandle mObjectSelection; + LLSafeHandle mObjectSelection; BOOL mDirty; }; diff --git a/linden/indra/newview/llfloaterpermissionsmgr.cpp b/linden/indra/newview/llfloaterpermissionsmgr.cpp index 6447d72..9cc223e 100644 --- a/linden/indra/newview/llfloaterpermissionsmgr.cpp +++ b/linden/indra/newview/llfloaterpermissionsmgr.cpp @@ -75,9 +75,9 @@ void LLFloaterPermissionsMgr::processPermissionsList(LLMessageSystem* msg, void* LLFloaterPermissionsMgr::LLFloaterPermissionsMgr() : LLFloater("floater_perm_mgr", "PermissionsManagerRect", "Permissions Manager", TRUE, MIN_PERM_MGR_WIDTH, MIN_PERM_MGR_HEIGHT) { - S32 y = mRect.getHeight() - VPAD - LINE; - LLRect scrollable_container_rect(0, y, mRect.getWidth(), 0); - LLRect permissions_rect(0, 0, mRect.getWidth() - HPAD - HPAD, 0); + S32 y = getRect().getHeight() - VPAD - LINE; + LLRect scrollable_container_rect(0, y, getRect().getWidth(), 0); + LLRect permissions_rect(0, 0, getRect().getWidth() - HPAD - HPAD, 0); mPermissions = new LLPermissionsView(permissions_rect); mScroller = new LLScrollableContainerView( "permissions container", @@ -124,9 +124,9 @@ void LLPermissionsView::addPermissionsData(const LLString& object_name, const LL // grow to make room for new element LLPermissionsData* perm_datap = new LLPermissionsData(object_id, permissions_flags); - reshape(mRect.getWidth(), mRect.getHeight() + LINE + VPAD + BTN_HEIGHT + VPAD); - S32 y = mRect.getHeight() - LINE - VPAD; - LLRect label_rect(HPAD, y + LINE, mRect.getWidth(), y); + reshape(getRect().getWidth(), getRect().getHeight() + LINE + VPAD + BTN_HEIGHT + VPAD); + S32 y = getRect().getHeight() - LINE - VPAD; + LLRect label_rect(HPAD, y + LINE, getRect().getWidth(), y); LLTextBox* text = new LLTextBox("perm_label", label_rect, object_name.c_str()); text->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM); addChild(text); diff --git a/linden/indra/newview/llfloaterpostcard.cpp b/linden/indra/newview/llfloaterpostcard.cpp index f866e49..47f59a6 100644 --- a/linden/indra/newview/llfloaterpostcard.cpp +++ b/linden/indra/newview/llfloaterpostcard.cpp @@ -67,7 +67,8 @@ /// Local function declarations, constants, enums, and typedefs ///---------------------------------------------------------------------------- -LLLinkedList LLFloaterPostcard::sInstances; +//static +LLFloaterPostcard::instance_list_t LLFloaterPostcard::sInstances; ///---------------------------------------------------------------------------- /// Class LLFloaterPostcard @@ -97,13 +98,13 @@ void LLFloaterPostcard::init() gAgent.sendReliableMessage(); } - sInstances.addData(this); + sInstances.insert(this); } // Destroys the object LLFloaterPostcard::~LLFloaterPostcard() { - sInstances.removeData(this); + sInstances.erase(this); mJPEGImage = NULL; // deletes image } @@ -113,25 +114,12 @@ BOOL LLFloaterPostcard::postBuild() childSetAction("send_btn", onClickSend, this); childDisable("from_form"); - childSetAction("publish_help_btn", onClickPublishHelp, this); - if (gAgent.isTeen()) - { - // Disable these buttons if they are PG (Teen) users - childDisable("allow_publish_check"); - childHide("allow_publish_check"); - childDisable("publish_help_btn"); - childHide("publish_help_btn"); - childDisable("mature_check"); - childHide("mature_check"); - } - - LLString name_string; + std::string name_string; gAgent.buildFullname(name_string); - childSetValue("name_form", LLSD(name_string)); - LLTextEditor *MsgField = LLUICtrlFactory::getTextEditorByName(this, "msg_form"); + LLTextEditor* MsgField = LLUICtrlFactory::getTextEditorByName(this, "msg_form"); if (MsgField) { MsgField->setWordWrap(TRUE); @@ -170,9 +158,9 @@ void LLFloaterPostcard::draw() LLGLSUIDefault gls_ui; LLFloater::draw(); - if(getVisible() && !mMinimized && mViewerImage.notNull() && mJPEGImage.notNull()) + if(getVisible() && !isMinimized() && mViewerImage.notNull() && mJPEGImage.notNull()) { - LLRect rect(mRect); + LLRect rect(getRect()); // first set the max extents of our preview rect.translate(-rect.mLeft, -rect.mBottom); @@ -252,8 +240,8 @@ void LLFloaterPostcard::onClickSend(void* data) { LLFloaterPostcard *self = (LLFloaterPostcard *)data; - LLString from(self->childGetValue("from_form").asString().c_str()); - LLString to(self->childGetValue("to_form").asString().c_str()); + std::string from(self->childGetValue("from_form").asString()); + std::string to(self->childGetValue("to_form").asString()); if (to.empty() || to.find('@') == std::string::npos) { @@ -267,7 +255,7 @@ void LLFloaterPostcard::onClickSend(void* data) return; } - LLString subject(self->childGetValue("subject_form").asString().c_str()); + std::string subject(self->childGetValue("subject_form").asString()); if(subject.empty() || !self->mHasFirstMsgFocus) { gViewerWindow->alertXml("PromptMissingSubjMsg", missingSubjMsgAlertCallback, self); @@ -286,12 +274,6 @@ void LLFloaterPostcard::onClickSend(void* data) } // static -void LLFloaterPostcard::onClickPublishHelp(void* data) -{ - gViewerWindow->alertXml("ClickPublishHelpPostcard"); -} - -// static void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data, S32 result, LLExtStat ext_status) // StoreAssetData callback (fixed) { LLFloaterPostcard *self = (LLFloaterPostcard *)user_data; @@ -321,8 +303,8 @@ void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data, msg->addString("Name", self->childGetValue("name_form").asString()); msg->addString("Subject", self->childGetValue("subject_form").asString()); msg->addString("Msg", self->childGetValue("msg_form").asString()); - msg->addBOOL("AllowPublish", self->childGetValue("allow_publish_check").asBoolean()); - msg->addBOOL("MaturePublish", self->childGetValue("mature_check").asBoolean()); + msg->addBOOL("AllowPublish", FALSE); + msg->addBOOL("MaturePublish", FALSE); gAgent.sendReliableMessage(); } @@ -332,11 +314,10 @@ void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data, // static void LLFloaterPostcard::updateUserInfo(const char *email) { - LLFloaterPostcard *instance; - - sInstances.resetList(); - while ((instance = sInstances.getNextData())) + for (instance_list_t::iterator iter = sInstances.begin(); + iter != sInstances.end(); ++iter) { + LLFloaterPostcard *instance = *iter; const LLString& text = instance->childGetValue("from_form").asString(); if (text.empty()) { @@ -371,14 +352,14 @@ void LLFloaterPostcard::missingSubjMsgAlertCallback(S32 option, void* data) if((self->childGetValue("subject_form").asString()).empty()) { // Stuff the subject back into the form. - self->childSetValue("subject_form", self->childGetText("default_subject")); + self->childSetValue("subject_form", self->getString("default_subject")); } if(!self->mHasFirstMsgFocus) { // The user never switched focus to the messagee window. // Using the default string. - self->childSetValue("msg_form", self->childGetText("default_message")); + self->childSetValue("msg_form", self->getString("default_message")); } self->sendPostcard(); @@ -405,8 +386,6 @@ void LLFloaterPostcard::sendPostcard() body["name"] = childGetValue("name_form").asString(); body["subject"] = childGetValue("subject_form").asString(); body["msg"] = childGetValue("msg_form").asString(); - body["allow-publish"] = childGetValue("allow_publish_check").asBoolean(); - body["mature-publish"] = childGetValue("mature_check").asBoolean(); LLHTTPClient::post(url, body, new LLSendPostcardResponder(body, mAssetID, LLAssetType::AT_IMAGE_JPEG)); } else diff --git a/linden/indra/newview/llfloaterpostcard.h b/linden/indra/newview/llfloaterpostcard.h index e04d45f..be7c2b2 100644 --- a/linden/indra/newview/llfloaterpostcard.h +++ b/linden/indra/newview/llfloaterpostcard.h @@ -57,7 +57,6 @@ public: static void onClickCancel(void* data); static void onClickSend(void* data); - static void onClickPublishHelp(void *data); static void uploadCallback(const LLUUID& asset_id, void *user_data, @@ -79,8 +78,9 @@ protected: LLVector2 mImageScale; LLVector3d mPosTakenGlobal; boolean mHasFirstMsgFocus; - - static LLLinkedList sInstances; + + typedef std::set instance_list_t; + static instance_list_t sInstances; }; diff --git a/linden/indra/newview/llfloaterpostprocess.cpp b/linden/indra/newview/llfloaterpostprocess.cpp new file mode 100644 index 0000000..999ad5d --- /dev/null +++ b/linden/indra/newview/llfloaterpostprocess.cpp @@ -0,0 +1,273 @@ +/** + * @file llfloaterpostprocess.cpp + * @brief LLFloaterPostProcess class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterpostprocess.h" + +#include "llsliderctrl.h" +#include "llcheckboxctrl.h" +#include "llvieweruictrlfactory.h" +#include "llviewerdisplay.h" +#include "llpostprocess.h" +#include "llcombobox.h" +#include "lllineeditor.h" +#include "llviewerwindow.h" + + +LLFloaterPostProcess* LLFloaterPostProcess::sPostProcess = NULL; + + +LLFloaterPostProcess::LLFloaterPostProcess() : LLFloater("Post-Process Floater") +{ + gUICtrlFactory->buildFloater(this, "floater_post_process.xml"); + + /// Color Filter Callbacks + childSetCommitCallback("ColorFilterToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_color_filter"); + //childSetCommitCallback("ColorFilterGamma", &LLFloaterPostProcess::onFloatControlMoved, &(gPostProcess->tweaks.gamma())); + childSetCommitCallback("ColorFilterBrightness", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness"); + childSetCommitCallback("ColorFilterSaturation", &LLFloaterPostProcess::onFloatControlMoved, (char*)"saturation"); + childSetCommitCallback("ColorFilterContrast", &LLFloaterPostProcess::onFloatControlMoved, (char*)"contrast"); + + childSetCommitCallback("ColorFilterBaseR", &LLFloaterPostProcess::onColorControlRMoved, (char*)"contrast_base"); + childSetCommitCallback("ColorFilterBaseG", &LLFloaterPostProcess::onColorControlGMoved, (char*)"contrast_base"); + childSetCommitCallback("ColorFilterBaseB", &LLFloaterPostProcess::onColorControlBMoved, (char*)"contrast_base"); + childSetCommitCallback("ColorFilterBaseI", &LLFloaterPostProcess::onColorControlIMoved, (char*)"contrast_base"); + + /// Night Vision Callbacks + childSetCommitCallback("NightVisionToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_night_vision"); + childSetCommitCallback("NightVisionBrightMult", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness_multiplier"); + childSetCommitCallback("NightVisionNoiseSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_size"); + childSetCommitCallback("NightVisionNoiseStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_strength"); + + /// Bloom Callbacks + childSetCommitCallback("BloomToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_bloom"); + childSetCommitCallback("BloomExtract", &LLFloaterPostProcess::onFloatControlMoved, (char*)"extract_low"); + childSetCommitCallback("BloomSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_width"); + childSetCommitCallback("BloomStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_strength"); + + // Effect loading and saving. + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(this, "PPEffectsCombo"); + childSetAction("PPLoadEffect", &LLFloaterPostProcess::onLoadEffect, comboBox); + comboBox->setCommitCallback(onChangeEffectName); + + LLLineEditor* editBox = LLUICtrlFactory::getLineEditorByName(this, "PPEffectNameEditor"); + childSetAction("PPSaveEffect", &LLFloaterPostProcess::onSaveEffect, editBox); + + syncMenu(); + +} + +LLFloaterPostProcess::~LLFloaterPostProcess() +{ + + +} + +LLFloaterPostProcess* LLFloaterPostProcess::instance() +{ + // if we don't have our singleton instance, create it + if (!sPostProcess) + { + sPostProcess = new LLFloaterPostProcess(); + sPostProcess->open(); + sPostProcess->setFocus(TRUE); + } + return sPostProcess; +} + +// Bool Toggle +void LLFloaterPostProcess::onBoolToggle(LLUICtrl* ctrl, void* userData) +{ + char const * boolVariableName = (char const *)userData; + + // check the bool + LLCheckBoxCtrl* cbCtrl = static_cast(ctrl); + gPostProcess->tweaks[boolVariableName] = cbCtrl->getValue(); +} + +// Float Moved +void LLFloaterPostProcess::onFloatControlMoved(LLUICtrl* ctrl, void* userData) +{ + char const * floatVariableName = (char const *)userData; + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + gPostProcess->tweaks[floatVariableName] = sldrCtrl->getValue(); +} + +// Color Moved +void LLFloaterPostProcess::onColorControlRMoved(LLUICtrl* ctrl, void* userData) +{ + char const * floatVariableName = (char const *)userData; + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + gPostProcess->tweaks[floatVariableName][0] = sldrCtrl->getValue(); +} + +// Color Moved +void LLFloaterPostProcess::onColorControlGMoved(LLUICtrl* ctrl, void* userData) +{ + char const * floatVariableName = (char const *)userData; + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + gPostProcess->tweaks[floatVariableName][1] = sldrCtrl->getValue(); +} + +// Color Moved +void LLFloaterPostProcess::onColorControlBMoved(LLUICtrl* ctrl, void* userData) +{ + char const * floatVariableName = (char const *)userData; + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + gPostProcess->tweaks[floatVariableName][2] = sldrCtrl->getValue(); +} + +// Color Moved +void LLFloaterPostProcess::onColorControlIMoved(LLUICtrl* ctrl, void* userData) +{ + char const * floatVariableName = (char const *)userData; + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + gPostProcess->tweaks[floatVariableName][3] = sldrCtrl->getValue(); +} + +void LLFloaterPostProcess::onLoadEffect(void* userData) +{ + LLComboBox* comboBox = static_cast(userData); + + LLSD::String effectName(comboBox->getSelectedValue().asString()); + + gPostProcess->setSelectedEffect(effectName); + + sPostProcess->syncMenu(); +} + +void LLFloaterPostProcess::onSaveEffect(void* userData) +{ + LLLineEditor* editBox = static_cast(userData); + + LLSD::String effectName(editBox->getValue().asString()); + + if (gPostProcess->mAllEffects.has(effectName)) + { + gViewerWindow->alertXml("PPSaveEffectAlert", &LLFloaterPostProcess::saveAlertCallback, userData); + } + else + { + gPostProcess->saveEffect(effectName); + sPostProcess->syncMenu(); + } +} + +void LLFloaterPostProcess::onChangeEffectName(LLUICtrl* ctrl, void * userData) +{ + // get the combo box and name + LLComboBox * comboBox = static_cast(ctrl); + LLLineEditor* editBox = LLUICtrlFactory::getLineEditorByName(sPostProcess, + "PPEffectNameEditor"); + + // set the parameter's new name + editBox->setValue(comboBox->getSelectedValue()); +} + +void LLFloaterPostProcess::saveAlertCallback(S32 option, void* userData) +{ + LLLineEditor* editBox = static_cast(userData); + + // if they choose save, do it. Otherwise, don't do anything + if (option == 0) + { + LLSD::String effectName(editBox->getValue().asString()); + + gPostProcess->saveEffect(effectName); + + sPostProcess->syncMenu(); + } + +} + +void LLFloaterPostProcess::show() +{ + // get the instance, make sure the values are synced + // and open the menu + LLFloaterPostProcess* postProcess = instance(); + postProcess->syncMenu(); + postProcess->open(); +} + +// virtual +void LLFloaterPostProcess::onClose(bool app_quitting) +{ + // just set visibility to false, don't get fancy yet + if (sPostProcess) + { + sPostProcess->setVisible(FALSE); + } +} + +void LLFloaterPostProcess::syncMenu() +{ + // add the combo boxe contents + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(this, "PPEffectsCombo"); + + if(comboBox != NULL) { + comboBox->removeall(); + + LLSD::map_const_iterator currEffect; + for(currEffect = gPostProcess->mAllEffects.beginMap(); + currEffect != gPostProcess->mAllEffects.endMap(); + ++currEffect) + { + comboBox->add(currEffect->first); + } + + // set the current effect as selected. + comboBox->selectByValue(gPostProcess->getSelectedEffect()); + } + + /// Sync Color Filter Menu + childSetValue("ColorFilterToggle", gPostProcess->tweaks.useColorFilter()); + //childSetValue("ColorFilterGamma", gPostProcess->tweaks.gamma()); + childSetValue("ColorFilterBrightness", gPostProcess->tweaks.brightness()); + childSetValue("ColorFilterSaturation", gPostProcess->tweaks.saturation()); + childSetValue("ColorFilterContrast", gPostProcess->tweaks.contrast()); + childSetValue("ColorFilterBaseR", gPostProcess->tweaks.contrastBaseR()); + childSetValue("ColorFilterBaseG", gPostProcess->tweaks.contrastBaseG()); + childSetValue("ColorFilterBaseB", gPostProcess->tweaks.contrastBaseB()); + childSetValue("ColorFilterBaseI", gPostProcess->tweaks.contrastBaseIntensity()); + + /// Sync Night Vision Menu + childSetValue("NightVisionToggle", gPostProcess->tweaks.useNightVisionShader()); + childSetValue("NightVisionBrightMult", gPostProcess->tweaks.brightMult()); + childSetValue("NightVisionNoiseSize", gPostProcess->tweaks.noiseSize()); + childSetValue("NightVisionNoiseStrength", gPostProcess->tweaks.noiseStrength()); + + /// Sync Bloom Menu + childSetValue("BloomToggle", LLSD(gPostProcess->tweaks.useBloomShader())); + childSetValue("BloomExtract", gPostProcess->tweaks.extractLow()); + childSetValue("BloomSize", gPostProcess->tweaks.bloomWidth()); + childSetValue("BloomStrength", gPostProcess->tweaks.bloomStrength()); +} diff --git a/linden/indra/newview/llfloaterpostprocess.h b/linden/indra/newview/llfloaterpostprocess.h new file mode 100644 index 0000000..03de20f --- /dev/null +++ b/linden/indra/newview/llfloaterpostprocess.h @@ -0,0 +1,90 @@ +/** + * @file llfloaterpostprocess.h + * @brief LLFloaterPostProcess class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERPOSTPROCESS_H +#define LL_LLFLOATERPOSTPROCESS_H + +#include "llfloater.h" + +class LLButton; +class LLSliderCtrl; +class LLTabContainer; +class LLPanelPermissions; +class LLPanelObject; +class LLPanelVolume; +class LLPanelContents; +class LLPanelFace; + +/** + * Menu for adjusting the post process settings of the world + */ +class LLFloaterPostProcess : public LLFloater +{ +public: + + LLFloaterPostProcess(); + virtual ~LLFloaterPostProcess(); + + /// one and one instance only + static LLFloaterPostProcess* instance(); + + /// post process callbacks + static void onBoolToggle(LLUICtrl* ctrl, void* userData); + static void onFloatControlMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlRMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlGMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlBMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlIMoved(LLUICtrl* ctrl, void* userData); + static void onLoadEffect(void* userData); + static void onSaveEffect(void* userData); + static void onChangeEffectName(LLUICtrl* ctrl, void * userData); + + /// prompts a user when overwriting an effect + static void saveAlertCallback(S32 option, void* userData); + + /// show off our menu + static void show(); + + /// stuff to do on exit + virtual void onClose(bool app_quitting); + + /// sync up sliders + void syncMenu(); + +/* + void refresh(); +*/ +public: + + static LLFloaterPostProcess* sPostProcess; +}; + +#endif diff --git a/linden/indra/newview/llfloaterpreference.cpp b/linden/indra/newview/llfloaterpreference.cpp index 09398fd..ff57b5c 100644 --- a/linden/indra/newview/llfloaterpreference.cpp +++ b/linden/indra/newview/llfloaterpreference.cpp @@ -73,6 +73,7 @@ #include "llviewerwindow.h" #include "llkeyboard.h" #include "llscrollcontainer.h" +#include "llfloaterhardwaresettings.h" #if LL_WINDOWS // for Logitech LCD keyboards / speakers @@ -127,13 +128,12 @@ S32 pref_min_height() } -LLPreferenceCore::LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton * default_btn) : +LLPreferenceCore::LLPreferenceCore(LLTabContainer* tab_container, LLButton * default_btn) : mTabContainer(tab_container), mGeneralPanel(NULL), mInputPanel(NULL), mNetworkPanel(NULL), mDisplayPanel(NULL), - mDisplayPanel2(NULL), mAudioPanel(NULL), mMsgPanel(NULL), mLCDPanel(NULL) @@ -150,24 +150,14 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton mTabContainer->addTabPanel(mNetworkPanel, mNetworkPanel->getLabel(), FALSE, onTabChanged, mTabContainer); mNetworkPanel->setDefaultBtn(default_btn); - #if LL_LIBXUL_ENABLED mWebPanel = new LLPanelWeb(); mTabContainer->addTabPanel(mWebPanel, mWebPanel->getLabel(), FALSE, onTabChanged, mTabContainer); mWebPanel->setDefaultBtn(default_btn); - #endif mDisplayPanel = new LLPanelDisplay(); mTabContainer->addTabPanel(mDisplayPanel, mDisplayPanel->getLabel(), FALSE, onTabChanged, mTabContainer); mDisplayPanel->setDefaultBtn(default_btn); - mDisplayPanel3 = new LLPanelDisplay3(); - mTabContainer->addTabPanel(mDisplayPanel3, mDisplayPanel3->getLabel(), FALSE, onTabChanged, mTabContainer); - mDisplayPanel3->setDefaultBtn(default_btn); - - mDisplayPanel2 = new LLPanelDisplay2(); - mTabContainer->addTabPanel(mDisplayPanel2, mDisplayPanel2->getLabel(), FALSE, onTabChanged, mTabContainer); - mDisplayPanel2->setDefaultBtn(default_btn); - mAudioPanel = new LLPanelAudioPrefs(); mTabContainer->addTabPanel(mAudioPanel, mAudioPanel->getLabel(), FALSE, onTabChanged, mTabContainer); mAudioPanel->setDefaultBtn(default_btn); @@ -227,16 +217,7 @@ LLPreferenceCore::~LLPreferenceCore() delete mDisplayPanel; mDisplayPanel = NULL; } - if (mDisplayPanel2) - { - delete mDisplayPanel2; - mDisplayPanel2 = NULL; - } - if (mDisplayPanel3) - { - delete mDisplayPanel3; - mDisplayPanel3 = NULL; - } + if (mAudioPanel) { delete mAudioPanel; @@ -257,13 +238,11 @@ LLPreferenceCore::~LLPreferenceCore() delete mMsgPanel; mMsgPanel = NULL; } - #if LL_LIBXUL_ENABLED if (mWebPanel) { delete mWebPanel; mWebPanel = NULL; } - #endif } @@ -273,15 +252,15 @@ void LLPreferenceCore::apply() mInputPanel->apply(); mNetworkPanel->apply(); mDisplayPanel->apply(); - mDisplayPanel2->apply(); - mDisplayPanel3->apply(); mPrefsChat->apply(); mPrefsVoice->apply(); mPrefsIM->apply(); mMsgPanel->apply(); - #if LL_LIBXUL_ENABLED + + // hardware menu apply + LLFloaterHardwareSettings::instance()->apply(); + mWebPanel->apply(); - #endif #if LL_WINDOWS && LL_LCD_COMPILE // only add this option if we actually have a logitech keyboard / speaker set if (gLcdScreen->Enabled()) @@ -299,16 +278,16 @@ void LLPreferenceCore::cancel() mInputPanel->cancel(); mNetworkPanel->cancel(); mDisplayPanel->cancel(); - mDisplayPanel2->cancel(); - mDisplayPanel3->cancel(); mAudioPanel->cancel(); mPrefsChat->cancel(); mPrefsVoice->cancel(); mPrefsIM->cancel(); mMsgPanel->cancel(); - #if LL_LIBXUL_ENABLED + + // cancel hardware menu + LLFloaterHardwareSettings::instance()->cancel(); + mWebPanel->cancel(); - #endif #if LL_WINDOWS && LL_LCD_COMPILE // only add this option if we actually have a logitech keyboard / speaker set if (gLcdScreen->Enabled()) @@ -322,7 +301,7 @@ void LLPreferenceCore::cancel() // static void LLPreferenceCore::onTabChanged(void* user_data, bool from_click) { - LLTabContainerCommon* self = (LLTabContainerCommon*)user_data; + LLTabContainer* self = (LLTabContainer*)user_data; gSavedSettings.setS32("LastPrefTab", self->getCurrentPanelIndex()); } @@ -336,6 +315,12 @@ void LLPreferenceCore::setPersonalInfo( mPrefsIM->setPersonalInfo(visibility, im_via_email, email); } +void LLPreferenceCore::refreshEnabledGraphics() +{ + LLFloaterHardwareSettings::instance()->refreshEnabledState(); + mDisplayPanel->refreshEnabledState(); +} + ////////////////////////////////////////////// // LLFloaterPreference @@ -371,7 +356,7 @@ BOOL LLFloaterPreference::postBuild() mPreferenceCore = new LLPreferenceCore( LLUICtrlFactory::getTabContainerByName(this, "pref core"), - static_cast(getChildByName("OK")) + getChild("OK") ); sInstance = this; @@ -529,3 +514,8 @@ void LLFloaterPreference::updateUserInfo( visibility, im_via_email, email); } } + +void LLFloaterPreference::refreshEnabledGraphics() +{ + sInstance->mPreferenceCore->refreshEnabledGraphics(); +} diff --git a/linden/indra/newview/llfloaterpreference.h b/linden/indra/newview/llfloaterpreference.h index bf16d0d..ad4b3b8 100644 --- a/linden/indra/newview/llfloaterpreference.h +++ b/linden/indra/newview/llfloaterpreference.h @@ -45,8 +45,6 @@ class LLPanelGeneral; class LLPanelInput; class LLPanelLCD; class LLPanelDisplay; -class LLPanelDisplay2; -class LLPanelDisplay3; class LLPanelAudioPrefs; class LLPanelDebug; class LLPanelNetwork; @@ -62,13 +60,13 @@ class LLPreferenceCore { public: - LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton * default_btn); + LLPreferenceCore(LLTabContainer* tab_container, LLButton * default_btn); ~LLPreferenceCore(); void apply(); void cancel(); - LLTabContainerCommon* getTabContainer() { return mTabContainer; } + LLTabContainer* getTabContainer() { return mTabContainer; } void setPersonalInfo( const char* visibility, @@ -76,15 +74,16 @@ public: const char* email); static void onTabChanged(void* user_data, bool from_click); + + // refresh all the graphics preferences menus + void refreshEnabledGraphics(); private: - LLTabContainerCommon *mTabContainer; + LLTabContainer *mTabContainer; LLPanelGeneral *mGeneralPanel; LLPanelInput *mInputPanel; LLPanelNetwork *mNetworkPanel; LLPanelDisplay *mDisplayPanel; - LLPanelDisplay2 *mDisplayPanel2; - LLPanelDisplay3 *mDisplayPanel3; LLPanelAudioPrefs *mAudioPanel; // LLPanelDebug *mDebugPanel; LLPrefsChat *mPrefsChat; @@ -113,6 +112,9 @@ public: BOOL im_via_email, const char* email); + // refresh all the graphics preferences menus + static void refreshEnabledGraphics(); + protected: LLPreferenceCore *mPreferenceCore; diff --git a/linden/indra/newview/llfloaterproperties.cpp b/linden/indra/newview/llfloaterproperties.cpp index 36f6051..3519520 100644 --- a/linden/indra/newview/llfloaterproperties.cpp +++ b/linden/indra/newview/llfloaterproperties.cpp @@ -303,18 +303,13 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) ////////////////// // CREATOR NAME // ////////////////// - char first_name[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - char last_name[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ if(!gCacheName) return; if(!gAgent.getRegion()) return; if (item->getCreatorUUID().notNull()) { - gCacheName->getName(item->getCreatorUUID(), first_name, last_name); - LLString name(first_name); - name.append(1, ' '); - name.append(last_name); - + std::string name; + gCacheName->getFullName(item->getCreatorUUID(), name); childSetEnabled("BtnCreator",TRUE); childSetEnabled("LabelCreatorTitle",TRUE); childSetEnabled("LabelCreatorName",TRUE); @@ -325,7 +320,7 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) childSetEnabled("BtnCreator",FALSE); childSetEnabled("LabelCreatorTitle",FALSE); childSetEnabled("LabelCreatorName",FALSE); - childSetText("LabelCreatorName",childGetText("unknown")); + childSetText("LabelCreatorName",getString("unknown")); } //////////////// @@ -336,16 +331,11 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) LLString name; if (perm.isGroupOwned()) { - char group_name[DB_GROUP_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - gCacheName->getGroupName(perm.getGroup(), group_name); - name.assign(group_name); + gCacheName->getGroupName(perm.getGroup(), name); } else { - gCacheName->getName(perm.getOwner(), first_name, last_name); - name.assign(first_name); - name.append(1, ' '); - name.append(last_name); + gCacheName->getFullName(perm.getOwner(), name); } childSetEnabled("BtnOwner",TRUE); childSetEnabled("LabelOwnerTitle",TRUE); @@ -357,7 +347,7 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) childSetEnabled("BtnOwner",FALSE); childSetEnabled("LabelOwnerTitle",FALSE); childSetEnabled("LabelOwnerName",FALSE); - childSetText("LabelOwnerName",childGetText("public")); + childSetText("LabelOwnerName",getString("public")); } ////////////////// @@ -368,7 +358,7 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) time_t time_utc = (time_t)item->getCreationDate(); if (0 == time_utc) { - childSetText("LabelAcquiredDate",childGetText("unknown")); + childSetText("LabelAcquiredDate",getString("unknown")); } else { @@ -380,11 +370,11 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) /////////////////////// if(can_agent_manipulate) { - childSetText("OwnerLabel",childGetText("you_can")); + childSetText("OwnerLabel",getString("you_can")); } else { - childSetText("OwnerLabel",childGetText("owner_can")); + childSetText("OwnerLabel",getString("owner_can")); } U32 base_mask = perm.getMaskBase(); diff --git a/linden/indra/newview/llfloaterregioninfo.cpp b/linden/indra/newview/llfloaterregioninfo.cpp index 2f01844..8043fe0 100644 --- a/linden/indra/newview/llfloaterregioninfo.cpp +++ b/linden/indra/newview/llfloaterregioninfo.cpp @@ -52,10 +52,12 @@ #include "llcheckboxctrl.h" #include "llcombobox.h" #include "llfilepicker.h" +#include "llfloaterdaycycle.h" #include "llfloatergodtools.h" // for send_sim_wide_deletes() #include "llfloatertopobjects.h" // added to fix SL-32336 #include "llfloatergroups.h" #include "llfloatertelehub.h" +#include "llfloaterwindlight.h" #include "lllineeditor.h" #include "llalertdialog.h" #include "llnamelistctrl.h" @@ -214,7 +216,6 @@ BOOL LLFloaterRegionInfo::postBuild() LLFloaterRegionInfo::~LLFloaterRegionInfo() { - sInstance = NULL; } void LLFloaterRegionInfo::onOpen() @@ -229,6 +230,7 @@ void LLFloaterRegionInfo::onOpen() LLFloater::onOpen(); } +// static void LLFloaterRegionInfo::requestRegionInfo() { // Must allow anyone to request the RegionInfo data @@ -247,14 +249,17 @@ void LLFloaterRegionInfo::requestRegionInfo() void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) { static LLDispatcher dispatch; - if(!sInstance) return; - + if(!findInstance()) + { + return; + } + if (!estate_dispatch_initialized) { LLPanelEstateInfo::initDispatch(dispatch); } - LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(sInstance, "region_panels"); + LLTabContainer* tab = LLUICtrlFactory::getTabContainerByName(findInstance(), "region_panels"); if (!tab) return; LLPanelEstateInfo* panel = (LLPanelEstateInfo*)LLUICtrlFactory::getPanelByName(tab, "Estate"); @@ -282,8 +287,12 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) LLPanel* panel; llinfos << "LLFloaterRegionInfo::processRegionInfo" << llendl; - if(!sInstance) return; - LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(sInstance, "region_panels"); + if(!findInstance()) + { + return; + } + + LLTabContainer* tab = LLUICtrlFactory::getTabContainerByName(findInstance(), "region_panels"); if(!tab) return; // extract message @@ -359,6 +368,8 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg) panel->childSetEnabled("fixed_sun_check", allow_modify && !use_estate_sun); panel->childSetValue("sun_hour_slider", LLSD(sun_hour)); panel->childSetEnabled("sun_hour_slider", allow_modify && !use_estate_sun); + + getInstance()->refreshFromRegion( gAgent.getRegion() ); } // static @@ -366,7 +377,7 @@ LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() { LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); if (!floater) return NULL; - LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(floater, "region_panels"); + LLTabContainer* tab = LLUICtrlFactory::getTabContainerByName(floater, "region_panels"); if (!tab) return NULL; LLPanelEstateInfo* panel = (LLPanelEstateInfo*)LLUICtrlFactory::getPanelByName(tab,"Estate"); return panel; @@ -377,7 +388,7 @@ LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() { LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); if (!floater) return NULL; - LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(floater, "region_panels"); + LLTabContainer* tab = LLUICtrlFactory::getTabContainerByName(floater, "region_panels"); if (!tab) return NULL; LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)LLUICtrlFactory::getPanelByName(tab, "Covenant"); return panel; @@ -450,6 +461,15 @@ void LLPanelRegionInfo::onChangeAnything(LLUICtrl* ctrl, void* user_data) } } +// static +// Enables set button on change to line editor +void LLPanelRegionInfo::onChangeText(LLLineEditor* caller, void* user_data) +{ + // reuse the previous method + onChangeAnything(0, user_data); +} + + // virtual BOOL LLPanelRegionInfo::postBuild() { @@ -519,6 +539,12 @@ void LLPanelRegionInfo::initCtrl(const char* name) childSetCommitCallback(name, onChangeAnything, this); } +void LLPanelRegionInfo::initTextCtrl(const char* name) +{ + childSetCommitCallback(name, onChangeAnything, this); + childSetKeystrokeCallback("abuse_email_address", onChangeText, this); +} + void LLPanelRegionInfo::initHelpBtn(const char* name, const char* xml_alert) { childSetAction(name, onClickHelp, (void*)xml_alert); @@ -1231,7 +1257,7 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate() LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); if (!floater) return true; - LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(floater, "region_panels"); + LLTabContainer* tab = LLUICtrlFactory::getTabContainerByName(floater, "region_panels"); if (!tab) return true; LLPanelEstateInfo* panel = (LLPanelEstateInfo*)LLUICtrlFactory::getPanelByName(tab, "Estate"); @@ -1412,9 +1438,21 @@ void LLPanelEstateInfo::onChangeFixedSun(LLUICtrl* ctrl, void* user_data) } } + + + //--------------------------------------------------------------------------- // Add/Remove estate access button callbacks //--------------------------------------------------------------------------- +void LLPanelEstateInfo::onClickEditSky(void* user_data) +{ + LLFloaterWindLight::show(); +} + +void LLPanelEstateInfo::onClickEditDayCycle(void* user_data) +{ + LLFloaterDayCycle::show(); +} // static void LLPanelEstateInfo::onClickAddAllowedAgent(void* user_data) @@ -1920,6 +1958,7 @@ bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) childSetEnabled("remove_banned_avatar_btn", god || owner || manager); childSetEnabled("message_estate_btn", god || owner || manager); childSetEnabled("kick_user_from_estate_btn", god || owner || manager); + childSetEnabled("abuse_email_address", god || owner || manager); // estate managers can't add estate managers childSetEnabled("add_estate_manager_btn", god || owner); @@ -1980,16 +2019,21 @@ BOOL LLPanelEstateInfo::postBuild() initCtrl("limit_payment"); initCtrl("limit_age_verified"); initCtrl("voice_chat_check"); + initTextCtrl("abuse_email_address"); initHelpBtn("estate_manager_help", "HelpEstateEstateManager"); initHelpBtn("use_global_time_help", "HelpEstateUseGlobalTime"); initHelpBtn("fixed_sun_help", "HelpEstateFixedSun"); + initHelpBtn("WLEditSkyHelp", "HelpEditSky"); + initHelpBtn("WLEditDayCycleHelp", "HelpEditDayCycle"); + initHelpBtn("externally_visible_help", "HelpEstateExternallyVisible"); initHelpBtn("allow_direct_teleport_help", "HelpEstateAllowDirectTeleport"); initHelpBtn("allow_resident_help", "HelpEstateAllowResident"); initHelpBtn("allow_group_help", "HelpEstateAllowGroup"); initHelpBtn("ban_resident_help", "HelpEstateBanResident"); - initHelpBtn("voice_chat_help", "HelpEstateVoiceChat"); + initHelpBtn("abuse_email_address_help", "HelpEstateAbuseEmailAddress"); + initHelpBtn("voice_chat_help", "HelpEstateVoiceChat"); // set up the use global time checkbox childSetCommitCallback("use_global_time_check", onChangeUseGlobalTime, this); @@ -2042,6 +2086,9 @@ BOOL LLPanelEstateInfo::postBuild() childSetAction("message_estate_btn", onClickMessageEstate, this); childSetAction("kick_user_from_estate_btn", onClickKickUser, this); + childSetAction("WLEditSky", onClickEditSky, this); + childSetAction("WLEditDayCycle", onClickEditDayCycle, this); + return LLPanelRegionInfo::postBuild(); } @@ -2086,8 +2133,19 @@ void LLPanelEstateInfo::callbackChangeLindenEstate(S32 option, void* data) { case 0: // send the update - LLFloaterRegionInfo::nextInvoice(); - self->commitEstateInfo(); + if (!self->commitEstateInfoCaps()) + { + // the caps method failed, try the old way + LLFloaterRegionInfo::nextInvoice(); + self->commitEstateInfoDataserver(); + } + // we don't want to do this because we'll get it automatically from the sim + // after the spaceserver processes it +// else +// { +// // caps method does not automatically send this info +// LLFloaterRegionInfo::requestRegionInfo(); +// } break; case 1: default: @@ -2125,12 +2183,75 @@ void LLPanelEstateInfo::getEstateOwner() } */ +class LLEstateChangeInfoResponder : public LLHTTPClient::Responder +{ +public: + LLEstateChangeInfoResponder(void* userdata) : mpPanel((LLPanelEstateInfo*)userdata) {}; + + // if we get a normal response, handle it here + virtual void result(const LLSD& content) + { + // refresh the panel from the database + mpPanel->refresh(); + } + + // if we get an error response + virtual void error(U32 status, const std::string& reason) + { + llinfos << "LLEstateChangeInfoResponder::error " + << status << ": " << reason << llendl; + } +private: + LLPanelEstateInfo* mpPanel; +}; + +// tries to send estate info using a cap; returns true if it succeeded +bool LLPanelEstateInfo::commitEstateInfoCaps() +{ + std::string url = gAgent.getRegion()->getCapability("EstateChangeInfo"); + + if (url.empty()) + { + // whoops, couldn't find the cap, so bail out + return false; + } + + LLSD body; + body["estate_name"] = getEstateName(); + + body["is_externally_visible"] = childGetValue("externally_visible_check").asBoolean(); + body["allow_direct_teleport"] = childGetValue("allow_direct_teleport").asBoolean(); + body["is_sun_fixed" ] = childGetValue("fixed_sun_check").asBoolean(); + body["deny_anonymous" ] = childGetValue("limit_payment").asBoolean(); + body["deny_age_unverified" ] = childGetValue("limit_age_verified").asBoolean(); + body["allow_voice_chat" ] = childGetValue("voice_chat_check").asBoolean(); + body["invoice" ] = LLFloaterRegionInfo::getLastInvoice(); + + // block fly is in estate database but not in estate UI, so we're not supporting it + //body["block_fly" ] = childGetValue("").asBoolean(); + + F32 sun_hour = getSunHour(); + if (childGetValue("use_global_time_check").asBoolean()) + { + sun_hour = 0.f; // 0 = global time + } + body["sun_hour"] = sun_hour; + + body["owner_abuse_email"] = childGetValue("abuse_email_address").asString(); + + // we use a responder so that we can re-get the data after committing to the database + LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder((void*)this)); + return true; +} + +/* This is the old way of doing things, is deprecated, and should be + deleted when the dataserver model can be removed */ // key = "estatechangeinfo" // strings[0] = str(estate_id) (added by simulator before relay - not here) // strings[1] = estate_name // strings[2] = str(estate_flags) // strings[3] = str((S32)(sun_hour * 1024.f)) -void LLPanelEstateInfo::commitEstateInfo() +void LLPanelEstateInfo::commitEstateInfoDataserver() { LLMessageSystem* msg = gMessageSystem; msg->newMessage("EstateOwnerMessage"); @@ -2174,7 +2295,6 @@ void LLPanelEstateInfo::setEstateFlags(U32 flags) childSetValue("allow_direct_teleport", LLSD(flags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT ? TRUE : FALSE) ); childSetValue("limit_payment", LLSD(flags & REGION_FLAGS_DENY_ANONYMOUS ? TRUE : FALSE) ); childSetValue("limit_age_verified", LLSD(flags & REGION_FLAGS_DENY_AGEUNVERIFIED ? TRUE : FALSE) ); - childSetVisible("abuse_email_text", flags & REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER); refresh(); } @@ -2277,6 +2397,16 @@ void LLPanelEstateInfo::setOwnerName(const std::string& name) childSetValue("estate_owner", LLSD(name)); } +const std::string LLPanelEstateInfo::getAbuseEmailAddress() const +{ + return childGetValue("abuse_email_address").asString(); +} + +void LLPanelEstateInfo::setAbuseEmailAddress(const std::string& address) +{ + childSetValue("abuse_email_address", LLSD(address)); +} + void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent, bool enable_group, bool enable_ban) @@ -2439,35 +2569,35 @@ LLPanelEstateCovenant::LLPanelEstateCovenant() // virtual bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region) { - LLTextBox* region_name = (LLTextBox*)getChildByName("region_name_text"); + LLTextBox* region_name = getChild("region_name_text"); if (region_name) { region_name->setText(region->getName()); } - LLTextBox* resellable_clause = (LLTextBox*)getChildByName("resellable_clause"); + LLTextBox* resellable_clause = getChild("resellable_clause"); if (resellable_clause) { if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) { - resellable_clause->setText(childGetText("can_not_resell")); + resellable_clause->setText(getString("can_not_resell")); } else { - resellable_clause->setText(childGetText("can_resell")); + resellable_clause->setText(getString("can_resell")); } } - LLTextBox* changeable_clause = (LLTextBox*)getChildByName("changeable_clause"); + LLTextBox* changeable_clause = getChild("changeable_clause"); if (changeable_clause) { if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) { - changeable_clause->setText(childGetText("can_change")); + changeable_clause->setText(getString("can_change")); } else { - changeable_clause->setText(childGetText("can_not_change")); + changeable_clause->setText(getString("can_not_change")); } } @@ -2493,12 +2623,12 @@ bool LLPanelEstateCovenant::estateUpdate(LLMessageSystem* msg) BOOL LLPanelEstateCovenant::postBuild() { initHelpBtn("covenant_help", "HelpEstateCovenant"); - mEstateNameText = (LLTextBox*)getChildByName("estate_name_text"); - mEstateOwnerText = (LLTextBox*)getChildByName("estate_owner_text"); - mLastModifiedText = (LLTextBox*)getChildByName("covenant_timestamp_text"); - mEditor = (LLViewerTextEditor*)getChildByName("covenant_editor"); + mEstateNameText = getChild("estate_name_text"); + mEstateOwnerText = getChild("estate_owner_text"); + mLastModifiedText = getChild("covenant_timestamp_text"); + mEditor = getChild("covenant_editor"); if (mEditor) mEditor->setHandleEditKeysDirectly(TRUE); - LLButton* reset_button = (LLButton*)getChildByName("reset_covenant"); + LLButton* reset_button = getChild("reset_covenant"); reset_button->setEnabled(gAgent.canManageEstate()); reset_button->setClickedCallback(LLPanelEstateCovenant::resetCovenantID, NULL); @@ -2821,6 +2951,7 @@ bool LLDispatchSetEstateOwner::operator()( // strings[6] = str(covenant_id) // strings[7] = str(covenant_timestamp) // strings[8] = str(send_to_agent_only) +// strings[9] = str(abuse_email_addr) bool LLDispatchEstateUpdateInfo::operator()( const LLDispatcher* dispatcher, const std::string& key, @@ -2836,6 +2967,15 @@ bool LLDispatchEstateUpdateInfo::operator()( std::string estate_name = strings[0].c_str(); panel->setEstateName(estate_name); + if (strings.size() > 9) + { + std::string abuse_email = strings[9].c_str(); + panel->setAbuseEmailAddress(abuse_email); + } + else + { + panel->setAbuseEmailAddress("@ Old Server @"); + } LLViewerRegion* regionp = gAgent.getRegion(); diff --git a/linden/indra/newview/llfloaterregioninfo.h b/linden/indra/newview/llfloaterregioninfo.h index 8918430..096c78b 100644 --- a/linden/indra/newview/llfloaterregioninfo.h +++ b/linden/indra/newview/llfloaterregioninfo.h @@ -58,9 +58,9 @@ class LLPanelRegionTerrainInfo; class LLPanelEstateInfo; class LLPanelEstateCovenant; -class LLFloaterRegionInfo : public LLFloater, public LLUISingleton +class LLFloaterRegionInfo : public LLFloater, public LLFloaterSingleton { - friend class LLUISingleton; + friend class LLUISingleton >; public: ~LLFloaterRegionInfo(); @@ -83,14 +83,14 @@ public: // from LLPanel virtual void refresh(); - void requestRegionInfo(); + static void requestRegionInfo(); protected: LLFloaterRegionInfo(const LLSD& seed); void refreshFromRegion(LLViewerRegion* region); // member data - LLTabContainerCommon* mTab; + LLTabContainer* mTab; typedef std::vector info_panels_t; info_panels_t mInfoPanels; //static S32 sRequestSerial; // serial # of last EstateOwnerRequest @@ -106,6 +106,7 @@ public: static void onBtnSet(void* user_data); static void onChangeChildCtrl(LLUICtrl* ctrl, void* user_data); static void onChangeAnything(LLUICtrl* ctrl, void* user_data); + static void onChangeText(LLLineEditor* caller, void* user_data); virtual bool refreshFromRegion(LLViewerRegion* region); virtual bool estateUpdate(LLMessageSystem* msg) { return true; } @@ -118,6 +119,7 @@ public: protected: void initCtrl(const char* name); + void initTextCtrl(const char* name); void initHelpBtn(const char* name, const char* xml_alert); // Callback for all help buttons, data is name of XML alert to show. @@ -255,6 +257,11 @@ public: static void onChangeFixedSun(LLUICtrl* ctrl, void* user_data); static void onChangeUseGlobalTime(LLUICtrl* ctrl, void* user_data); + static void onClickEditSky(void* userdata); + static void onClickEditSkyHelp(void* userdata); + static void onClickEditDayCycle(void* userdata); + static void onClickEditDayCycleHelp(void* userdata); + static void onClickAddAllowedAgent(void* user_data); static void onClickRemoveAllowedAgent(void* user_data); static void onClickAddAllowedGroup(void* user_data); @@ -320,6 +327,9 @@ public: const std::string getOwnerName() const; void setOwnerName(const std::string& name); + const std::string getAbuseEmailAddress() const; + void setAbuseEmailAddress(const std::string& address); + // If visible from mainland, allowed agent and allowed groups // are ignored, so must disable UI. void setAccessAllowedEnabled(bool enable_agent, bool enable_group, bool enable_ban); @@ -338,7 +348,8 @@ protected: // confirmation dialog callback static void callbackChangeLindenEstate(S32 opt, void* data); - void commitEstateInfo(); + void commitEstateInfoDataserver(); + bool commitEstateInfoCaps(); void commitEstateAccess(); void commitEstateManagers(); diff --git a/linden/indra/newview/llfloaterreleasemsg.cpp b/linden/indra/newview/llfloaterreleasemsg.cpp index b3fb965..4f122f5 100644 --- a/linden/indra/newview/llfloaterreleasemsg.cpp +++ b/linden/indra/newview/llfloaterreleasemsg.cpp @@ -60,10 +60,8 @@ LLFloaterReleaseMsg* LLFloaterReleaseMsg::getInstance() LLFloaterReleaseMsg::LLFloaterReleaseMsg() : LLFloater( "Release Message Floater" ) -#if LL_LIBXUL_ENABLED , mWebBrowser( 0 ) -#endif // LL_LIBXUL_ENABLED { // create floater from its XML definition gUICtrlFactory->buildFloater( this, "floater_sim_release_message.xml" ); @@ -75,7 +73,6 @@ LLFloaterReleaseMsg::LLFloaterReleaseMsg() reshape( rect.getWidth(), rect.getHeight(), FALSE ); setRect( rect ); -#if LL_LIBXUL_ENABLED mWebBrowser = LLViewerUICtrlFactory::getWebBrowserByName(this, "release_message_floater_browser" ); if ( mWebBrowser ) { @@ -89,7 +86,6 @@ LLFloaterReleaseMsg::LLFloaterReleaseMsg() // special ones that do other stuff (like open F1 Help) //mWebBrowser->setOpenSecondLifeLinksInMap( false ); } -#endif // LL_LIBXUL_ENABLED childSetAction("close_btn", onClickClose, this); setDefaultBtn("close_btn"); @@ -99,14 +95,12 @@ LLFloaterReleaseMsg::LLFloaterReleaseMsg() // LLFloaterReleaseMsg::~LLFloaterReleaseMsg() { -#if LL_LIBXUL_ENABLED // stop observing browser events if ( mWebBrowser ) mWebBrowser->remObserver( this ); -#endif // LL_LIBXUL_ENABLED // save position of floater - gSavedSettings.setRect( "HtmlReleaseMessage", mRect ); + gSavedSettings.setRect( "HtmlReleaseMessage", getRect() ); sInstance = 0; } @@ -131,16 +125,12 @@ void LLFloaterReleaseMsg::show() sInstance->setTitle(sInstance->mTitleBase + " " + gLastVersionChannel); sInstance->open(); -#if LL_LIBXUL_ENABLED // navigate to the URL if ( sInstance->mWebBrowser ) sInstance->mWebBrowser->navigateTo( url ); -#endif // LL_LIBXUL_ENABLED // make floater appear sInstance->setVisibleAndFrontmost(); - - sInstance->draw(); } diff --git a/linden/indra/newview/llfloaterreleasemsg.h b/linden/indra/newview/llfloaterreleasemsg.h index e97d803..917a6ee 100644 --- a/linden/indra/newview/llfloaterreleasemsg.h +++ b/linden/indra/newview/llfloaterreleasemsg.h @@ -52,9 +52,7 @@ class LLFloaterReleaseMsg : LLString mTitleBase; private: LLFloaterReleaseMsg(); -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* mWebBrowser; -#endif // LL_LIBXUL_ENABLED LLButton* mCloseButton; }; diff --git a/linden/indra/newview/llfloaterreporter.cpp b/linden/indra/newview/llfloaterreporter.cpp index f0af5d0..5c076f0 100644 --- a/linden/indra/newview/llfloaterreporter.cpp +++ b/linden/indra/newview/llfloaterreporter.cpp @@ -861,7 +861,7 @@ void LLFloaterReporter::takeScreenshot() const S32 IMAGE_HEIGHT = 768; LLPointer raw = new LLImageRaw; - if( !gViewerWindow->rawSnapshot(raw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, TRUE, FALSE)) + if( !gViewerWindow->rawSnapshot(raw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE, TRUE, FALSE)) { llwarns << "Unable to take screenshot" << llendl; return; @@ -903,7 +903,7 @@ void LLFloaterReporter::takeScreenshot() gImageList.addImage(image_in_list); // the texture picker then uses that texture - LLTexturePicker* texture = LLUICtrlFactory::getTexturePickerByName(this, "screenshot"); + LLTexturePicker* texture = getChild("screenshot"); if (texture) { texture->setImageAssetID(mResourceDatap->mAssetInfo.mUuid); diff --git a/linden/indra/newview/llfloatersaveavatar.cpp b/linden/indra/newview/llfloatersaveavatar.cpp deleted file mode 100644 index 2675212..0000000 --- a/linden/indra/newview/llfloatersaveavatar.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/** - * @file llfloatersaveavatar.cpp - * @brief write out avatar as CAL3D file - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfloatersaveavatar.h" - -#include "lldir.h" - -#include "llagent.h" -#include "llvoavatar.h" -#include "llbutton.h" -#include "lllineeditor.h" -#include "llvieweruictrlfactory.h" -#include "llviewercontrol.h" - -static LLFloaterSaveAvatar* mSingleton = NULL; - -LLFloaterSaveAvatar::LLFloaterSaveAvatar() : LLFloater("Save Avatar") -{ - llassert( !mSingleton ); - mSingleton = this; -} - -LLFloaterSaveAvatar::~LLFloaterSaveAvatar() -{ - llassert( mSingleton == this ); - mSingleton = NULL; -} - -// Creates singleton or (if it already exists) brings it to the front -// static -void LLFloaterSaveAvatar::show() -{ - if ( !mSingleton) - { - LLFloaterSaveAvatar *instance = new LLFloaterSaveAvatar(); - - gUICtrlFactory->buildFloater(instance, "floater_save_avatar.xml"); - S32 left; - S32 top; - gFloaterView->getNewFloaterPosition(&left, &top); - instance->setOrigin(left, top - instance->getRect().getHeight()); - } - else - { - mSingleton->open(); /*Flawfinder: ignore*/ - } -} - -BOOL LLFloaterSaveAvatar::postBuild() -{ - mBaseNameEdit = LLViewerUICtrlFactory::getLineEditorByName(this, "base_name_edit"); - mBaseNameEdit->setText(gSavedSettings.getString("AvExportBaseName")); - mPathEdit = LLViewerUICtrlFactory::getLineEditorByName(this, "path_edit"); - mPathEdit->setText(gSavedSettings.getString("AvExportPath")); - - mSaveBtn = LLViewerUICtrlFactory::getButtonByName(this, "save_btn"); - mSaveBtn->setClickedCallback(onSave); - mSaveBtn->setCallbackUserData(this); - - return TRUE; -} - -//static -void LLFloaterSaveAvatar::onSave( void* user_data ) -{ - LLFloaterSaveAvatar* self = (LLFloaterSaveAvatar*)user_data; - - gSavedSettings.setString("AvExportPath", self->mPathEdit->getText()); - gSavedSettings.setString("AvExportBaseName", self->mBaseNameEdit->getText()); - - std::string path_name = self->mPathEdit->getText(); - if (path_name.size() && *(path_name.end() - 1) == '\\') - { - // remove trailing backslash - path_name.erase(path_name.end() - 1); - } - - std::string base_name = self->mBaseNameEdit->getText(); - if (base_name.size() && *(base_name.end() - 1) == '_') - { - // remove trailing underscore - base_name.erase(base_name.end() - 1); - } - - gAgent.getAvatarObject()->writeCAL3D(path_name, base_name); - self->close(); -} diff --git a/linden/indra/newview/llfloatersaveavatar.h b/linden/indra/newview/llfloatersaveavatar.h deleted file mode 100644 index 5a02fe4..0000000 --- a/linden/indra/newview/llfloatersaveavatar.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file llfloatersaveavatar.h - * @brief write out avatar as CAL3D file - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLFLOATERSAVEAVATAR_H -#define LL_LLFLOATERSAVEAVATAR_H - -#include "llfloater.h" - -class LLButton; -class LLLineEditor; - -class LLFloaterSaveAvatar : public LLFloater -{ -public: - static void show( void ); // Creates singleton or (if it already exists) brings it to the front - static void onSave( void* user_data ); - - virtual ~LLFloaterSaveAvatar(); - /*virtual*/ BOOL postBuild(); - -protected: - LLFloaterSaveAvatar(); - -public: - LLLineEditor* mBaseNameEdit; - LLLineEditor* mPathEdit; - LLButton* mSaveBtn; -}; - -#endif // LL_LLFLOATERSAVEAVATAR_H diff --git a/linden/indra/newview/llfloaterscriptdebug.cpp b/linden/indra/newview/llfloaterscriptdebug.cpp index 005bc53..b88ab78 100644 --- a/linden/indra/newview/llfloaterscriptdebug.cpp +++ b/linden/indra/newview/llfloaterscriptdebug.cpp @@ -163,14 +163,14 @@ LLFloaterScriptDebugOutput::LLFloaterScriptDebugOutput() LLFloaterScriptDebugOutput::LLFloaterScriptDebugOutput(const LLUUID& object_id) : LLFloater("script instance floater", LLRect(0, 200, 200, 0), "Script", TRUE), mObjectID(object_id) { - S32 y = mRect.getHeight() - LLFLOATER_HEADER_SIZE - LLFLOATER_VPAD; + S32 y = getRect().getHeight() - LLFLOATER_HEADER_SIZE - LLFLOATER_VPAD; S32 x = LLFLOATER_HPAD; // History editor // Give it a border on the top LLRect history_editor_rect( x, y, - mRect.getWidth() - LLFLOATER_HPAD, + getRect().getWidth() - LLFLOATER_HPAD, LLFLOATER_VPAD ); mHistoryEditor = new LLViewerTextEditor( "Chat History Editor", history_editor_rect, S32_MAX, "", LLFontGL::sSansSerif); @@ -186,14 +186,14 @@ void LLFloaterScriptDebugOutput::init(const LLString& title, BOOL resizable, BOOL minimizable, BOOL close_btn) { LLFloater::init(title, resizable, min_width, min_height, drag_on_left, minimizable, close_btn); - S32 y = mRect.getHeight() - LLFLOATER_HEADER_SIZE - LLFLOATER_VPAD; + S32 y = getRect().getHeight() - LLFLOATER_HEADER_SIZE - LLFLOATER_VPAD; S32 x = LLFLOATER_HPAD; // History editor // Give it a border on the top LLRect history_editor_rect( x, y, - mRect.getWidth() - LLFLOATER_HPAD, + getRect().getWidth() - LLFLOATER_HPAD, LLFLOATER_VPAD ); mHistoryEditor = new LLViewerTextEditor( "Chat History Editor", history_editor_rect, S32_MAX, "", LLFontGL::sSansSerif); diff --git a/linden/indra/newview/llfloatersellland.cpp b/linden/indra/newview/llfloatersellland.cpp index f3ae4ec..0be9246 100644 --- a/linden/indra/newview/llfloatersellland.cpp +++ b/linden/indra/newview/llfloatersellland.cpp @@ -244,13 +244,7 @@ void LLFloaterSellLandUI::updateParcelInfo() if(mSellToBuyer) { LLString name; - char firstname[MAX_STRING]; /* Flawfinder: ignore */ - char lastname[MAX_STRING]; /* Flawfinder: ignore */ - gCacheName->getName(mAuthorizedBuyer, firstname, lastname); - name.assign(firstname); - name.append(" "); - name.append(lastname); - + gCacheName->getFullName(mAuthorizedBuyer, name); childSetText("sell_to_agent", name); } } diff --git a/linden/indra/newview/llfloatersellland.h b/linden/indra/newview/llfloatersellland.h index 5109f34..0b5a480 100644 --- a/linden/indra/newview/llfloatersellland.h +++ b/linden/indra/newview/llfloatersellland.h @@ -40,7 +40,7 @@ class LLFloaterSellLand { public: static void sellLand(LLViewerRegion* region, - LLHandle parcel); + LLSafeHandle parcel); }; #endif // LL_LLFLOATERSELLLAND_H diff --git a/linden/indra/newview/llfloatersnapshot.cpp b/linden/indra/newview/llfloatersnapshot.cpp index 54895d5..9c91348 100644 --- a/linden/indra/newview/llfloatersnapshot.cpp +++ b/linden/indra/newview/llfloatersnapshot.cpp @@ -36,7 +36,9 @@ #include "llfontgl.h" #include "llsys.h" #include "llgl.h" +#include "llglimmediate.h" #include "v3dmath.h" +#include "llmath.h" #include "lldir.h" #include "llsdserialize.h" @@ -86,7 +88,7 @@ F32 FALL_TIME = 0.6f; S32 BORDER_WIDTH = 6; const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte - +#define MAX_TEXTURE_SIZE 512 //max upload texture size 512 * 512 ///---------------------------------------------------------------------------- /// Class LLSnapshotLivePreview ///---------------------------------------------------------------------------- @@ -112,6 +114,8 @@ public: void setSize(S32 w, S32 h); void getSize(S32& w, S32& h) const; S32 getDataSize() const { return mDataSize; } + void setMaxImageSize(S32 size) ; + S32 getMaxImageSize() {return mMaxImageSize ;} ESnapshotType getSnapshotType() const { return mSnapshotType; } BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; } @@ -138,7 +142,8 @@ protected: S32 mWidth[2]; S32 mHeight[2]; BOOL mImageScaled[2]; - + S32 mMaxImageSize ; + S32 mCurImageIndex; LLPointer mRawImage; LLPointer mRawImageEncoded; @@ -161,6 +166,7 @@ protected: public: static std::set sList; + BOOL mKeepAspectRatio ; }; std::set LLSnapshotLivePreview::sList; @@ -195,6 +201,9 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) : mHeight[1] = gViewerWindow->getWindowDisplayHeight(); mImageScaled[0] = FALSE; mImageScaled[1] = FALSE; + + mMaxImageSize = MAX_IMAGE_SIZE ; + mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ; } LLSnapshotLivePreview::~LLSnapshotLivePreview() @@ -208,6 +217,18 @@ LLSnapshotLivePreview::~LLSnapshotLivePreview() sList.erase(this); } +void LLSnapshotLivePreview::setMaxImageSize(S32 size) +{ + if(size < MAX_IMAGE_SIZE) + { + mMaxImageSize = size; + } + else + { + mMaxImageSize = MAX_IMAGE_SIZE ; + } +} + LLImageGL* LLSnapshotLivePreview::getCurrentImage() { return mViewerImage[mCurImageIndex]; @@ -221,9 +242,9 @@ F32 LLSnapshotLivePreview::getImageAspect() } F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]); - F32 window_aspect_ratio = ((F32)mRect.getWidth()) / ((F32)mRect.getHeight()); + F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight()); - if (gSavedSettings.getBOOL("KeepAspectForSnapshot")) + if (!mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot")) { return image_aspect_ratio; } @@ -262,26 +283,26 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot) } LLRect& rect = mImageRect[mCurImageIndex]; - rect.set(0, mRect.getHeight(), mRect.getWidth(), 0); + rect.set(0, getRect().getHeight(), getRect().getWidth(), 0); F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]); - F32 window_aspect_ratio = ((F32)mRect.getWidth()) / ((F32)mRect.getHeight()); + F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight()); - if (gSavedSettings.getBOOL("KeepAspectForSnapshot")) + if (mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot")) { if (image_aspect_ratio > window_aspect_ratio) { // trim off top and bottom - S32 new_height = llround((F32)mRect.getWidth() / image_aspect_ratio); - rect.mBottom += (mRect.getHeight() - new_height) / 2; - rect.mTop -= (mRect.getHeight() - new_height) / 2; + S32 new_height = llround((F32)getRect().getWidth() / image_aspect_ratio); + rect.mBottom += (getRect().getHeight() - new_height) / 2; + rect.mTop -= (getRect().getHeight() - new_height) / 2; } else if (image_aspect_ratio < window_aspect_ratio) { // trim off left and right - S32 new_width = llround((F32)mRect.getHeight() * image_aspect_ratio); - rect.mLeft += (mRect.getWidth() - new_width) / 2; - rect.mRight -= (mRect.getWidth() - new_width) / 2; + S32 new_width = llround((F32)getRect().getHeight() * image_aspect_ratio); + rect.mLeft += (getRect().getWidth() - new_width) / 2; + rect.mRight -= (getRect().getWidth() - new_width) / 2; } } } @@ -314,15 +335,14 @@ void LLSnapshotLivePreview::draw() mSnapshotUpToDate) { LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f); - gl_rect_2d(mRect, bg_color); + gl_rect_2d(getRect(), bg_color); LLRect &rect = mImageRect[mCurImageIndex]; LLRect shadow_rect = mImageRect[mCurImageIndex]; shadow_rect.stretch(BORDER_WIDTH); gl_drop_shadow(shadow_rect.mLeft, shadow_rect.mTop, shadow_rect.mRight, shadow_rect.mBottom, LLColor4(0.f, 0.f, 0.f, mNeedsFlash ? 0.f :0.5f), 10); - LLGLSTexture set_texture; LLColor4 image_color(1.f, 1.f, 1.f, 1.f); - glColor4fv(image_color.mV); + gGL.color4fv(image_color.mV); LLViewerImage::bindTexture(mViewerImage[mCurImageIndex]); // calculate UV scale F32 uv_width = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mWidth[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f); @@ -330,26 +350,26 @@ void LLSnapshotLivePreview::draw() glPushMatrix(); { glTranslatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { - glTexCoord2f(uv_width, uv_height); - glVertex2i(rect.getWidth(), rect.getHeight() ); + gGL.texCoord2f(uv_width, uv_height); + gGL.vertex2i(rect.getWidth(), rect.getHeight() ); - glTexCoord2f(0.f, uv_height); - glVertex2i(0, rect.getHeight() ); + gGL.texCoord2f(0.f, uv_height); + gGL.vertex2i(0, rect.getHeight() ); - glTexCoord2f(0.f, 0.f); - glVertex2i(0, 0); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(0, 0); - glTexCoord2f(uv_width, 0.f); - glVertex2i(rect.getWidth(), 0); + gGL.texCoord2f(uv_width, 0.f); + gGL.vertex2i(rect.getWidth(), 0); } - glEnd(); + gGL.end(); } glPopMatrix(); - glColor4f(1.f, 1.f, 1.f, mFlashAlpha); - gl_rect_2d(mRect); + gGL.color4f(1.f, 1.f, 1.f, mFlashAlpha); + gl_rect_2d(getRect()); if (mNeedsFlash) { if (mFlashAlpha < 1.f) @@ -393,23 +413,23 @@ void LLSnapshotLivePreview::draw() S32 y2 = gViewerWindow->getWindowHeight(); LLGLSNoTexture no_texture; - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { - glColor4f(1.f, 1.f, 1.f, 0.f); - glVertex2i(x1, y1); - glVertex2i(x1 + gViewerWindow->getWindowWidth(), y2); - glColor4f(1.f, 1.f, 1.f, SHINE_OPACITY); - glVertex2i(x2 + gViewerWindow->getWindowWidth(), y2); - glVertex2i(x2, y1); - - glColor4f(1.f, 1.f, 1.f, SHINE_OPACITY); - glVertex2i(x2, y1); - glVertex2i(x2 + gViewerWindow->getWindowWidth(), y2); - glColor4f(1.f, 1.f, 1.f, 0.f); - glVertex2i(x3 + gViewerWindow->getWindowWidth(), y2); - glVertex2i(x3, y1); + gGL.color4f(1.f, 1.f, 1.f, 0.f); + gGL.vertex2i(x1, y1); + gGL.vertex2i(x1 + gViewerWindow->getWindowWidth(), y2); + gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY); + gGL.vertex2i(x2 + gViewerWindow->getWindowWidth(), y2); + gGL.vertex2i(x2, y1); + + gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY); + gGL.vertex2i(x2, y1); + gGL.vertex2i(x2 + gViewerWindow->getWindowWidth(), y2); + gGL.color4f(1.f, 1.f, 1.f, 0.f); + gGL.vertex2i(x3 + gViewerWindow->getWindowWidth(), y2); + gGL.vertex2i(x3, y1); } - glEnd(); + gGL.end(); } if (mShineAnimTimer.getElapsedTimeF32() > SHINE_TIME) @@ -422,31 +442,31 @@ void LLSnapshotLivePreview::draw() // draw framing rectangle { LLGLSNoTexture no_texture; - glColor4f(1.f, 1.f, 1.f, 1.f); + gGL.color4f(1.f, 1.f, 1.f, 1.f); LLRect outline_rect = mImageRect[mCurImageIndex]; - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { - glVertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); - glVertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); - glVertex2i(outline_rect.mRight, outline_rect.mTop); - glVertex2i(outline_rect.mLeft, outline_rect.mTop); - - glVertex2i(outline_rect.mLeft, outline_rect.mBottom); - glVertex2i(outline_rect.mRight, outline_rect.mBottom); - glVertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH); - glVertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH); - - glVertex2i(outline_rect.mLeft, outline_rect.mTop); - glVertex2i(outline_rect.mLeft, outline_rect.mBottom); - glVertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH); - glVertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); - - glVertex2i(outline_rect.mRight, outline_rect.mBottom); - glVertex2i(outline_rect.mRight, outline_rect.mTop); - glVertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); - glVertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH); + gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); + gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); + gGL.vertex2i(outline_rect.mRight, outline_rect.mTop); + gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop); + + gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom); + gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom); + gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH); + gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH); + + gGL.vertex2i(outline_rect.mLeft, outline_rect.mTop); + gGL.vertex2i(outline_rect.mLeft, outline_rect.mBottom); + gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH); + gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); + + gGL.vertex2i(outline_rect.mRight, outline_rect.mBottom); + gGL.vertex2i(outline_rect.mRight, outline_rect.mTop); + gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH); + gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mBottom - BORDER_WIDTH); } - glEnd(); + gGL.end(); } // draw old image dropping away @@ -455,12 +475,10 @@ void LLSnapshotLivePreview::draw() S32 old_image_index = (mCurImageIndex + 1) % 2; if (mViewerImage[old_image_index].notNull() && mFallAnimTimer.getElapsedTimeF32() < FALL_TIME) { - LLGLSTexture texture_set; - F32 fall_interp = mFallAnimTimer.getElapsedTimeF32() / FALL_TIME; F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f); LLColor4 image_color(1.f, 1.f, 1.f, alpha); - glColor4fv(image_color.mV); + gGL.color4fv(image_color.mV); LLViewerImage::bindTexture(mViewerImage[old_image_index]); // calculate UV scale // *FIX get this to work with old image @@ -470,23 +488,23 @@ void LLSnapshotLivePreview::draw() glPushMatrix(); { LLRect& rect = mImageRect[old_image_index]; - glTranslatef((F32)rect.mLeft, (F32)rect.mBottom - llround(mRect.getHeight() * 2.f * (fall_interp * fall_interp)), 0.f); + glTranslatef((F32)rect.mLeft, (F32)rect.mBottom - llround(getRect().getHeight() * 2.f * (fall_interp * fall_interp)), 0.f); glRotatef(-45.f * fall_interp, 0.f, 0.f, 1.f); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { - glTexCoord2f(uv_width, uv_height); - glVertex2i(rect.getWidth(), rect.getHeight() ); + gGL.texCoord2f(uv_width, uv_height); + gGL.vertex2i(rect.getWidth(), rect.getHeight() ); - glTexCoord2f(0.f, uv_height); - glVertex2i(0, rect.getHeight() ); + gGL.texCoord2f(0.f, uv_height); + gGL.vertex2i(0, rect.getHeight() ); - glTexCoord2f(0.f, 0.f); - glVertex2i(0, 0); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(0, 0); - glTexCoord2f(uv_width, 0.f); - glVertex2i(rect.getWidth(), 0); + gGL.texCoord2f(uv_width, 0.f); + gGL.vertex2i(rect.getWidth(), 0); } - glEnd(); + gGL.end(); } glPopMatrix(); } @@ -497,7 +515,7 @@ void LLSnapshotLivePreview::draw() /*virtual*/ void LLSnapshotLivePreview::reshape(S32 width, S32 height, BOOL called_from_parent) { - LLRect old_rect = mRect; + LLRect old_rect = getRect(); LLView::reshape(width, height, called_from_parent); if (old_rect.getWidth() != width || old_rect.getHeight() != height) { @@ -552,10 +570,12 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview ) if(gViewerWindow->rawSnapshot(previewp->mRawImage, previewp->mWidth[previewp->mCurImageIndex], previewp->mHeight[previewp->mCurImageIndex], - !gSavedSettings.getBOOL("KeepAspectForSnapshot"), + previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"), + previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE, gSavedSettings.getBOOL("RenderUIInSnapshot"), FALSE, - previewp->mSnapshotBufferType)) + previewp->mSnapshotBufferType, + previewp->getMaxImageSize())) { previewp->mRawImageEncoded->resize(previewp->mRawImage->getWidth(), previewp->mRawImage->getHeight(), previewp->mRawImage->getComponents()); @@ -726,6 +746,9 @@ public: static void onClickKeep(void* data); static void onClickNewSnapshot(void* data); static void onClickAutoSnap(LLUICtrl *ctrl, void* data); + //static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data); + static void onClickLess(void* data) ; + static void onClickMore(void* data) ; static void onClickUICheck(LLUICtrl *ctrl, void* data); static void onClickHUDCheck(LLUICtrl *ctrl, void* data); static void onClickKeepOpenCheck(LLUICtrl *ctrl, void* data); @@ -736,19 +759,22 @@ public: static void onCommitLayerTypes(LLUICtrl* ctrl, void*data); static void onCommitSnapshotType(LLUICtrl* ctrl, void* data); static void onCommitCustomResolution(LLUICtrl *ctrl, void* data); + static void checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value); static LLSnapshotLivePreview* getPreviewView(LLFloaterSnapshot *floater); static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname); static void updateControls(LLFloaterSnapshot* floater); static void updateLayout(LLFloaterSnapshot* floater); - static LLViewHandle sPreviewHandle; + static LLHandle sPreviewHandle; + static BOOL sAspectRatioCheckOff ; private: static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater); static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater); static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname); static void checkAutoSnapshot(LLSnapshotLivePreview* floater); + static void checkAspectRatio(LLFloaterSnapshot *view, S32 index) ; public: std::vector mAvatarPauseHandles; @@ -757,12 +783,14 @@ public: }; // static -LLViewHandle LLFloaterSnapshot::Impl::sPreviewHandle; +LLHandle LLFloaterSnapshot::Impl::sPreviewHandle; +//static +BOOL LLFloaterSnapshot::Impl::sAspectRatioCheckOff = FALSE ; // static LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater) { - LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)LLView::getViewByHandle(sPreviewHandle); + LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)sPreviewHandle.get(); return previewp; } @@ -811,13 +839,37 @@ void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshot* floater, const st void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) { LLSnapshotLivePreview* previewp = getPreviewView(floaterp); + + S32 delta_height = gSavedSettings.getBOOL("AdvanceSnapshot") ? 0 : -230 ; + + LLComboBox* combo; + if(!gSavedSettings.getBOOL("AdvanceSnapshot")) //set to original window resolution + { + previewp->mKeepAspectRatio = TRUE ; + + combo = LLUICtrlFactory::getComboBoxByName(floaterp, "postcard_size_combo"); + combo->setCurrentByIndex(0) ; + gSavedSettings.setS32("SnapshotPostcardLastResolution", 0) ; + + combo = LLUICtrlFactory::getComboBoxByName(floaterp, "texture_size_combo"); + combo->setCurrentByIndex(0) ; + gSavedSettings.setS32("SnapshotTextureLastResolution", 0) ; + + combo = LLUICtrlFactory::getComboBoxByName(floaterp, "local_size_combo"); + combo->setCurrentByIndex(0) ; + gSavedSettings.setS32("SnapshotLocalLastResolution", 0) ; + + LLSnapshotLivePreview* previewp = getPreviewView(floaterp); + previewp->setSize(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); + } + if (floaterp->childGetValue("freeze_frame_check").asBoolean()) { // stop all mouse events at fullscreen preview layer floaterp->getParent()->setMouseOpaque(TRUE); // shrink to smaller layout - floaterp->reshape(floaterp->mRect.getWidth(), 410); + floaterp->reshape(floaterp->getRect().getWidth(), 526 + delta_height); // can see and interact with fullscreen preview now if (previewp) @@ -850,7 +902,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) else // turning off freeze frame mode { floaterp->getParent()->setMouseOpaque(FALSE); - floaterp->reshape(floaterp->mRect.getWidth(), 510); + floaterp->reshape(floaterp->getRect().getWidth(), 526 + delta_height); if (previewp) { previewp->setVisible(FALSE); @@ -878,6 +930,8 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp) // static void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) { + BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot") ; + LLRadioGroup* snapshot_type_radio = LLUICtrlFactory::getRadioGroupByName(floater, "snapshot_type_radio"); snapshot_type_radio->setSelectedIndex(gSavedSettings.getS32("LastSnapshotType")); LLSnapshotLivePreview::ESnapshotType shot_type = getTypeIndex(floater); @@ -895,19 +949,29 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) combo = LLUICtrlFactory::getComboBoxByName(floater, "local_size_combo"); if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution")); - floater->childSetVisible("upload_btn", FALSE); floater->childSetVisible("send_btn", FALSE); floater->childSetVisible("save_btn", FALSE); - + floater->childSetEnabled("keep_aspect_check", FALSE) ; + switch(shot_type) { case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR; floater->childSetValue("layer_types", "colors"); floater->childSetEnabled("layer_types", FALSE); - floater->childSetEnabled("image_quality_slider", TRUE); - setResolution(floater, "postcard_size_combo"); + + if(is_advance) + { + floater->childSetEnabled("image_quality_slider", TRUE); + setResolution(floater, "postcard_size_combo"); + + if(!sAspectRatioCheckOff) + { + floater->childSetEnabled("keep_aspect_check", TRUE) ; + } + } + floater->childSetVisible("send_btn", TRUE); break; case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: @@ -915,18 +979,69 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) floater->childSetValue("layer_types", "colors"); floater->childSetEnabled("layer_types", FALSE); floater->childSetEnabled("image_quality_slider", FALSE); - setResolution(floater, "texture_size_combo"); + + if(is_advance) + { + setResolution(floater, "texture_size_combo"); + } + floater->childSetVisible("upload_btn", TRUE); break; case LLSnapshotLivePreview::SNAPSHOT_BITMAP: floater->childSetEnabled("layer_types", TRUE); floater->childSetEnabled("image_quality_slider", FALSE); - setResolution(floater, "local_size_combo"); + + if(is_advance) + { + setResolution(floater, "local_size_combo"); + + if(!sAspectRatioCheckOff) + { + floater->childSetEnabled("keep_aspect_check", TRUE) ; + } + } + floater->childSetVisible("save_btn", TRUE); break; default: break; } + + if(is_advance) + { + floater->childSetVisible("type_label2", TRUE) ; + floater->childSetVisible("layer_types", TRUE) ; + floater->childSetVisible("layer_type_label", TRUE) ; + floater->childSetVisible("snapshot_width", TRUE) ; + floater->childSetVisible("snapshot_height", TRUE) ; + floater->childSetVisible("keep_aspect_check", TRUE) ; + floater->childSetVisible("ui_check", TRUE) ; + floater->childSetVisible("hud_check", TRUE) ; + floater->childSetVisible("keep_open_check", TRUE) ; + floater->childSetVisible("freeze_frame_check", TRUE) ; + floater->childSetVisible("auto_snapshot_check", TRUE) ; + floater->childSetVisible("image_quality_slider", TRUE); + floater->childSetVisible("more_btn", FALSE); + floater->childSetVisible("less_btn", TRUE); + } + else + { + floater->childSetVisible("type_label2", FALSE) ; + floater->childSetVisible("layer_types", FALSE) ; + floater->childSetVisible("layer_type_label", FALSE) ; + floater->childSetVisible("snapshot_width", FALSE) ; + floater->childSetVisible("snapshot_height", FALSE) ; + floater->childSetVisible("keep_aspect_check", FALSE) ; + floater->childSetVisible("ui_check", FALSE) ; + floater->childSetVisible("hud_check", FALSE) ; + floater->childSetVisible("keep_open_check", FALSE) ; + floater->childSetVisible("freeze_frame_check", FALSE) ; + floater->childSetVisible("auto_snapshot_check", FALSE) ; + floater->childSetVisible("image_quality_slider", FALSE); + floater->childSetVisible("more_btn", TRUE); + floater->childSetVisible("less_btn", FALSE); + } + LLSnapshotLivePreview* previewp = getPreviewView(floater); if (previewp) { @@ -939,7 +1054,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp) { if (previewp) - { + { previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot")); } } @@ -1026,6 +1141,59 @@ void LLFloaterSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data) } } +void LLFloaterSnapshot::Impl::onClickMore(void* data) +{ + //floater->childSetVisible("more_btn", FALSE); + //floater->childSetVisible("less_btn", TRUE); + + gSavedSettings.setBOOL( "AdvanceSnapshot", TRUE ); + + LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; + if (view) + { + view->translate( 0, -230 ); + view->reshape(view->getRect().getWidth(), 526); + + updateControls(view) ; + updateLayout(view) ; + } +} +void LLFloaterSnapshot::Impl::onClickLess(void* data) +{ + //floater->childSetVisible("less_btn", FALSE); + //floater->childSetVisible("more_btn", TRUE); + + gSavedSettings.setBOOL( "AdvanceSnapshot", FALSE ); + + LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; + if (view) + { + view->translate( 0, 230 ); + view->reshape(view->getRect().getWidth(), 294); + + updateControls(view) ; + updateLayout(view) ; + } +} + +//void LLFloaterSnapshot::Impl::onClickAdvanceSnap(LLUICtrl *ctrl, void* data) +//{ +// LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl; +// gSavedSettings.setBOOL( "AdvanceSnapshot", check->get() ); +// +// LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; +// if (view) +// { +// S32 delta_height = gSavedSettings.getBOOL("AdvanceSnapshot") ? 0 : -230 ; +// +// view->translate( 0, delta_height ? 230 : -230 ); +// view->reshape(view->getRect().getWidth(), 526 + delta_height); +// +// updateControls(view) ; +// updateLayout(view) ; +// } +//} + // static void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data) { @@ -1069,7 +1237,31 @@ void LLFloaterSnapshot::Impl::onClickKeepAspectCheck(LLUICtrl* ctrl, void* data) LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; if (view) { - checkAutoSnapshot(getPreviewView(view)); + LLSnapshotLivePreview* previewp = getPreviewView(view) ; + if(previewp) + { + previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ; + + S32 w, h ; + previewp->getSize(w, h) ; + checkImageSize(previewp, w, h, TRUE, previewp->getMaxImageSize()) ; + previewp->setSize(w, h) ; + + //update textbox + LLSpinCtrl *sctrl = LLViewerUICtrlFactory::getSpinnerByName(view, "snapshot_width") ; + if(sctrl) + { + sctrl->setValue(w) ; + } + + sctrl = LLViewerUICtrlFactory::getSpinnerByName(view, "snapshot_height") ; + if(sctrl) + { + sctrl->setValue(h) ; + } + + checkAutoSnapshot(previewp); + } } } @@ -1104,6 +1296,48 @@ void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data) } // static +void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 index) +{ + LLSnapshotLivePreview *previewp = getPreviewView(view) ; + + if(!index) //current window size + { + sAspectRatioCheckOff = TRUE ; + view->childSetEnabled("keep_aspect_check", FALSE) ; + + if(previewp) + { + previewp->mKeepAspectRatio = TRUE ; + } + } + else if(-1 == index) //custom + { + sAspectRatioCheckOff = FALSE ; + if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE != gSavedSettings.getS32("LastSnapshotType")) + { + view->childSetEnabled("keep_aspect_check", TRUE) ; + + if(previewp) + { + previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ; + } + } + } + else + { + sAspectRatioCheckOff = TRUE ; + view->childSetEnabled("keep_aspect_check", FALSE) ; + + if(previewp) + { + previewp->mKeepAspectRatio = FALSE ; + } + } + + return ; +} + +// static void LLFloaterSnapshot::Impl::onCommitResolution(LLUICtrl* ctrl, void* data) { LLComboBox* combobox = (LLComboBox*)ctrl; @@ -1126,7 +1360,7 @@ void LLFloaterSnapshot::Impl::onCommitResolution(LLUICtrl* ctrl, void* data) std::string sdstring = combobox->getSelectedValue(); LLSD sdres; std::stringstream sstream(sdstring); - LLSDSerialize::fromNotation(sdres, sstream); + LLSDSerialize::fromNotation(sdres, sstream, sdstring.size()); S32 width = sdres[0]; S32 height = sdres[1]; @@ -1148,7 +1382,12 @@ void LLFloaterSnapshot::Impl::onCommitResolution(LLUICtrl* ctrl, void* data) previewp->setSize(width, height); } + checkAspectRatio(view, width) ; + previewp->getSize(width, height); + checkImageSize(previewp, width, height, TRUE, previewp->getMaxImageSize()) ; + previewp->setSize(width, height); + view->childSetValue("snapshot_width", width); view->childSetValue("snapshot_height", height); // hide old preview as the aspect ratio could be wrong @@ -1193,7 +1432,74 @@ void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const s if (combo) { combo->setCurrentByIndex(combo->getItemCount() - 1); + + checkAspectRatio(floater, -1);//combo->getCurrentIndex()) ; + } +} + + + +//static +void LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value) +{ + //if texture, ignore aspect ratio setting, round image size to power of 2. + if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == gSavedSettings.getS32("LastSnapshotType")) + { + if(width > max_value) + { + width = max_value ; + } + if(height > max_value) + { + height = max_value ; + } + + //round to nearest power of 2 + width = get_nearest_power_two(width, MAX_TEXTURE_SIZE) ; + height = get_nearest_power_two(height, MAX_TEXTURE_SIZE) ; + + return ; } + + if(previewp && previewp->mKeepAspectRatio) + { + if(gViewerWindow->getWindowDisplayWidth() < 1 || gViewerWindow->getWindowDisplayHeight() < 1) + { + return ; + } + + //aspect ratio of the current window + F32 aspect_ratio = (F32)gViewerWindow->getWindowDisplayWidth() / gViewerWindow->getWindowDisplayHeight() ; + + //change another value proportionally + if(isWidthChanged) + { + height = (S32)(width / aspect_ratio) ; + } + else + { + width = (S32)(height * aspect_ratio) ; + } + + //bound w/h by the max_value + if(width > max_value || height > max_value) + { + if(width > height) + { + width = max_value ; + height = (S32)(width / aspect_ratio) ; + } + else + { + height = max_value ; + width = (S32)(height * aspect_ratio) ; + } + } + } + else + { + } + return ; } //static @@ -1216,6 +1522,33 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat if (w != curw || h != curh) { + S32 width = w ; + S32 height = h ; + + previewp->setMaxImageSize((S32)((LLSpinCtrl *)ctrl)->getMaxValue()) ; + checkImageSize(previewp, width, height, width != curw, previewp->getMaxImageSize()) ; + + if(width != w || height != h) + { + LLSpinCtrl *sctrl = LLViewerUICtrlFactory::getSpinnerByName(view, "snapshot_width") ; + if(sctrl) + { + sctrl->setValue(width) ; + } + + sctrl = LLViewerUICtrlFactory::getSpinnerByName(view, "snapshot_height") ; + if(sctrl) + { + sctrl->setValue(height) ; + } + + w = width ; + h = height ; + + gSavedSettings.setS32("LastSnapshotWidth", w); + gSavedSettings.setS32("LastSnapshotHeight", h); + } + previewp->setSize(w,h); checkAutoSnapshot(previewp); comboSetCustom(view, "postcard_size_combo"); @@ -1242,8 +1575,8 @@ LLFloaterSnapshot::~LLFloaterSnapshot() { if (sInstance == this) { - delete LLView::getViewByHandle(Impl::sPreviewHandle); - Impl::sPreviewHandle = LLViewHandle::sDeadHandle; + LLView::deleteViewByHandle(Impl::sPreviewHandle); + Impl::sPreviewHandle = LLHandle(); sInstance = NULL; } @@ -1269,7 +1602,12 @@ BOOL LLFloaterSnapshot::postBuild() childSetValue("auto_snapshot_check", gSavedSettings.getBOOL("AutoSnapshot")); childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this); - + + //childSetValue("advance_snapshot_check", gSavedSettings.getBOOL("AdvanceSnapshot")); + //childSetCommitCallback("advance_snapshot_check", Impl::onClickAdvanceSnap, this); + childSetAction("more_btn", Impl::onClickMore, this); + childSetAction("less_btn", Impl::onClickLess, this); + childSetAction("upload_btn", Impl::onClickKeep, this); childSetAction("send_btn", Impl::onClickKeep, this); childSetAction("save_btn", Impl::onClickKeep, this); @@ -1315,7 +1653,7 @@ BOOL LLFloaterSnapshot::postBuild() sInstance->getRootView()->addChild(previewp); sInstance->getRootView()->addChild(gSnapshotFloaterView); - Impl::sPreviewHandle = previewp->mViewHandle; + Impl::sPreviewHandle = previewp->getHandle(); impl.updateControls(this); @@ -1332,7 +1670,7 @@ void LLFloaterSnapshot::draw() return; } - if(getVisible() && !mMinimized) + if(getVisible() && !isMinimized()) { if (previewp && previewp->getDataSize() > 0) { @@ -1354,12 +1692,12 @@ void LLFloaterSnapshot::draw() if (previewp->getSnapshotUpToDate()) { LLString bytes_string; - gResMgr->getIntegerString(bytes_string, previewp->getDataSize()); + gResMgr->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 ); childSetTextArg("file_size_label", "[SIZE]", bytes_string); } else { - childSetTextArg("file_size_label", "[SIZE]", childGetText("unknwon")); + childSetTextArg("file_size_label", "[SIZE]", getString("unknown")); childSetColor("file_size_label", gColors.getColor( "LabelTextColor" )); } childSetEnabled("upload_btn", previewp->getSnapshotUpToDate()); @@ -1382,11 +1720,11 @@ void LLFloaterSnapshot::draw() LLFloater::draw(); // draw snapshot thumbnail if not in fullscreen preview mode - if (!gSavedSettings.getBOOL("UseFreezeFrame") && previewp && previewp->getCurrentImage() && previewp->getSnapshotUpToDate()) + if (/*!gSavedSettings.getBOOL("UseFreezeFrame") &&*/ previewp && previewp->getCurrentImage() && previewp->getSnapshotUpToDate()) { F32 aspect = previewp->getImageAspect(); // UI size for thumbnail - S32 max_width = mRect.getWidth() - 20; + S32 max_width = getRect().getWidth() - 20; S32 max_height = 90; S32 img_render_width = 0; @@ -1414,7 +1752,7 @@ void LLFloaterSnapshot::draw() glScalef(llmin(1.f, (F32)image_width / (F32)previewp->getCurrentImage()->getWidth()), llmin(1.f, (F32)image_height / (F32)previewp->getCurrentImage()->getHeight()), 1.f); } glMatrixMode(GL_MODELVIEW); - gl_draw_scaled_image((mRect.getWidth() - img_render_width) / 2, 35 + (max_height - img_render_height) / 2, img_render_width, img_render_height, previewp->getCurrentImage(), LLColor4::white); + gl_draw_scaled_image((getRect().getWidth() - img_render_width) / 2, getRect().getHeight() - 205 + (max_height - img_render_height) / 2, img_render_width, img_render_height, previewp->getCurrentImage(), LLColor4::white); } glMatrixMode(GL_TEXTURE); glPopMatrix(); diff --git a/linden/indra/newview/llfloatertelehub.h b/linden/indra/newview/llfloatertelehub.h index 302868b..c93ef90 100644 --- a/linden/indra/newview/llfloatertelehub.h +++ b/linden/indra/newview/llfloatertelehub.h @@ -75,7 +75,7 @@ private: S32 mNumSpawn; LLVector3 mSpawnPointPos[MAX_SPAWNPOINTS_PER_TELEHUB]; - LLHandle mObjectSelection; + LLSafeHandle mObjectSelection; static LLFloaterTelehub* sInstance; }; diff --git a/linden/indra/newview/llfloatertest.cpp b/linden/indra/newview/llfloatertest.cpp index 584622b..2346e3e 100644 --- a/linden/indra/newview/llfloatertest.cpp +++ b/linden/indra/newview/llfloatertest.cpp @@ -63,7 +63,6 @@ public: private: static void onClickButton(void*); static void onClickText(void*); - static void onCloseTab(void*); static void onClickTab(void*, bool); static void onCommitCheck(LLUICtrl*, void*); static void onCommitCombo(LLUICtrl*, void*); @@ -155,9 +154,8 @@ LLFloaterTestImpl::LLFloaterTestImpl() tab = new LLTabContainer("test_tab", LLRect(LEFT, y, RIGHT, BOTTOM), LLTabContainer::TOP, - onCloseTab, this, - "Tab Title", - TRUE); // bordered + TRUE, // bordered + FALSE); // horizontal addChild(tab); mTab = tab; @@ -322,12 +320,6 @@ void LLFloaterTestImpl::onClickText(void*) } // static -void LLFloaterTestImpl::onCloseTab(void*) -{ - llinfos << "close tab" << llendl; -} - -// static void LLFloaterTestImpl::onClickTab(void*, bool) { llinfos << "click tab" << llendl; diff --git a/linden/indra/newview/llfloatertools.cpp b/linden/indra/newview/llfloatertools.cpp index 6764ffe..ba4ff50 100644 --- a/linden/indra/newview/llfloatertools.cpp +++ b/linden/indra/newview/llfloatertools.cpp @@ -181,7 +181,7 @@ BOOL LLFloaterTools::postBuild() // make sounds on visibility changes. setSoundFlags(LLView::SILENT); - mDragHandle->setEnabled( !gSavedSettings.getBOOL("ToolboxAutoMove") ); + getDragHandle()->setEnabled( !gSavedSettings.getBOOL("ToolboxAutoMove") ); LLRect rect; mBtnFocus = LLUICtrlFactory::getButtonByName(this,"button focus");//btn; @@ -317,14 +317,14 @@ BOOL LLFloaterTools::postBuild() mTab->selectFirstTab(); } - mStatusText["rotate"] = childGetText("status_rotate"); - mStatusText["scale"] = childGetText("status_scale"); - mStatusText["move"] = childGetText("status_move"); - mStatusText["modifyland"] = childGetText("status_modifyland"); - mStatusText["camera"] = childGetText("status_camera"); - mStatusText["grab"] = childGetText("status_grab"); - mStatusText["place"] = childGetText("status_place"); - mStatusText["selectland"] = childGetText("status_selectland"); + mStatusText["rotate"] = getString("status_rotate"); + mStatusText["scale"] = getString("status_scale"); + mStatusText["move"] = getString("status_move"); + mStatusText["modifyland"] = getString("status_modifyland"); + mStatusText["camera"] = getString("status_camera"); + mStatusText["grab"] = getString("status_grab"); + mStatusText["place"] = getString("status_place"); + mStatusText["selectland"] = getString("status_selectland"); return TRUE; } @@ -396,7 +396,7 @@ LLFloaterTools::LLFloaterTools() mTabLand(NULL), mDirty(TRUE) { - mAutoFocus = FALSE; + setAutoFocus(FALSE); LLCallbackMap::map_t factory_map; factory_map["General"] = LLCallbackMap(createPanelPermissions, this);//LLPanelPermissions factory_map["Object"] = LLCallbackMap(createPanelObject, this);//LLPanelObject @@ -442,7 +442,7 @@ void LLFloaterTools::setStatusText(const std::string& text) void LLFloaterTools::refresh() { - const S32 INFO_WIDTH = mRect.getWidth(); + const S32 INFO_WIDTH = getRect().getWidth(); const S32 INFO_HEIGHT = 384; LLRect object_info_rect(0, 0, INFO_WIDTH, -INFO_HEIGHT); BOOL all_volume = gSelectMgr->selectionAllPCode( LL_PCODE_VOLUME ); @@ -611,19 +611,19 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) switch (mObjectSelection->getSelectType()) { case SELECT_TYPE_HUD: - mComboGridMode->add(childGetText("grid_screen_text")); - mComboGridMode->add(childGetText("grid_local_text")); - //mComboGridMode->add(childGetText("grid_reference_text")); + mComboGridMode->add(getString("grid_screen_text")); + mComboGridMode->add(getString("grid_local_text")); + //mComboGridMode->add(getString("grid_reference_text")); break; case SELECT_TYPE_WORLD: - mComboGridMode->add(childGetText("grid_world_text")); - mComboGridMode->add(childGetText("grid_local_text")); - mComboGridMode->add(childGetText("grid_reference_text")); + mComboGridMode->add(getString("grid_world_text")); + mComboGridMode->add(getString("grid_local_text")); + mComboGridMode->add(getString("grid_reference_text")); break; case SELECT_TYPE_ATTACHMENT: - mComboGridMode->add(childGetText("grid_attachment_text")); - mComboGridMode->add(childGetText("grid_local_text")); - mComboGridMode->add(childGetText("grid_reference_text")); + mComboGridMode->add(getString("grid_attachment_text")); + mComboGridMode->add(getString("grid_local_text")); + mComboGridMode->add(getString("grid_reference_text")); break; } @@ -805,12 +805,12 @@ void LLFloaterTools::showMore(BOOL show_more) if (show_more) { - reshape( mRect.getWidth(), mLargeHeight, TRUE); + reshape( getRect().getWidth(), mLargeHeight, TRUE); translate( 0, mSmallHeight - mLargeHeight ); } else { - reshape( mRect.getWidth(), mSmallHeight, TRUE); + reshape( getRect().getWidth(), mSmallHeight, TRUE); translate( 0, mLargeHeight - mSmallHeight ); } childSetVisible("button less", show_more); diff --git a/linden/indra/newview/llfloatertools.h b/linden/indra/newview/llfloatertools.h index 38151f4..b0a804b 100644 --- a/linden/indra/newview/llfloatertools.h +++ b/linden/indra/newview/llfloatertools.h @@ -34,6 +34,7 @@ #include "llfloater.h" #include "llcoord.h" +#include "llparcelselection.h" class LLButton; class LLTextBox; @@ -50,8 +51,7 @@ class LLComboBox; class LLParcelSelection; class LLObjectSelection; -typedef LLHandle LLParcelSelectionHandle; -typedef LLHandle LLObjectSelectionHandle; +typedef LLSafeHandle LLObjectSelectionHandle; class LLFloaterTools : public LLFloater @@ -174,7 +174,7 @@ public: std::vector mButtons;//[ 15 ]; - LLTabContainerCommon *mTab; + LLTabContainer *mTab; LLPanelPermissions *mPanelPermissions; LLPanelObject *mPanelObject; LLPanelVolume *mPanelVolume; diff --git a/linden/indra/newview/llfloatertopobjects.cpp b/linden/indra/newview/llfloatertopobjects.cpp index 631c92d..04f00bd 100644 --- a/linden/indra/newview/llfloatertopobjects.cpp +++ b/linden/indra/newview/llfloatertopobjects.cpp @@ -207,7 +207,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) LLSD element; element["id"] = LLUUID::null; element["columns"][0]["column"] = "name"; - element["columns"][0]["value"] = childGetText("none_descriptor"); + element["columns"][0]["value"] = getString("none_descriptor"); element["columns"][0]["font"] = "SANSSERIF"; list->addElement(element); @@ -219,19 +219,19 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS) { - setTitle(childGetText("top_scripts_title")); - list->setColumnLabel("score", childGetText("scripts_score_label")); + setTitle(getString("top_scripts_title")); + list->setColumnLabel("score", getString("scripts_score_label")); - LLUIString format = childGetText("top_scripts_text"); + LLUIString format = getString("top_scripts_text"); format.setArg("[COUNT]", llformat("%d", total_count)); format.setArg("[TIME]", llformat("%0.1f", mtotalScore)); childSetValue("title_text", LLSD(format)); } else { - setTitle(childGetText("top_colliders_title")); - list->setColumnLabel("score", childGetText("colliders_score_label")); - LLUIString format = childGetText("top_colliders_text"); + setTitle(getString("top_colliders_title")); + list->setColumnLabel("score", getString("colliders_score_label")); + LLUIString format = getString("top_colliders_text"); format.setArg("[COUNT]", llformat("%d", total_count)); childSetValue("title_text", LLSD(format)); } diff --git a/linden/indra/newview/llfloatertos.cpp b/linden/indra/newview/llfloatertos.cpp index fd069c9..c64173e 100644 --- a/linden/indra/newview/llfloatertos.cpp +++ b/linden/indra/newview/llfloatertos.cpp @@ -145,7 +145,6 @@ BOOL LLFloaterTOS::postBuild() return TRUE; } -#if LL_LIBXUL_ENABLED // disable Agree to TOS radio button until the page has fully loaded LLRadioGroup* tos_agreement = LLUICtrlFactory::getRadioGroupByName(this, "tos_agreement"); if ( tos_agreement ) @@ -160,7 +159,7 @@ BOOL LLFloaterTOS::postBuild() editor->setVisible( FALSE ); }; - LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "tos_html"); + LLWebBrowserCtrl* web_browser = getChild("tos_html"); if ( web_browser ) { // start to observe it so we see navigate complete events @@ -170,20 +169,8 @@ BOOL LLFloaterTOS::postBuild() }; gResponsePtr = LLIamHere::build( this ); - LLHTTPClient::get( childGetValue( "real_url" ).asString(), gResponsePtr ); + LLHTTPClient::get( getString( "real_url" ), gResponsePtr ); }; -#else - LLTextEditor *Editor = LLUICtrlFactory::getTextEditorByName(this, "tos_text"); - if (Editor) - { - Editor->setHandleEditKeysDirectly( TRUE ); - Editor->setEnabled( FALSE ); - Editor->setReadOnlyFgColor(LLColor4::white); - Editor->setWordWrap(TRUE); - Editor->setFocus(TRUE); - } - childSetValue("tos_text", LLSD(mMessage)); -#endif return TRUE; } @@ -193,15 +180,14 @@ void LLFloaterTOS::setSiteIsAlive( bool alive ) // only do this for TOS pages if ( mType == TOS_TOS ) { -#if LL_LIBXUL_ENABLED - LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "tos_html"); + LLWebBrowserCtrl* web_browser = getChild("tos_html"); // if the contents of the site was retrieved if ( alive ) { if ( web_browser ) { // navigate to the "real" page - web_browser->navigateTo( childGetValue( "real_url" ).asString() ); + web_browser->navigateTo( getString( "real_url" ) ); }; } else @@ -220,20 +206,17 @@ void LLFloaterTOS::setSiteIsAlive( bool alive ) web_browser->setVisible( FALSE ); }; }; -#endif // LL_LIBXUL_ENABLED }; } LLFloaterTOS::~LLFloaterTOS() { -#if LL_LIBXUL_ENABLED // stop obsaerving events - LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "tos_html"); + LLWebBrowserCtrl* web_browser = getChild("tos_html"); if ( web_browser ) { web_browser->addObserver( this ); }; -#endif // LL_LIBXUL_ENABLED // tell the responder we're not here anymore if ( gResponsePtr ) diff --git a/linden/indra/newview/llfloaterurldisplay.h b/linden/indra/newview/llfloaterurldisplay.h index e603c17..dce9c75 100644 --- a/linden/indra/newview/llfloaterurldisplay.h +++ b/linden/indra/newview/llfloaterurldisplay.h @@ -39,7 +39,7 @@ class LLPanelPlace; class LLSD; class LLUUID; -class LLFloaterURLDisplay : public LLFloater, public LLUISingleton +class LLFloaterURLDisplay : public LLFloater, public LLFloaterSingleton { public: LLFloaterURLDisplay(const LLSD& sd); diff --git a/linden/indra/newview/llfloaterurlentry.cpp b/linden/indra/newview/llfloaterurlentry.cpp new file mode 100644 index 0000000..b2cc37f --- /dev/null +++ b/linden/indra/newview/llfloaterurlentry.cpp @@ -0,0 +1,293 @@ +/** + * @file llfloaterurlentry.cpp + * @brief LLFloaterURLEntry class implementation + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterurlentry.h" + +#include "llpanellandmedia.h" + +// project includes +#include "llcombobox.h" +#include "llurlhistory.h" +#include "llvieweruictrlfactory.h" +#include "llwindow.h" +#include "llviewerwindow.h" + +static LLFloaterURLEntry* sInstance = NULL; + +// Move this to its own file. +// helper class that tries to download a URL from a web site and calls a method +// on the Panel Land Media and to discover the MIME type +class LLMediaTypeResponder : public LLHTTPClient::Responder +{ +public: + LLMediaTypeResponder( const LLHandle parent ) : + mParent( parent ) + {} + + LLHandle mParent; + + + virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content) + { + std::string media_type = content["content-type"].asString(); + std::string::size_type idx1 = media_type.find_first_of(";"); + std::string mime_type = media_type.substr(0, idx1); + completeAny(status, mime_type); + } + + virtual void error( U32 status, const std::string& reason ) + { + completeAny(status, "none/none"); + } + + void completeAny(U32 status, const std::string& mime_type) + { + // Set empty type to none/none. Empty string is reserved for legacy parcels + // which have no mime type set. + std::string resolved_mime_type = ! mime_type.empty() ? mime_type : "none/none"; + LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mParent.get(); + if ( floater_url_entry ) + floater_url_entry->headerFetchComplete( status, resolved_mime_type ); + } +}; + +//----------------------------------------------------------------------------- +// LLFloaterURLEntry() +//----------------------------------------------------------------------------- +LLFloaterURLEntry::LLFloaterURLEntry(LLHandle parent) + : + LLFloater(), + mPanelLandMediaHandle(parent) +{ + gUICtrlFactory->buildFloater(this, "floater_url_entry.xml"); + + mMediaURLEdit = LLUICtrlFactory::getComboBoxByName(this, "media_entry"); + + // Cancel button + childSetAction("cancel_btn", onBtnCancel, this); + + // Cancel button + childSetAction("clear_btn", onBtnClear, this); + + // clear media list button + LLSD parcel_history = LLURLHistory::getURLHistory("parcel"); + bool enable_clear_button = parcel_history.size() > 0 ? true : false; + childSetEnabled( "clear_btn", enable_clear_button ); + + // OK button + childSetAction("ok_btn", onBtnOK, this); + + setDefaultBtn("ok_btn"); + buildURLHistory(); + + sInstance = this; +} + +//----------------------------------------------------------------------------- +// ~LLFloaterURLEntry() +//----------------------------------------------------------------------------- +LLFloaterURLEntry::~LLFloaterURLEntry() +{ + sInstance = NULL; +} + +void LLFloaterURLEntry::buildURLHistory() +{ + LLCtrlListInterface* url_list = childGetListInterface("media_entry"); + if (url_list) + { + url_list->operateOnAll(LLCtrlListInterface::OP_DELETE); + } + + // Get all of the entries in the "parcel" collection + LLSD parcel_history = LLURLHistory::getURLHistory("parcel"); + + LLSD::array_iterator iter_history = + parcel_history.beginArray(); + LLSD::array_iterator end_history = + parcel_history.endArray(); + for(; iter_history != end_history; ++iter_history) + { + url_list->addSimpleElement((*iter_history).asString()); + } +} + +void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_type) +{ + LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get(); + if (panel_media) + { + // status is ignored for now -- error = "none/none" + panel_media->setMediaType(mime_type); + panel_media->setMediaURL(mMediaURLEdit->getValue().asString()); + } + // Decrement the cursor + getWindow()->decBusyCount(); + childSetVisible("loading_label", false); + close(); +} + +// static +LLHandle LLFloaterURLEntry::show(LLHandle parent) +{ + if (sInstance) + { + sInstance->open(); + } + else + { + sInstance = new LLFloaterURLEntry(parent); + } + sInstance->updateFromLandMediaPanel(); + return sInstance->getHandle(); +} + +void LLFloaterURLEntry::updateFromLandMediaPanel() +{ + LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get(); + if (panel_media) + { + std::string media_url = panel_media->getMediaURL(); + addURLToCombobox(media_url); + } +} + +bool LLFloaterURLEntry::addURLToCombobox(const std::string& media_url) +{ + if(! mMediaURLEdit->setSimple( media_url ) && ! media_url.empty()) + { + mMediaURLEdit->add( media_url ); + mMediaURLEdit->setSimple( media_url ); + return true; + } + + // URL was not added for whatever reason (either it was empty or already existed) + return false; +} + +// static +//----------------------------------------------------------------------------- +// onBtnOK() +//----------------------------------------------------------------------------- +void LLFloaterURLEntry::onBtnOK( void* userdata ) +{ + LLFloaterURLEntry *self =(LLFloaterURLEntry *)userdata; + + std::string media_url = self->mMediaURLEdit->getValue().asString(); + self->mMediaURLEdit->remove(media_url); + LLURLHistory::removeURL("parcel", media_url); + if(self->addURLToCombobox(media_url)) + { + // Add this url to the parcel collection + LLURLHistory::addURL("parcel", media_url); + } + + // leading whitespace causes problems with the MIME-type detection so strip it + LLString::trim( media_url ); + + // First check the URL scheme + LLURI url(media_url); + std::string scheme = url.scheme(); + + // We assume that an empty scheme is an http url, as this is how we will treat it. + if(scheme == "") + { + scheme = "http"; + } + + // Discover the MIME type only for "http" scheme. + if(scheme == "http") + { + LLHTTPClient::getHeaderOnly( media_url, + new LLMediaTypeResponder(self->getHandle())); + } + else + { + self->headerFetchComplete(0, scheme); + } + + // Grey the buttons until we get the header response + self->childSetEnabled("ok_btn", false); + self->childSetEnabled("cancel_btn", false); + self->childSetEnabled("media_entry", false); + + // show progress bar here? + getWindow()->incBusyCount(); + self->childSetVisible("loading_label", true); +} + +// static +//----------------------------------------------------------------------------- +// onBtnCancel() +//----------------------------------------------------------------------------- +void LLFloaterURLEntry::onBtnCancel( void* userdata ) +{ + LLFloaterURLEntry *self =(LLFloaterURLEntry *)userdata; + self->close(); +} + +// static +//----------------------------------------------------------------------------- +// onBtnClear() +//----------------------------------------------------------------------------- +void LLFloaterURLEntry::onBtnClear( void* userdata ) +{ + gViewerWindow->alertXml( "ConfirmClearMediaUrlList", callback_clear_url_list, userdata ); +} + +void LLFloaterURLEntry::callback_clear_url_list(S32 option, void* userdata) +{ + if ( option == 0 ) // YES + { + LLFloaterURLEntry *self =(LLFloaterURLEntry *)userdata; + + if ( self ) + { + // clear saved list + LLCtrlListInterface* url_list = self->childGetListInterface("media_entry"); + if ( url_list ) + { + url_list->operateOnAll( LLCtrlListInterface::OP_DELETE ); + } + + // clear current contents of combo box + self->mMediaURLEdit->clear(); + + // clear stored version of list + LLURLHistory::clear("parcel"); + + // cleared the list so disable Clear button + self->childSetEnabled( "clear_btn", false ); + } + } +} diff --git a/linden/indra/newview/llfloaterurlentry.h b/linden/indra/newview/llfloaterurlentry.h new file mode 100644 index 0000000..069b69f --- /dev/null +++ b/linden/indra/newview/llfloaterurlentry.h @@ -0,0 +1,69 @@ +/** + * @file llfloaternamedesc.h + * @brief LLFloaterNameDesc class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERURLENTRY_H +#define LL_LLFLOATERURLENTRY_H + +#include "llfloater.h" +#include "llpanellandmedia.h" + +class LLLineEditor; +class LLComboBox; + +class LLFloaterURLEntry : public LLFloater +{ +public: + // Can only be shown by LLPanelLandMedia, and pushes data back into + // that panel via the handle. + static LLHandle show(LLHandle panel_land_media_handle); + + void updateFromLandMediaPanel(); + + void headerFetchComplete(U32 status, const std::string& mime_type); + + bool addURLToCombobox(const std::string& media_url); + +private: + LLFloaterURLEntry(LLHandle parent); + /*virtual*/ ~LLFloaterURLEntry(); + void buildURLHistory(); + +private: + LLComboBox* mMediaURLEdit; + LLHandle mPanelLandMediaHandle; + + static void onBtnOK(void*); + static void onBtnCancel(void*); + static void onBtnClear(void*); + static void callback_clear_url_list(S32 option, void* userdata); +}; + +#endif // LL_LLFLOATERURLENTRY_H diff --git a/linden/indra/newview/llfloatervoicewizard.cpp b/linden/indra/newview/llfloatervoicewizard.cpp index 65601ff..94063a0 100644 --- a/linden/indra/newview/llfloatervoicewizard.cpp +++ b/linden/indra/newview/llfloatervoicewizard.cpp @@ -83,7 +83,7 @@ void LLFloaterVoiceWizard::draw() mDevicePanel->refresh(); } - LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName(this, "wizard_tabs"); + LLTabContainer* tabs = LLUICtrlFactory::getTabContainerByName(this, "wizard_tabs"); if (tabs) { @@ -156,7 +156,7 @@ void LLFloaterVoiceWizard::onClose(bool app_quitting) // static void LLFloaterVoiceWizard::onClickNext(void *user_data) { - LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName((LLFloater*)user_data, "wizard_tabs"); + LLTabContainer* tabs = LLUICtrlFactory::getTabContainerByName((LLFloater*)user_data, "wizard_tabs"); if (tabs) { tabs->selectNextTab(); @@ -166,7 +166,7 @@ void LLFloaterVoiceWizard::onClickNext(void *user_data) // static void LLFloaterVoiceWizard::onClickBack(void *user_data) { - LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName((LLFloater*)user_data, "wizard_tabs"); + LLTabContainer* tabs = LLUICtrlFactory::getTabContainerByName((LLFloater*)user_data, "wizard_tabs"); if (tabs) { tabs->selectPrevTab(); @@ -364,7 +364,7 @@ void LLPanelDeviceSettings::refresh() if(mCtrlInputDevices) { mCtrlInputDevices->removeall(); - mCtrlInputDevices->add( childGetText("default_text"), ADD_BOTTOM ); + mCtrlInputDevices->add( getString("default_text"), ADD_BOTTOM ); devices = gVoiceClient->getCaptureDevices(); for(iter=devices->begin(); iter != devices->end(); iter++) @@ -374,14 +374,14 @@ void LLPanelDeviceSettings::refresh() if(!mCtrlInputDevices->setSimple(mInputDevice)) { - mCtrlInputDevices->setSimple(childGetText("default_text")); + mCtrlInputDevices->setSimple(getString("default_text")); } } if(mCtrlOutputDevices) { mCtrlOutputDevices->removeall(); - mCtrlOutputDevices->add( childGetText("default_text"), ADD_BOTTOM ); + mCtrlOutputDevices->add( getString("default_text"), ADD_BOTTOM ); devices = gVoiceClient->getRenderDevices(); for(iter=devices->begin(); iter != devices->end(); iter++) @@ -391,7 +391,7 @@ void LLPanelDeviceSettings::refresh() if(!mCtrlOutputDevices->setSimple(mOutputDevice)) { - mCtrlOutputDevices->setSimple(childGetText("default_text")); + mCtrlOutputDevices->setSimple(getString("default_text")); } } mDevicesUpdated = TRUE; diff --git a/linden/indra/newview/llfloatervoicewizard.h b/linden/indra/newview/llfloatervoicewizard.h index 9b1a1a0..a70677d 100644 --- a/linden/indra/newview/llfloatervoicewizard.h +++ b/linden/indra/newview/llfloatervoicewizard.h @@ -39,7 +39,7 @@ class LLPrefsVoiceLogic; class LLPanelDeviceSettings; class LLFloaterVoiceWizard -: public LLFloater, public LLUISingleton + : public LLFloater, public LLFloaterSingleton { public: LLFloaterVoiceWizard(const LLSD& seed); @@ -84,12 +84,12 @@ protected: F32 mMicVolume; std::string mInputDevice; std::string mOutputDevice; - LLComboBox *mCtrlInputDevices; - LLComboBox *mCtrlOutputDevices; + class LLComboBox *mCtrlInputDevices; + class LLComboBox *mCtrlOutputDevices; BOOL mDevicesUpdated; }; -class LLFloaterDeviceSettings : public LLFloater, public LLUISingleton +class LLFloaterDeviceSettings : public LLFloater, public LLFloaterSingleton { public: LLFloaterDeviceSettings(const LLSD& seed); diff --git a/linden/indra/newview/llfloaterwater.cpp b/linden/indra/newview/llfloaterwater.cpp new file mode 100644 index 0000000..c842a87 --- /dev/null +++ b/linden/indra/newview/llfloaterwater.cpp @@ -0,0 +1,735 @@ +/** + * @file llfloaterwater.cpp + * @brief LLFloaterWater class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterwater.h" + +#include "pipeline.h" +#include "llsky.h" + +#include "llsliderctrl.h" +#include "llspinctrl.h" +#include "llcolorswatch.h" +#include "llcheckboxctrl.h" +#include "lltexturectrl.h" +#include "llvieweruictrlfactory.h" +#include "llviewercamera.h" +#include "llcombobox.h" +#include "lllineeditor.h" +#include "llfloaterdaycycle.h" +#include "llboost.h" + +#include "v4math.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "llsavedsettingsglue.h" + +#include "llwaterparamset.h" +#include "llwaterparammanager.h" +#include "llpostprocess.h" + +#undef max + +LLFloaterWater* LLFloaterWater::sWaterMenu = NULL; + +std::set LLFloaterWater::sDefaultPresets; + +LLFloaterWater::LLFloaterWater() : LLFloater("water floater") +{ + gUICtrlFactory->buildFloater(this, "floater_water.xml"); + + // add the combo boxes + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(this, "WaterPresetsCombo"); + + if(comboBox != NULL) { + + std::map::iterator mIt = + LLWaterParamManager::instance()->mParamList.begin(); + for(; mIt != LLWaterParamManager::instance()->mParamList.end(); mIt++) + { + comboBox->add(mIt->first); + } + + // set defaults on combo boxes + comboBox->selectByValue(LLSD("Default")); + } + + LLString def_water = getString("WLDefaultWaterNames"); + + // no editing or deleting of the blank string + sDefaultPresets.insert(""); + boost_tokenizer tokens(def_water, boost::char_separator(":")); + for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) + { + LLString tok(*token_iter); + sDefaultPresets.insert(tok); + } + + // load it up + initCallbacks(); +} + +LLFloaterWater::~LLFloaterWater() +{ +} + +void LLFloaterWater::initCallbacks(void) { + + // help buttons + initHelpBtn("WaterFogColorHelp", "HelpWaterFogColor"); + initHelpBtn("WaterFogDensityHelp", "HelpWaterFogDensity"); + initHelpBtn("WaterUnderWaterFogModHelp", "HelpUnderWaterFogMod"); + initHelpBtn("WaterGlowHelp", "HelpWaterGlow"); + initHelpBtn("WaterNormalScaleHelp", "HelpWaterNormalScale"); + initHelpBtn("WaterFresnelScaleHelp", "HelpWaterFresnelScale"); + initHelpBtn("WaterFresnelOffsetHelp", "HelpWaterFresnelOffset"); + + initHelpBtn("WaterBlurMultiplierHelp", "HelpWaterBlurMultiplier"); + initHelpBtn("WaterScaleBelowHelp", "HelpWaterScaleBelow"); + initHelpBtn("WaterScaleAboveHelp", "HelpWaterScaleAbove"); + + initHelpBtn("WaterNormalMapHelp", "HelpWaterNormalMap"); + initHelpBtn("WaterWave1Help", "HelpWaterWave1"); + initHelpBtn("WaterWave2Help", "HelpWaterWave2"); + + LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + + childSetCommitCallback("WaterFogColor", onWaterFogColorMoved, ¶m_mgr->mFogColor); + + // + childSetCommitCallback("WaterGlow", onColorControlAMoved, ¶m_mgr->mFogColor); + + // fog density + childSetCommitCallback("WaterFogDensity", onExpFloatControlMoved, ¶m_mgr->mFogDensity); + childSetCommitCallback("WaterUnderWaterFogMod", onFloatControlMoved, ¶m_mgr->mUnderWaterFogMod); + + // blue density + childSetCommitCallback("WaterNormalScaleX", onVector3ControlXMoved, ¶m_mgr->mNormalScale); + childSetCommitCallback("WaterNormalScaleY", onVector3ControlYMoved, ¶m_mgr->mNormalScale); + childSetCommitCallback("WaterNormalScaleZ", onVector3ControlZMoved, ¶m_mgr->mNormalScale); + + // fresnel + childSetCommitCallback("WaterFresnelScale", onFloatControlMoved, ¶m_mgr->mFresnelScale); + childSetCommitCallback("WaterFresnelOffset", onFloatControlMoved, ¶m_mgr->mFresnelOffset); + + // scale above/below + childSetCommitCallback("WaterScaleAbove", onFloatControlMoved, ¶m_mgr->mScaleAbove); + childSetCommitCallback("WaterScaleBelow", onFloatControlMoved, ¶m_mgr->mScaleBelow); + + // blur mult + childSetCommitCallback("WaterBlurMult", onFloatControlMoved, ¶m_mgr->mBlurMultiplier); + + // Load/save + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(this, "WaterPresetsCombo"); + + //childSetAction("WaterLoadPreset", onLoadPreset, comboBox); + childSetAction("WaterNewPreset", onNewPreset, comboBox); + childSetAction("WaterSavePreset", onSavePreset, comboBox); + childSetAction("WaterDeletePreset", onDeletePreset, comboBox); + + // wave direction + childSetCommitCallback("WaterWave1DirX", onVector2ControlXMoved, ¶m_mgr->mWave1Dir); + childSetCommitCallback("WaterWave1DirY", onVector2ControlYMoved, ¶m_mgr->mWave1Dir); + childSetCommitCallback("WaterWave2DirX", onVector2ControlXMoved, ¶m_mgr->mWave2Dir); + childSetCommitCallback("WaterWave2DirY", onVector2ControlYMoved, ¶m_mgr->mWave2Dir); + + comboBox->setCommitCallback(onChangePresetName); + + LLTextureCtrl* textCtrl = getChild("WaterNormalMap"); + textCtrl->setDefaultImageAssetID(LLUUID(gViewerArt.getString("water_normal.tga"))); + childSetCommitCallback("WaterNormalMap", onNormalMapPicked, NULL); +} + +void LLFloaterWater::onClickHelp(void* data) +{ + LLFloaterWater* self = LLFloaterWater::instance(); + + const char* xml_alert = (const char*) data; + LLAlertDialog* dialogp = gViewerWindow->alertXml(xml_alert); + if (dialogp) + { + LLFloater* root_floater = gFloaterView->getParentFloater(self); + if (root_floater) + { + root_floater->addDependentFloater(dialogp); + } + } +} + +void LLFloaterWater::initHelpBtn(const char* name, const char* xml_alert) +{ + childSetAction(name, onClickHelp, (void*)xml_alert); +} + +void LLFloaterWater::newPromptCallback(S32 option, const LLString& text, void* userData) +{ + if(text == "") + { + return; + } + + if(option == 0) { + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(sWaterMenu, + "WaterPresetsCombo"); + + LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + + // add the current parameters to the list + // see if it's there first + std::map::iterator mIt = + param_mgr->mParamList.find(text.c_str()); + + // if not there, add a new one + if(mIt == param_mgr->mParamList.end()) + { + param_mgr->addParamSet(text.c_str(), + param_mgr->mCurParams); + comboBox->add(text); + comboBox->sortByName(); + + comboBox->setSelectedByValue(text, true); + + param_mgr->savePreset(text); + + // otherwise, send a message to the user + } + else + { + gViewerWindow->alertXml("ExistsWaterPresetAlert"); + } + } +} + +void LLFloaterWater::syncMenu() +{ + bool err; + + LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + + LLWaterParamSet & current_params = param_mgr->mCurParams; + + // blue horizon + param_mgr->mFogColor = current_params.getVector4(param_mgr->mFogColor.mName, err); + + LLColor4 col = param_mgr->getFogColor(); + childSetValue("WaterGlow", col.mV[3]); + col.mV[3] = 1.0f; + LLColorSwatchCtrl* colCtrl = sWaterMenu->getChild("WaterFogColor"); + + colCtrl->set(col); + + // fog and wavelets + param_mgr->mFogDensity.mExp = + log(current_params.getFloat(param_mgr->mFogDensity.mName, err)) / + log(param_mgr->mFogDensity.mBase); + param_mgr->setDensitySliderValue(param_mgr->mFogDensity.mExp); + childSetValue("WaterFogDensity", param_mgr->mFogDensity.mExp); + + param_mgr->mUnderWaterFogMod.mX = + current_params.getFloat(param_mgr->mUnderWaterFogMod.mName, err); + childSetValue("WaterUnderWaterFogMod", param_mgr->mUnderWaterFogMod.mX); + + param_mgr->mNormalScale = current_params.getVector3(param_mgr->mNormalScale.mName, err); + childSetValue("WaterNormalScaleX", param_mgr->mNormalScale.mX); + childSetValue("WaterNormalScaleY", param_mgr->mNormalScale.mY); + childSetValue("WaterNormalScaleZ", param_mgr->mNormalScale.mZ); + + // Fresnel + param_mgr->mFresnelScale.mX = current_params.getFloat(param_mgr->mFresnelScale.mName, err); + childSetValue("WaterFresnelScale", param_mgr->mFresnelScale.mX); + param_mgr->mFresnelOffset.mX = current_params.getFloat(param_mgr->mFresnelOffset.mName, err); + childSetValue("WaterFresnelOffset", param_mgr->mFresnelOffset.mX); + + // Scale Above/Below + param_mgr->mScaleAbove.mX = current_params.getFloat(param_mgr->mScaleAbove.mName, err); + childSetValue("WaterScaleAbove", param_mgr->mScaleAbove.mX); + param_mgr->mScaleBelow.mX = current_params.getFloat(param_mgr->mScaleBelow.mName, err); + childSetValue("WaterScaleBelow", param_mgr->mScaleBelow.mX); + + // blur mult + param_mgr->mBlurMultiplier.mX = current_params.getFloat(param_mgr->mBlurMultiplier.mName, err); + childSetValue("WaterBlurMult", param_mgr->mBlurMultiplier.mX); + + // wave directions + param_mgr->mWave1Dir = current_params.getVector2(param_mgr->mWave1Dir.mName, err); + childSetValue("WaterWave1DirX", param_mgr->mWave1Dir.mX); + childSetValue("WaterWave1DirY", param_mgr->mWave1Dir.mY); + + param_mgr->mWave2Dir = current_params.getVector2(param_mgr->mWave2Dir.mName, err); + childSetValue("WaterWave2DirX", param_mgr->mWave2Dir.mX); + childSetValue("WaterWave2DirY", param_mgr->mWave2Dir.mY); + + LLTextureCtrl* textCtrl = sWaterMenu->getChild("WaterNormalMap"); + textCtrl->setImageAssetID(param_mgr->getNormalMapID()); +} + + +// static +LLFloaterWater* LLFloaterWater::instance() +{ + if (!sWaterMenu) + { + sWaterMenu = new LLFloaterWater(); + sWaterMenu->open(); + sWaterMenu->setFocus(TRUE); + } + return sWaterMenu; +} +void LLFloaterWater::show() +{ + LLFloaterWater* water = instance(); + water->syncMenu(); + + // comment in if you want the menu to rebuild each time + //gUICtrlFactory->buildFloater(water, "floater_water.xml"); + //water->initCallbacks(); + + water->open(); +} + +bool LLFloaterWater::isOpen() +{ + if (sWaterMenu != NULL) { + return true; + } + return false; +} + +// virtual +void LLFloaterWater::onClose(bool app_quitting) +{ + if (sWaterMenu) + { + sWaterMenu->setVisible(FALSE); + } +} + +// vector control callbacks +void LLFloaterWater::onVector3ControlXMoved(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WaterVector3Control * vectorControl = static_cast(userData); + + vectorControl->mX = sldrCtrl->getValueF32(); + + vectorControl->update(LLWaterParamManager::instance()->mCurParams); + + LLWaterParamManager::instance()->propagateParameters(); +} + +// vector control callbacks +void LLFloaterWater::onVector3ControlYMoved(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WaterVector3Control * vectorControl = static_cast(userData); + + vectorControl->mY = sldrCtrl->getValueF32(); + + vectorControl->update(LLWaterParamManager::instance()->mCurParams); + + LLWaterParamManager::instance()->propagateParameters(); +} + +// vector control callbacks +void LLFloaterWater::onVector3ControlZMoved(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WaterVector3Control * vectorControl = static_cast(userData); + + vectorControl->mZ = sldrCtrl->getValueF32(); + + vectorControl->update(LLWaterParamManager::instance()->mCurParams); + + LLWaterParamManager::instance()->propagateParameters(); +} + + +// vector control callbacks +void LLFloaterWater::onVector2ControlXMoved(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WaterVector2Control * vectorControl = static_cast(userData); + + vectorControl->mX = sldrCtrl->getValueF32(); + + vectorControl->update(LLWaterParamManager::instance()->mCurParams); + + LLWaterParamManager::instance()->propagateParameters(); +} + +// vector control callbacks +void LLFloaterWater::onVector2ControlYMoved(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WaterVector2Control * vectorControl = static_cast(userData); + + vectorControl->mY = sldrCtrl->getValueF32(); + + vectorControl->update(LLWaterParamManager::instance()->mCurParams); + + LLWaterParamManager::instance()->propagateParameters(); +} + +// color control callbacks +void LLFloaterWater::onColorControlRMoved(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WaterColorControl * colorControl = static_cast(userData); + + colorControl->mR = sldrCtrl->getValueF32(); + + // move i if it's the max + if(colorControl->mR >= colorControl->mG + && colorControl->mR >= colorControl->mB + && colorControl->mHasSliderName) + { + colorControl->mI = colorControl->mR; + std::string name = colorControl->mSliderName; + name.append("I"); + + sWaterMenu->childSetValue(name, colorControl->mR); + } + + colorControl->update(LLWaterParamManager::instance()->mCurParams); + + LLWaterParamManager::instance()->propagateParameters(); +} + +void LLFloaterWater::onColorControlGMoved(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WaterColorControl * colorControl = static_cast(userData); + + colorControl->mG = sldrCtrl->getValueF32(); + + // move i if it's the max + if(colorControl->mG >= colorControl->mR + && colorControl->mG >= colorControl->mB + && colorControl->mHasSliderName) + { + colorControl->mI = colorControl->mG; + std::string name = colorControl->mSliderName; + name.append("I"); + + sWaterMenu->childSetValue(name, colorControl->mG); + + } + + colorControl->update(LLWaterParamManager::instance()->mCurParams); + + LLWaterParamManager::instance()->propagateParameters(); +} + +void LLFloaterWater::onColorControlBMoved(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WaterColorControl * colorControl = static_cast(userData); + + colorControl->mB = sldrCtrl->getValueF32(); + + // move i if it's the max + if(colorControl->mB >= colorControl->mR + && colorControl->mB >= colorControl->mG + && colorControl->mHasSliderName) + { + colorControl->mI = colorControl->mB; + std::string name = colorControl->mSliderName; + name.append("I"); + + sWaterMenu->childSetValue(name, colorControl->mB); + } + + colorControl->update(LLWaterParamManager::instance()->mCurParams); + + LLWaterParamManager::instance()->propagateParameters(); +} + +void LLFloaterWater::onColorControlAMoved(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WaterColorControl * colorControl = static_cast(userData); + + colorControl->mA = sldrCtrl->getValueF32(); + + colorControl->update(LLWaterParamManager::instance()->mCurParams); + + LLWaterParamManager::instance()->propagateParameters(); +} + + +void LLFloaterWater::onColorControlIMoved(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WaterColorControl * colorControl = static_cast(userData); + + colorControl->mI = sldrCtrl->getValueF32(); + + // only for sliders where we pass a name + if(colorControl->mHasSliderName) + { + // set it to the top + F32 maxVal = std::max(std::max(colorControl->mR, colorControl->mG), colorControl->mB); + F32 iVal; + + iVal = colorControl->mI; + + // get the names of the other sliders + std::string rName = colorControl->mSliderName; + rName.append("R"); + std::string gName = colorControl->mSliderName; + gName.append("G"); + std::string bName = colorControl->mSliderName; + bName.append("B"); + + // handle if at 0 + if(iVal == 0) + { + colorControl->mR = 0; + colorControl->mG = 0; + colorControl->mB = 0; + + // if all at the start + // set them all to the intensity + } + else if (maxVal == 0) + { + colorControl->mR = iVal; + colorControl->mG = iVal; + colorControl->mB = iVal; + } + else + { + // add delta amounts to each + F32 delta = (iVal - maxVal) / maxVal; + colorControl->mR *= (1.0f + delta); + colorControl->mG *= (1.0f + delta); + colorControl->mB *= (1.0f + delta); + } + + // set the sliders to the new vals + sWaterMenu->childSetValue(rName.c_str(), colorControl->mR); + sWaterMenu->childSetValue(gName.c_str(), colorControl->mG); + sWaterMenu->childSetValue(bName.c_str(), colorControl->mB); + } + + // now update the current parameters and send them to shaders + colorControl->update(LLWaterParamManager::instance()->mCurParams); + LLWaterParamManager::instance()->propagateParameters(); +} + +void LLFloaterWater::onExpFloatControlMoved(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WaterExpFloatControl * expFloatControl = static_cast(userData); + + F32 val = sldrCtrl->getValueF32(); + expFloatControl->mExp = val; + LLWaterParamManager::instance()->setDensitySliderValue(val); + + expFloatControl->update(LLWaterParamManager::instance()->mCurParams); + LLWaterParamManager::instance()->propagateParameters(); +} + +void LLFloaterWater::onFloatControlMoved(LLUICtrl* ctrl, void* userData) +{ + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WaterFloatControl * floatControl = static_cast(userData); + + floatControl->mX = sldrCtrl->getValueF32() / floatControl->mMult; + + floatControl->update(LLWaterParamManager::instance()->mCurParams); + LLWaterParamManager::instance()->propagateParameters(); +} +void LLFloaterWater::onWaterFogColorMoved(LLUICtrl* ctrl, void* userData) +{ + LLColorSwatchCtrl* swatch = static_cast(ctrl); + WaterColorControl * colorControl = static_cast(userData); + *colorControl = swatch->get(); + + colorControl->update(LLWaterParamManager::instance()->mCurParams); + LLWaterParamManager::instance()->propagateParameters(); +} + +void LLFloaterWater::onBoolToggle(LLUICtrl* ctrl, void* userData) +{ + LLCheckBoxCtrl* cbCtrl = static_cast(ctrl); + + bool value = cbCtrl->get(); + (*(static_cast(userData))) = value; +} + +void LLFloaterWater::onNormalMapPicked(LLUICtrl* ctrl, void* userData) +{ + LLTextureCtrl* textCtrl = static_cast(ctrl); + LLUUID textID = textCtrl->getImageAssetID(); + LLWaterParamManager::instance()->setNormalMapID(textID); +} + +void LLFloaterWater::onNewPreset(void* userData) +{ + gViewerWindow->alertXmlEditText("NewWaterPreset", LLString::format_map_t(), + NULL, NULL, newPromptCallback, NULL); +} + +void LLFloaterWater::onSavePreset(void* userData) +{ + // get the name + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(sWaterMenu, + "WaterPresetsCombo"); + + // don't save the empty name + if(comboBox->getSelectedItemLabel() == "") + { + return; + } + + LLWaterParamManager::instance()->mCurParams.mName = + comboBox->getSelectedItemLabel(); + + // check to see if it's a default and shouldn't be overwritten + std::set::iterator sIt = sDefaultPresets.find( + comboBox->getSelectedItemLabel().c_str()); + if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("WaterEditPresets")) + { + gViewerWindow->alertXml("WLNoEditDefault"); + return; + } + + gViewerWindow->alertXml("WLSavePresetAlert", saveAlertCallback, sWaterMenu); +} + +void LLFloaterWater::saveAlertCallback(S32 option, void* userdata) +{ + // if they choose save, do it. Otherwise, don't do anything + if(option == 0) + { + LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + + param_mgr->setParamSet( + param_mgr->mCurParams.mName, + param_mgr->mCurParams); + + // comment this back in to save to file + param_mgr->savePreset(param_mgr->mCurParams.mName); + } + +} + +void LLFloaterWater::onDeletePreset(void* userData) +{ + LLComboBox* combo_box = LLUICtrlFactory::getComboBoxByName(sWaterMenu, + "WaterPresetsCombo"); + + if(combo_box->getSelectedValue().asString() == "") + { + return; + } + + LLString::format_map_t args; + args["[SKY]"] = combo_box->getSelectedValue().asString(); + gViewerWindow->alertXml("WLDeletePresetAlert", args, deleteAlertCallback, sWaterMenu); +} + +void LLFloaterWater::deleteAlertCallback(S32 option, void* userdata) +{ + // if they choose delete, do it. Otherwise, don't do anything + if(option == 0) + { + LLComboBox* combo_box = LLUICtrlFactory::getComboBoxByName(sWaterMenu, + "WaterPresetsCombo"); + LLFloaterDayCycle* day_cycle = NULL; + LLComboBox* key_combo = NULL; + LLMultiSliderCtrl* mult_sldr = NULL; + + if(LLFloaterDayCycle::isOpen()) + { + day_cycle = LLFloaterDayCycle::instance(); + key_combo = LLUICtrlFactory::getComboBoxByName(day_cycle, + "WaterKeyPresets"); + mult_sldr = LLUICtrlFactory::getMultiSliderByName(day_cycle, + "WaterDayCycleKeys"); + } + + LLString name = combo_box->getSelectedValue().asString(); + + // check to see if it's a default and shouldn't be deleted + std::set::iterator sIt = sDefaultPresets.find(name.c_str()); + if(sIt != sDefaultPresets.end()) + { + gViewerWindow->alertXml("WaterNoEditDefault"); + return; + } + + LLWaterParamManager::instance()->removeParamSet(name, true); + + // remove and choose another + S32 new_index = combo_box->getCurrentIndex(); + + combo_box->remove(name); + + if(key_combo != NULL) + { + key_combo->remove(name); + + // remove from slider, as well + day_cycle->deletePreset(name); + } + + // pick the previously selected index after delete + if(new_index > 0) + { + new_index--; + } + + if(combo_box->getItemCount() > 0) + { + combo_box->setCurrentByIndex(new_index); + } + } +} + + +void LLFloaterWater::onChangePresetName(LLUICtrl* ctrl, void * userData) +{ + LLComboBox * combo_box = static_cast(ctrl); + + if(combo_box->getSimple() == "") + { + return; + } + + LLWaterParamManager::instance()->loadPreset( + combo_box->getSelectedValue().asString()); + sWaterMenu->syncMenu(); +} + diff --git a/linden/indra/newview/llfloaterwater.h b/linden/indra/newview/llfloaterwater.h new file mode 100644 index 0000000..60d175e --- /dev/null +++ b/linden/indra/newview/llfloaterwater.h @@ -0,0 +1,133 @@ +/** + * @file llfloaterwindlight.h + * @brief LLFloaterWater class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* + * Menu for adjusting the atmospheric settings of the world + */ + +#ifndef LL_LLFLOATER_WATER_H +#define LL_LLFLOATER_WATER_H + +#include "llfloater.h" + +#include +#include "llwlparamset.h" + +struct WaterColorControl; +struct WaterloatControl; + + +/// Menuing system for all of windlight's functionality +class LLFloaterWater : public LLFloater +{ +public: + + LLFloaterWater(); + virtual ~LLFloaterWater(); + + /// initialize all + void initCallbacks(void); + + /// one and one instance only + static LLFloaterWater* instance(); + + // help button stuff + static void onClickHelp(void* data); + void initHelpBtn(const char* name, const char* xml_alert); + + static void newPromptCallback(S32 option, const LLString& text, void* userData); + + /// general purpose callbacks for dealing with color controllers + static void onColorControlRMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlGMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlBMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlAMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlIMoved(LLUICtrl* ctrl, void* userData); + + static void onVector3ControlXMoved(LLUICtrl* ctrl, void* userData); + static void onVector3ControlYMoved(LLUICtrl* ctrl, void* userData); + static void onVector3ControlZMoved(LLUICtrl* ctrl, void* userData); + + static void onVector2ControlXMoved(LLUICtrl* ctrl, void* userData); + static void onVector2ControlYMoved(LLUICtrl* ctrl, void* userData); + + static void onFloatControlMoved(LLUICtrl* ctrl, void* userData); + + static void onExpFloatControlMoved(LLUICtrl* ctrl, void* userData); + + static void onWaterFogColorMoved(LLUICtrl* ctrl, void* userData); + + static void onBoolToggle(LLUICtrl* ctrl, void* userData); + + /// handle if they choose a new normal map + static void onNormalMapPicked(LLUICtrl* ctrl, void* userData); + + /// when user hits the load preset button + static void onNewPreset(void* userData); + + /// when user hits the save preset button + static void onSavePreset(void* userData); + + /// prompts a user when overwriting a preset + static void saveAlertCallback(S32 option, void* userdata); + + /// when user hits the save preset button + static void onDeletePreset(void* userData); + + /// prompts a user when overwriting a preset + static void deleteAlertCallback(S32 option, void* userdata); + + /// what to do when you change the preset name + static void onChangePresetName(LLUICtrl* ctrl, void* userData); + + //// menu management + + /// show off our menu + static void show(); + + /// return if the menu exists or not + static bool isOpen(); + + /// stuff to do on exit + virtual void onClose(bool app_quitting); + + /// sync up sliders with parameters + void syncMenu(); + +private: + // one instance on the inside + static LLFloaterWater* sWaterMenu; + + static std::set sDefaultPresets; +}; + + +#endif diff --git a/linden/indra/newview/llfloaterwindlight.cpp b/linden/indra/newview/llfloaterwindlight.cpp new file mode 100644 index 0000000..2321f5d --- /dev/null +++ b/linden/indra/newview/llfloaterwindlight.cpp @@ -0,0 +1,998 @@ +/** + * @file llfloaterwindlight.cpp + * @brief LLFloaterWindLight class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterwindlight.h" + +#include "pipeline.h" +#include "llsky.h" + +#include "llsliderctrl.h" +#include "llmultislider.h" +#include "llmultisliderctrl.h" +#include "llspinctrl.h" +#include "llcheckboxctrl.h" +#include "llvieweruictrlfactory.h" +#include "llviewercamera.h" +#include "llcombobox.h" +#include "lllineeditor.h" +#include "llfloaterdaycycle.h" +#include "llboost.h" + +#include "v4math.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "llsavedsettingsglue.h" + +#include "llwlparamset.h" +#include "llwlparammanager.h" +#include "llpostprocess.h" + +#undef max + +LLFloaterWindLight* LLFloaterWindLight::sWindLight = NULL; + +std::set LLFloaterWindLight::sDefaultPresets; + +static const F32 WL_SUN_AMBIENT_SLIDER_SCALE = 3.0f; + +LLFloaterWindLight::LLFloaterWindLight() : LLFloater("windlight floater") +{ + gUICtrlFactory->buildFloater(this, "floater_windlight_options.xml"); + + // add the combo boxes + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(this, "WLPresetsCombo"); + + if(comboBox != NULL) { + + std::map::iterator mIt = + LLWLParamManager::instance()->mParamList.begin(); + for(; mIt != LLWLParamManager::instance()->mParamList.end(); mIt++) + { + comboBox->add(mIt->first); + } + + // entry for when we're in estate time + comboBox->add(""); + + // set defaults on combo boxes + comboBox->selectByValue(LLSD("Default")); + } + + // add the list of presets + LLString def_days = getString("WLDefaultSkyNames"); + + // no editing or deleting of the blank string + sDefaultPresets.insert(""); + boost_tokenizer tokens(def_days, boost::char_separator(":")); + for (boost_tokenizer::iterator token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) + { + LLString tok(*token_iter); + sDefaultPresets.insert(tok); + } + + // load it up + initCallbacks(); +} + +LLFloaterWindLight::~LLFloaterWindLight() +{ +} + +void LLFloaterWindLight::initCallbacks(void) { + + // help buttons + initHelpBtn("WLBlueHorizonHelp", "HelpBlueHorizon"); + initHelpBtn("WLHazeHorizonHelp", "HelpHazeHorizon"); + initHelpBtn("WLBlueDensityHelp", "HelpBlueDensity"); + initHelpBtn("WLHazeDensityHelp", "HelpHazeDensity"); + + initHelpBtn("WLDensityMultHelp", "HelpDensityMult"); + initHelpBtn("WLDistanceMultHelp", "HelpDistanceMult"); + initHelpBtn("WLMaxAltitudeHelp", "HelpMaxAltitude"); + + initHelpBtn("WLSunlightColorHelp", "HelpSunlightColor"); + initHelpBtn("WLAmbientHelp", "HelpSunAmbient"); + initHelpBtn("WLSunGlowHelp", "HelpSunGlow"); + initHelpBtn("WLTimeOfDayHelp", "HelpTimeOfDay"); + initHelpBtn("WLEastAngleHelp", "HelpEastAngle"); + + initHelpBtn("WLSceneGammaHelp", "HelpSceneGamma"); + initHelpBtn("WLStarBrightnessHelp", "HelpStarBrightness"); + + initHelpBtn("WLCloudColorHelp", "HelpCloudColor"); + initHelpBtn("WLCloudDetailHelp", "HelpCloudDetail"); + initHelpBtn("WLCloudDensityHelp", "HelpCloudDensity"); + initHelpBtn("WLCloudCoverageHelp", "HelpCloudCoverage"); + + initHelpBtn("WLCloudScaleHelp", "HelpCloudScale"); + initHelpBtn("WLCloudScrollXHelp", "HelpCloudScrollX"); + initHelpBtn("WLCloudScrollYHelp", "HelpCloudScrollY"); + + initHelpBtn("WLClassicCloudsHelp", "HelpClassicClouds"); + + LLWLParamManager * param_mgr = LLWLParamManager::instance(); + + // blue horizon + childSetCommitCallback("WLBlueHorizonR", onColorControlRMoved, ¶m_mgr->mBlueHorizon); + childSetCommitCallback("WLBlueHorizonG", onColorControlGMoved, ¶m_mgr->mBlueHorizon); + childSetCommitCallback("WLBlueHorizonB", onColorControlBMoved, ¶m_mgr->mBlueHorizon); + childSetCommitCallback("WLBlueHorizonI", onColorControlIMoved, ¶m_mgr->mBlueHorizon); + + // haze density, horizon, mult, and altitude + childSetCommitCallback("WLHazeDensity", onColorControlRMoved, ¶m_mgr->mHazeDensity); + childSetCommitCallback("WLHazeHorizon", onColorControlRMoved, ¶m_mgr->mHazeHorizon); + childSetCommitCallback("WLDensityMult", onFloatControlMoved, ¶m_mgr->mDensityMult); + childSetCommitCallback("WLMaxAltitude", onFloatControlMoved, ¶m_mgr->mMaxAlt); + + // blue density + childSetCommitCallback("WLBlueDensityR", onColorControlRMoved, ¶m_mgr->mBlueDensity); + childSetCommitCallback("WLBlueDensityG", onColorControlGMoved, ¶m_mgr->mBlueDensity); + childSetCommitCallback("WLBlueDensityB", onColorControlBMoved, ¶m_mgr->mBlueDensity); + childSetCommitCallback("WLBlueDensityI", onColorControlIMoved, ¶m_mgr->mBlueDensity); + + // Lighting + + // sunlight + childSetCommitCallback("WLSunlightR", onColorControlRMoved, ¶m_mgr->mSunlight); + childSetCommitCallback("WLSunlightG", onColorControlGMoved, ¶m_mgr->mSunlight); + childSetCommitCallback("WLSunlightB", onColorControlBMoved, ¶m_mgr->mSunlight); + childSetCommitCallback("WLSunlightI", onColorControlIMoved, ¶m_mgr->mSunlight); + + // glow + childSetCommitCallback("WLGlowR", onGlowRMoved, ¶m_mgr->mGlow); + childSetCommitCallback("WLGlowB", onGlowBMoved, ¶m_mgr->mGlow); + + // ambient + childSetCommitCallback("WLAmbientR", onColorControlRMoved, ¶m_mgr->mAmbient); + childSetCommitCallback("WLAmbientG", onColorControlGMoved, ¶m_mgr->mAmbient); + childSetCommitCallback("WLAmbientB", onColorControlBMoved, ¶m_mgr->mAmbient); + childSetCommitCallback("WLAmbientI", onColorControlIMoved, ¶m_mgr->mAmbient); + + // time of day + childSetCommitCallback("WLSunAngle", onSunMoved, ¶m_mgr->mLightnorm); + childSetCommitCallback("WLEastAngle", onSunMoved, ¶m_mgr->mLightnorm); + + // Clouds + + // Cloud Color + childSetCommitCallback("WLCloudColorR", onColorControlRMoved, ¶m_mgr->mCloudColor); + childSetCommitCallback("WLCloudColorG", onColorControlGMoved, ¶m_mgr->mCloudColor); + childSetCommitCallback("WLCloudColorB", onColorControlBMoved, ¶m_mgr->mCloudColor); + childSetCommitCallback("WLCloudColorI", onColorControlIMoved, ¶m_mgr->mCloudColor); + + // Cloud + childSetCommitCallback("WLCloudX", onColorControlRMoved, ¶m_mgr->mCloudMain); + childSetCommitCallback("WLCloudY", onColorControlGMoved, ¶m_mgr->mCloudMain); + childSetCommitCallback("WLCloudDensity", onColorControlBMoved, ¶m_mgr->mCloudMain); + + // Cloud Detail + childSetCommitCallback("WLCloudDetailX", onColorControlRMoved, ¶m_mgr->mCloudDetail); + childSetCommitCallback("WLCloudDetailY", onColorControlGMoved, ¶m_mgr->mCloudDetail); + childSetCommitCallback("WLCloudDetailDensity", onColorControlBMoved, ¶m_mgr->mCloudDetail); + + // Cloud extras + childSetCommitCallback("WLCloudCoverage", onFloatControlMoved, ¶m_mgr->mCloudCoverage); + childSetCommitCallback("WLCloudScale", onFloatControlMoved, ¶m_mgr->mCloudScale); + childSetCommitCallback("WLCloudLockX", onCloudScrollXToggled, NULL); + childSetCommitCallback("WLCloudLockY", onCloudScrollYToggled, NULL); + childSetCommitCallback("WLCloudScrollX", onCloudScrollXMoved, NULL); + childSetCommitCallback("WLCloudScrollY", onCloudScrollYMoved, NULL); + childSetCommitCallback("WLDistanceMult", onFloatControlMoved, ¶m_mgr->mDistanceMult); + childSetCommitCallback("DrawClassicClouds", LLSavedSettingsGlue::setBOOL, (void*)"SkyUseClassicClouds"); + + // WL Top + childSetAction("WLDayCycleMenuButton", onOpenDayCycle, NULL); + // Load/save + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(this, "WLPresetsCombo"); + + //childSetAction("WLLoadPreset", onLoadPreset, comboBox); + childSetAction("WLNewPreset", onNewPreset, comboBox); + childSetAction("WLSavePreset", onSavePreset, comboBox); + childSetAction("WLDeletePreset", onDeletePreset, comboBox); + + comboBox->setCommitCallback(onChangePresetName); + + + // Dome + childSetCommitCallback("WLGamma", onFloatControlMoved, ¶m_mgr->mWLGamma); + childSetCommitCallback("WLStarAlpha", onStarAlphaMoved, NULL); +} + +void LLFloaterWindLight::onClickHelp(void* data) +{ + LLFloaterWindLight* self = LLFloaterWindLight::instance(); + + const char* xml_alert = (const char*) data; + LLAlertDialog* dialogp = gViewerWindow->alertXml(xml_alert); + if (dialogp) + { + LLFloater* root_floater = gFloaterView->getParentFloater(self); + if (root_floater) + { + root_floater->addDependentFloater(dialogp); + } + } + +} + +void LLFloaterWindLight::initHelpBtn(const char* name, const char* xml_alert) +{ + childSetAction(name, onClickHelp, (void*)xml_alert); +} + +void LLFloaterWindLight::newPromptCallback(S32 option, const LLString& text, void* userData) +{ + if(text == "") + { + return; + } + + if(option == 0) { + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(sWindLight, + "WLPresetsCombo"); + + LLFloaterDayCycle* sDayCycle = NULL; + LLComboBox* keyCombo = NULL; + if(LLFloaterDayCycle::isOpen()) + { + sDayCycle = LLFloaterDayCycle::instance(); + keyCombo = LLUICtrlFactory::getComboBoxByName(sDayCycle, + "WLKeyPresets"); + } + + // add the current parameters to the list + // see if it's there first + std::map::iterator mIt = + LLWLParamManager::instance()->mParamList.find(text.c_str()); + + // if not there, add a new one + if(mIt == LLWLParamManager::instance()->mParamList.end()) + { + LLWLParamManager::instance()->addParamSet(text.c_str(), + LLWLParamManager::instance()->mCurParams); + comboBox->add(text); + comboBox->sortByName(); + + // add a blank to the bottom + comboBox->selectFirstItem(); + if(comboBox->getSimple() == "") + { + comboBox->remove(0); + } + comboBox->add(""); + + comboBox->setSelectedByValue(text, true); + if(LLFloaterDayCycle::isOpen()) + { + keyCombo->add(text); + keyCombo->sortByName(); + } + LLWLParamManager::instance()->savePreset(text); + + // otherwise, send a message to the user + } + else + { + gViewerWindow->alertXml("ExistsSkyPresetAlert"); + } + } +} + +void LLFloaterWindLight::syncMenu() +{ + bool err; + + LLWLParamManager * param_mgr = LLWLParamManager::instance(); + + LLWLParamSet& currentParams = param_mgr->mCurParams; + //std::map & currentParams = param_mgr->mCurParams.mParamValues; + + // blue horizon + param_mgr->mBlueHorizon = currentParams.getVector(param_mgr->mBlueHorizon.name, err); + childSetValue("WLBlueHorizonR", param_mgr->mBlueHorizon.r / 2.0); + childSetValue("WLBlueHorizonG", param_mgr->mBlueHorizon.g / 2.0); + childSetValue("WLBlueHorizonB", param_mgr->mBlueHorizon.b / 2.0); + childSetValue("WLBlueHorizonI", + std::max(param_mgr->mBlueHorizon.r / 2.0, + std::max(param_mgr->mBlueHorizon.g / 2.0, + param_mgr->mBlueHorizon.b / 2.0))); + + // haze density, horizon, mult, and altitude + param_mgr->mHazeDensity = currentParams.getVector(param_mgr->mHazeDensity.name, err); + childSetValue("WLHazeDensity", param_mgr->mHazeDensity.r); + param_mgr->mHazeHorizon = currentParams.getVector(param_mgr->mHazeHorizon.name, err); + childSetValue("WLHazeHorizon", param_mgr->mHazeHorizon.r); + param_mgr->mDensityMult = currentParams.getVector(param_mgr->mDensityMult.name, err); + childSetValue("WLDensityMult", param_mgr->mDensityMult.x * + param_mgr->mDensityMult.mult); + param_mgr->mMaxAlt = currentParams.getVector(param_mgr->mMaxAlt.name, err); + childSetValue("WLMaxAltitude", param_mgr->mMaxAlt.x); + + // blue density + param_mgr->mBlueDensity = currentParams.getVector(param_mgr->mBlueDensity.name, err); + childSetValue("WLBlueDensityR", param_mgr->mBlueDensity.r / 2.0); + childSetValue("WLBlueDensityG", param_mgr->mBlueDensity.g / 2.0); + childSetValue("WLBlueDensityB", param_mgr->mBlueDensity.b / 2.0); + childSetValue("WLBlueDensityI", + std::max(param_mgr->mBlueDensity.r / 2.0, + std::max(param_mgr->mBlueDensity.g / 2.0, param_mgr->mBlueDensity.b / 2.0))); + + // Lighting + + // sunlight + param_mgr->mSunlight = currentParams.getVector(param_mgr->mSunlight.name, err); + childSetValue("WLSunlightR", param_mgr->mSunlight.r / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLSunlightG", param_mgr->mSunlight.g / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLSunlightB", param_mgr->mSunlight.b / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLSunlightI", + std::max(param_mgr->mSunlight.r / WL_SUN_AMBIENT_SLIDER_SCALE, + std::max(param_mgr->mSunlight.g / WL_SUN_AMBIENT_SLIDER_SCALE, param_mgr->mSunlight.b / WL_SUN_AMBIENT_SLIDER_SCALE))); + + // glow + param_mgr->mGlow = currentParams.getVector(param_mgr->mGlow.name, err); + childSetValue("WLGlowR", 2 - param_mgr->mGlow.r / 20.0f); + childSetValue("WLGlowB", -param_mgr->mGlow.b / 5.0f); + + // ambient + param_mgr->mAmbient = currentParams.getVector(param_mgr->mAmbient.name, err); + childSetValue("WLAmbientR", param_mgr->mAmbient.r / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLAmbientG", param_mgr->mAmbient.g / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLAmbientB", param_mgr->mAmbient.b / WL_SUN_AMBIENT_SLIDER_SCALE); + childSetValue("WLAmbientI", + std::max(param_mgr->mAmbient.r / WL_SUN_AMBIENT_SLIDER_SCALE, + std::max(param_mgr->mAmbient.g / WL_SUN_AMBIENT_SLIDER_SCALE, param_mgr->mAmbient.b / WL_SUN_AMBIENT_SLIDER_SCALE))); + + childSetValue("WLSunAngle", param_mgr->mCurParams.getFloat("sun_angle",err) / F_TWO_PI); + childSetValue("WLEastAngle", param_mgr->mCurParams.getFloat("east_angle",err) / F_TWO_PI); + + // Clouds + + // Cloud Color + param_mgr->mCloudColor = currentParams.getVector(param_mgr->mCloudColor.name, err); + childSetValue("WLCloudColorR", param_mgr->mCloudColor.r); + childSetValue("WLCloudColorG", param_mgr->mCloudColor.g); + childSetValue("WLCloudColorB", param_mgr->mCloudColor.b); + childSetValue("WLCloudColorI", + std::max(param_mgr->mCloudColor.r, + std::max(param_mgr->mCloudColor.g, param_mgr->mCloudColor.b))); + + // Cloud + param_mgr->mCloudMain = currentParams.getVector(param_mgr->mCloudMain.name, err); + childSetValue("WLCloudX", param_mgr->mCloudMain.r); + childSetValue("WLCloudY", param_mgr->mCloudMain.g); + childSetValue("WLCloudDensity", param_mgr->mCloudMain.b); + + // Cloud Detail + param_mgr->mCloudDetail = currentParams.getVector(param_mgr->mCloudDetail.name, err); + childSetValue("WLCloudDetailX", param_mgr->mCloudDetail.r); + childSetValue("WLCloudDetailY", param_mgr->mCloudDetail.g); + childSetValue("WLCloudDetailDensity", param_mgr->mCloudDetail.b); + + // Cloud extras + param_mgr->mCloudCoverage = currentParams.getVector(param_mgr->mCloudCoverage.name, err); + param_mgr->mCloudScale = currentParams.getVector(param_mgr->mCloudScale.name, err); + childSetValue("WLCloudCoverage", param_mgr->mCloudCoverage.x); + childSetValue("WLCloudScale", param_mgr->mCloudScale.x); + + // cloud scrolling + bool lockX = !param_mgr->mCurParams.getEnableCloudScrollX(); + bool lockY = !param_mgr->mCurParams.getEnableCloudScrollY(); + childSetValue("WLCloudLockX", lockX); + childSetValue("WLCloudLockY", lockY); + childSetValue("DrawClassicClouds", gSavedSettings.getBOOL("SkyUseClassicClouds")); + + // disable if locked, enable if not + if(lockX) + { + childDisable("WLCloudScrollX"); + } else { + childEnable("WLCloudScrollX"); + } + if(lockY) + { + childDisable("WLCloudScrollY"); + } else { + childEnable("WLCloudScrollY"); + } + + // *HACK cloud scrolling is off my an additive of 10 + childSetValue("WLCloudScrollX", param_mgr->mCurParams.getCloudScrollX() - 10.0f); + childSetValue("WLCloudScrollY", param_mgr->mCurParams.getCloudScrollY() - 10.0f); + + param_mgr->mDistanceMult = currentParams.getVector(param_mgr->mDistanceMult.name, err); + childSetValue("WLDistanceMult", param_mgr->mDistanceMult.x); + + // Tweak extras + + param_mgr->mWLGamma = currentParams.getVector(param_mgr->mWLGamma.name, err); + childSetValue("WLGamma", param_mgr->mWLGamma.x); + + childSetValue("WLStarAlpha", param_mgr->mCurParams.getStarBrightness()); +} + + +// static +LLFloaterWindLight* LLFloaterWindLight::instance() +{ + if (!sWindLight) + { + sWindLight = new LLFloaterWindLight(); + sWindLight->open(); + sWindLight->setFocus(TRUE); + } + return sWindLight; +} +void LLFloaterWindLight::show() +{ + LLFloaterWindLight* windLight = instance(); + windLight->syncMenu(); + + // comment in if you want the menu to rebuild each time + //gUICtrlFactory->buildFloater(windLight, "floater_windlight_options.xml"); + //windLight->initCallbacks(); + + windLight->open(); +} + +bool LLFloaterWindLight::isOpen() +{ + if (sWindLight != NULL) { + return true; + } + return false; +} + +// virtual +void LLFloaterWindLight::onClose(bool app_quitting) +{ + if (sWindLight) + { + sWindLight->setVisible(FALSE); + } +} + +// color control callbacks +void LLFloaterWindLight::onColorControlRMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WLColorControl * colorControl = static_cast(userData); + + colorControl->r = sldrCtrl->getValueF32(); + if(colorControl->isSunOrAmbientColor) { + colorControl->r *= 3; + } + if(colorControl->isBlueHorizonOrDensity) { + colorControl->r *= 2; + } + + // move i if it's the max + if(colorControl->r >= colorControl->g && colorControl->r >= colorControl->b + && colorControl->hasSliderName) { + colorControl->i = colorControl->r; + std::string name = colorControl->mSliderName; + name.append("I"); + + if(colorControl->isSunOrAmbientColor) { + sWindLight->childSetValue(name, colorControl->r / 3); + } else if(colorControl->isBlueHorizonOrDensity) { + sWindLight->childSetValue(name, colorControl->r / 2); + } else { + sWindLight->childSetValue(name, colorControl->r); + } + } + + colorControl->update(LLWLParamManager::instance()->mCurParams); + + LLWLParamManager::instance()->propagateParameters(); +} + +void LLFloaterWindLight::onColorControlGMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WLColorControl * colorControl = static_cast(userData); + + colorControl->g = sldrCtrl->getValueF32(); + if(colorControl->isSunOrAmbientColor) { + colorControl->g *= 3; + } + if(colorControl->isBlueHorizonOrDensity) { + colorControl->g *= 2; + } + + // move i if it's the max + if(colorControl->g >= colorControl->r && colorControl->g >= colorControl->b + && colorControl->hasSliderName) { + colorControl->i = colorControl->g; + std::string name = colorControl->mSliderName; + name.append("I"); + + if(colorControl->isSunOrAmbientColor) { + sWindLight->childSetValue(name, colorControl->g / 3); + } else if(colorControl->isBlueHorizonOrDensity) { + sWindLight->childSetValue(name, colorControl->g / 2); + } else { + sWindLight->childSetValue(name, colorControl->g); + } + } + + colorControl->update(LLWLParamManager::instance()->mCurParams); + + LLWLParamManager::instance()->propagateParameters(); +} + +void LLFloaterWindLight::onColorControlBMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WLColorControl * colorControl = static_cast(userData); + + colorControl->b = sldrCtrl->getValueF32(); + if(colorControl->isSunOrAmbientColor) { + colorControl->b *= 3; + } + if(colorControl->isBlueHorizonOrDensity) { + colorControl->b *= 2; + } + + // move i if it's the max + if(colorControl->b >= colorControl->r && colorControl->b >= colorControl->g + && colorControl->hasSliderName) { + colorControl->i = colorControl->b; + std::string name = colorControl->mSliderName; + name.append("I"); + + if(colorControl->isSunOrAmbientColor) { + sWindLight->childSetValue(name, colorControl->b / 3); + } else if(colorControl->isBlueHorizonOrDensity) { + sWindLight->childSetValue(name, colorControl->b / 2); + } else { + sWindLight->childSetValue(name, colorControl->b); + } + } + + colorControl->update(LLWLParamManager::instance()->mCurParams); + + LLWLParamManager::instance()->propagateParameters(); +} + +void LLFloaterWindLight::onColorControlIMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WLColorControl * colorControl = static_cast(userData); + + colorControl->i = sldrCtrl->getValueF32(); + + // only for sliders where we pass a name + if(colorControl->hasSliderName) { + + // set it to the top + F32 maxVal = std::max(std::max(colorControl->r, colorControl->g), colorControl->b); + F32 iVal; + + if(colorControl->isSunOrAmbientColor) + { + iVal = colorControl->i * 3; + } + else if(colorControl->isBlueHorizonOrDensity) + { + iVal = colorControl->i * 2; + } + else + { + iVal = colorControl->i; + } + + // get the names of the other sliders + std::string rName = colorControl->mSliderName; + rName.append("R"); + std::string gName = colorControl->mSliderName; + gName.append("G"); + std::string bName = colorControl->mSliderName; + bName.append("B"); + + // handle if at 0 + if(iVal == 0) { + colorControl->r = 0; + colorControl->g = 0; + colorControl->b = 0; + + // if all at the start + // set them all to the intensity + } else if (maxVal == 0) { + colorControl->r = iVal; + colorControl->g = iVal; + colorControl->b = iVal; + + } else { + + // add delta amounts to each + F32 delta = (iVal - maxVal) / maxVal; + colorControl->r *= (1.0f + delta); + colorControl->g *= (1.0f + delta); + colorControl->b *= (1.0f + delta); + } + + // divide sun color vals by three + if(colorControl->isSunOrAmbientColor) + { + sWindLight->childSetValue(rName.c_str(), colorControl->r/3); + sWindLight->childSetValue(gName.c_str(), colorControl->g/3); + sWindLight->childSetValue(bName.c_str(), colorControl->b/3); + + } + else if(colorControl->isBlueHorizonOrDensity) + { + sWindLight->childSetValue(rName.c_str(), colorControl->r/2); + sWindLight->childSetValue(gName.c_str(), colorControl->g/2); + sWindLight->childSetValue(bName.c_str(), colorControl->b/2); + + } + else + { + // set the sliders to the new vals + sWindLight->childSetValue(rName.c_str(), colorControl->r); + sWindLight->childSetValue(gName.c_str(), colorControl->g); + sWindLight->childSetValue(bName.c_str(), colorControl->b); + } + } + + // now update the current parameters and send them to shaders + colorControl->update(LLWLParamManager::instance()->mCurParams); + LLWLParamManager::instance()->propagateParameters(); +} + +/// GLOW SPECIFIC CODE +void LLFloaterWindLight::onGlowRMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WLColorControl * colorControl = static_cast(userData); + + // scaled by 20 + colorControl->r = (2 - sldrCtrl->getValueF32()) * 20; + + colorControl->update(LLWLParamManager::instance()->mCurParams); + LLWLParamManager::instance()->propagateParameters(); +} + +/// \NOTE that we want NEGATIVE (-) B +void LLFloaterWindLight::onGlowBMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WLColorControl * colorControl = static_cast(userData); + + /// \NOTE that we want NEGATIVE (-) B and NOT by 20 as 20 is too big + colorControl->b = -sldrCtrl->getValueF32() * 5; + + colorControl->update(LLWLParamManager::instance()->mCurParams); + LLWLParamManager::instance()->propagateParameters(); +} + +void LLFloaterWindLight::onFloatControlMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + WLFloatControl * floatControl = static_cast(userData); + + floatControl->x = sldrCtrl->getValueF32() / floatControl->mult; + + floatControl->update(LLWLParamManager::instance()->mCurParams); + LLWLParamManager::instance()->propagateParameters(); +} + +void LLFloaterWindLight::onBoolToggle(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLCheckBoxCtrl* cbCtrl = static_cast(ctrl); + + bool value = cbCtrl->get(); + (*(static_cast(userData))) = value; +} + + +// Lighting callbacks + +// time of day +void LLFloaterWindLight::onSunMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sunSldr = LLUICtrlFactory::getSliderByName(sWindLight, + "WLSunAngle"); + LLSliderCtrl* eastSldr = LLUICtrlFactory::getSliderByName(sWindLight, + "WLEastAngle"); + + WLColorControl * colorControl = static_cast(userData); + + // get the two angles + LLWLParamManager * param_mgr = LLWLParamManager::instance(); + + param_mgr->mCurParams.setSunAngle(F_TWO_PI * sunSldr->getValueF32()); + param_mgr->mCurParams.setEastAngle(F_TWO_PI * eastSldr->getValueF32()); + + // set the sun vector + colorControl->r = -sin(param_mgr->mCurParams.getEastAngle()) * + cos(param_mgr->mCurParams.getSunAngle()); + colorControl->g = sin(param_mgr->mCurParams.getSunAngle()); + colorControl->b = cos(param_mgr->mCurParams.getEastAngle()) * + cos(param_mgr->mCurParams.getSunAngle()); + colorControl->i = 1.f; + + colorControl->update(param_mgr->mCurParams); + param_mgr->propagateParameters(); +} + +void LLFloaterWindLight::onFloatTweakMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + F32 * tweak = static_cast(userData); + + (*tweak) = sldrCtrl->getValueF32(); + LLWLParamManager::instance()->propagateParameters(); +} + +void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + + LLWLParamManager::instance()->mCurParams.setStarBrightness(sldrCtrl->getValueF32()); +} + +void LLFloaterWindLight::onNewPreset(void* userData) +{ + gViewerWindow->alertXmlEditText("NewSkyPreset", LLString::format_map_t(), + NULL, NULL, newPromptCallback, NULL); +} + +void LLFloaterWindLight::onSavePreset(void* userData) +{ + // get the name + LLComboBox* comboBox = LLUICtrlFactory::getComboBoxByName(sWindLight, + "WLPresetsCombo"); + + // don't save the empty name + if(comboBox->getSelectedItemLabel() == "") + { + return; + } + + // check to see if it's a default and shouldn't be overwritten + std::set::iterator sIt = sDefaultPresets.find( + comboBox->getSelectedItemLabel().c_str()); + if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("SkyEditPresets")) + { + gViewerWindow->alertXml("WLNoEditDefault"); + return; + } + + LLWLParamManager::instance()->mCurParams.mName = + comboBox->getSelectedItemLabel(); + + gViewerWindow->alertXml("WLSavePresetAlert", saveAlertCallback, sWindLight); +} + +void LLFloaterWindLight::saveAlertCallback(S32 option, void* userdata) +{ + // if they choose save, do it. Otherwise, don't do anything + if(option == 0) + { + LLWLParamManager * param_mgr = LLWLParamManager::instance(); + + param_mgr->setParamSet(param_mgr->mCurParams.mName, param_mgr->mCurParams); + + // comment this back in to save to file + param_mgr->savePreset(param_mgr->mCurParams.mName); + } + +} + +void LLFloaterWindLight::onDeletePreset(void* userData) +{ + LLComboBox* combo_box = LLUICtrlFactory::getComboBoxByName(sWindLight, + "WLPresetsCombo"); + + if(combo_box->getSelectedValue().asString() == "") + { + return; + } + + LLString::format_map_t args; + args["[SKY]"] = combo_box->getSelectedValue().asString(); + gViewerWindow->alertXml("WLDeletePresetAlert", args, deleteAlertCallback, sWindLight); +} + +void LLFloaterWindLight::deleteAlertCallback(S32 option, void* userdata) +{ + // if they choose delete, do it. Otherwise, don't do anything + if(option == 0) + { + LLComboBox* combo_box = LLUICtrlFactory::getComboBoxByName(sWindLight, + "WLPresetsCombo"); + LLFloaterDayCycle* day_cycle = NULL; + LLComboBox* key_combo = NULL; + LLMultiSliderCtrl* mult_sldr = NULL; + + if(LLFloaterDayCycle::isOpen()) + { + day_cycle = LLFloaterDayCycle::instance(); + key_combo = LLUICtrlFactory::getComboBoxByName(day_cycle, + "WLKeyPresets"); + mult_sldr = LLUICtrlFactory::getMultiSliderByName(day_cycle, + "WLDayCycleKeys"); + } + + LLString name(combo_box->getSelectedValue().asString()); + + // check to see if it's a default and shouldn't be deleted + std::set::iterator sIt = sDefaultPresets.find(name.c_str()); + if(sIt != sDefaultPresets.end()) + { + gViewerWindow->alertXml("WLNoEditDefault"); + return; + } + + LLWLParamManager::instance()->removeParamSet(name, true); + + // remove and choose another + S32 new_index = combo_box->getCurrentIndex(); + + combo_box->remove(name); + if(key_combo != NULL) + { + key_combo->remove(name); + + // remove from slider, as well + day_cycle->deletePreset(name); + } + + // pick the previously selected index after delete + if(new_index > 0) + { + new_index--; + } + + if(combo_box->getItemCount() > 0) + { + combo_box->setCurrentByIndex(new_index); + } + } +} + + +void LLFloaterWindLight::onChangePresetName(LLUICtrl* ctrl, void * userData) +{ + deactivateAnimator(); + + LLComboBox * combo_box = static_cast(ctrl); + + if(combo_box->getSimple() == "") + { + return; + } + + LLWLParamManager::instance()->loadPreset( + combo_box->getSelectedValue().asString()); + sWindLight->syncMenu(); +} + +void LLFloaterWindLight::onOpenDayCycle(void* userData) +{ + LLFloaterDayCycle::show(); +} + +// Clouds +void LLFloaterWindLight::onCloudScrollXMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + // *HACK all cloud scrolling is off by an additive of 10. + LLWLParamManager::instance()->mCurParams.setCloudScrollX(sldrCtrl->getValueF32() + 10.0f); +} + +void LLFloaterWindLight::onCloudScrollYMoved(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + + // *HACK all cloud scrolling is off by an additive of 10. + LLWLParamManager::instance()->mCurParams.setCloudScrollY(sldrCtrl->getValueF32() + 10.0f); +} + +void LLFloaterWindLight::onCloudScrollXToggled(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLCheckBoxCtrl* cbCtrl = static_cast(ctrl); + + bool lock = cbCtrl->get(); + LLWLParamManager::instance()->mCurParams.setEnableCloudScrollX(!lock); + + LLSliderCtrl* sldr = LLUICtrlFactory::getSliderByName(sWindLight, + "WLCloudScrollX"); + + if(cbCtrl->get()) + { + sldr->setEnabled(false); + } + else + { + sldr->setEnabled(true); + } + +} + +void LLFloaterWindLight::onCloudScrollYToggled(LLUICtrl* ctrl, void* userData) +{ + deactivateAnimator(); + + LLCheckBoxCtrl* cbCtrl = static_cast(ctrl); + bool lock = cbCtrl->get(); + LLWLParamManager::instance()->mCurParams.setEnableCloudScrollY(!lock); + + LLSliderCtrl* sldr = LLUICtrlFactory::getSliderByName(sWindLight, + "WLCloudScrollY"); + + if(cbCtrl->get()) + { + sldr->setEnabled(false); + } + else + { + sldr->setEnabled(true); + } +} + +void LLFloaterWindLight::deactivateAnimator() +{ + LLWLParamManager::instance()->mAnimator.mIsRunning = false; + LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; +} diff --git a/linden/indra/newview/llfloaterwindlight.h b/linden/indra/newview/llfloaterwindlight.h new file mode 100644 index 0000000..2dbabdb --- /dev/null +++ b/linden/indra/newview/llfloaterwindlight.h @@ -0,0 +1,142 @@ +/** + * @file llfloaterwindlight.h + * @brief LLFloaterWindLight class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* + * Menu for adjusting the atmospheric settings of the world + */ + +#ifndef LL_LLFLOATERWINDLIGHT_H +#define LL_LLFLOATERWINDLIGHT_H + +#include "llfloater.h" + +#include +#include "llwlparamset.h" + +struct WLColorControl; +struct WLFloatControl; + + +/// Menuing system for all of windlight's functionality +class LLFloaterWindLight : public LLFloater +{ +public: + + LLFloaterWindLight(); + virtual ~LLFloaterWindLight(); + + /// initialize all + void initCallbacks(void); + + /// one and one instance only + static LLFloaterWindLight* instance(); + + // help button stuff + static void onClickHelp(void* data); + void initHelpBtn(const char* name, const char* xml_alert); + + static void newPromptCallback(S32 option, const LLString& text, void* userData); + + /// general purpose callbacks for dealing with color controllers + static void onColorControlRMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlGMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlBMoved(LLUICtrl* ctrl, void* userData); + static void onColorControlIMoved(LLUICtrl* ctrl, void* userData); + static void onFloatControlMoved(LLUICtrl* ctrl, void* userData); + static void onBoolToggle(LLUICtrl* ctrl, void* userData); + + /// lighting callbacks for glow + static void onGlowRMoved(LLUICtrl* ctrl, void* userData); + //static void onGlowGMoved(LLUICtrl* ctrl, void* userData); + static void onGlowBMoved(LLUICtrl* ctrl, void* userData); + + /// lighting callbacks for sun + static void onSunMoved(LLUICtrl* ctrl, void* userData); + + /// handle if float is changed + static void onFloatTweakMoved(LLUICtrl* ctrl, void* userData); + + /// for handling when the star slider is moved to adjust the alpha + static void onStarAlphaMoved(LLUICtrl* ctrl, void* userData); + + /// when user hits the load preset button + static void onNewPreset(void* userData); + + /// when user hits the save preset button + static void onSavePreset(void* userData); + + /// prompts a user when overwriting a preset + static void saveAlertCallback(S32 option, void* userdata); + + /// when user hits the save preset button + static void onDeletePreset(void* userData); + + /// prompts a user when overwriting a preset + static void deleteAlertCallback(S32 option, void* userdata); + + /// what to do when you change the preset name + static void onChangePresetName(LLUICtrl* ctrl, void* userData); + + /// when user hits the save preset button + static void onOpenDayCycle(void* userData); + + /// handle cloud scrolling + static void onCloudScrollXMoved(LLUICtrl* ctrl, void* userData); + static void onCloudScrollYMoved(LLUICtrl* ctrl, void* userData); + static void onCloudScrollXToggled(LLUICtrl* ctrl, void* userData); + static void onCloudScrollYToggled(LLUICtrl* ctrl, void* userData); + + //// menu management + + /// show off our menu + static void show(); + + /// return if the menu exists or not + static bool isOpen(); + + /// stuff to do on exit + virtual void onClose(bool app_quitting); + + /// sync up sliders with parameters + void syncMenu(); + + /// turn off animated skies + static void deactivateAnimator(); + +private: + // one instance on the inside + static LLFloaterWindLight* sWindLight; + + static std::set sDefaultPresets; +}; + + +#endif diff --git a/linden/indra/newview/llfloaterworldmap.cpp b/linden/indra/newview/llfloaterworldmap.cpp index 7a8940d..9ac3133 100644 --- a/linden/indra/newview/llfloaterworldmap.cpp +++ b/linden/indra/newview/llfloaterworldmap.cpp @@ -39,13 +39,6 @@ #include "llfloaterworldmap.h" -// Library includes -#include "llfontgl.h" -#include "llinventory.h" -#include "lllineeditor.h" -#include "message.h" - -// Viewer includes #include "llagent.h" #include "llviewerwindow.h" #include "llbutton.h" @@ -54,36 +47,23 @@ #include "llcombobox.h" #include "llviewercontrol.h" #include "lldraghandle.h" -#include "lleconomy.h" #include "llfirstuse.h" #include "llfocusmgr.h" -#include "lliconctrl.h" #include "llinventorymodel.h" -#include "llinventoryview.h" #include "lllandmarklist.h" +#include "lllineeditor.h" #include "llnetmap.h" #include "llpreviewlandmark.h" -#include "llradiogroup.h" #include "llregionhandle.h" -#include "llresizehandle.h" -#include "llresmgr.h" #include "llscrolllistctrl.h" -#include "llsliderctrl.h" -#include "llspinctrl.h" -#include "llstatusbar.h" -#include "lltabcontainer.h" #include "lltextbox.h" #include "lltracker.h" -#include "llui.h" -#include "lluiconstants.h" #include "llurldispatcher.h" -#include "llviewercamera.h" #include "llviewermenu.h" #include "llviewerregion.h" #include "llviewerstats.h" #include "llworldmap.h" #include "llworldmapview.h" -#include "llurl.h" #include "llvieweruictrlfactory.h" #include "llappviewer.h" #include "llmapimagetype.h" @@ -170,13 +150,7 @@ const LLUUID LLFloaterWorldMap::sHomeID( "10000000-0000-0000-0000-000000000001" LLFloaterWorldMap::LLFloaterWorldMap() -: LLFloater("worldmap", "FloaterWorldMapRect", "World Map", - TRUE, // resize - 410, // min-width - 520, // min-height - FALSE, // drag on left - TRUE, // minimize - TRUE), // close +: LLFloater("worldmap"), mInventory(NULL), mInventoryObserver(NULL), mFriendObserver(NULL), @@ -518,7 +492,7 @@ void LLFloaterWorldMap::draw() childSetEnabled("copy_slurl", (mSLURL.size() > 0) ); setMouseOpaque(TRUE); - mDragHandle->setMouseOpaque(TRUE); + getDragHandle()->setMouseOpaque(TRUE); //RN: snaps to zoom value because interpolation caused jitter in the text rendering if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)childGetValue("zoom slider").asReal()) diff --git a/linden/indra/newview/llfloaterworldmap.h b/linden/indra/newview/llfloaterworldmap.h index 7addaa7..5fe685e 100644 --- a/linden/indra/newview/llfloaterworldmap.h +++ b/linden/indra/newview/llfloaterworldmap.h @@ -161,7 +161,7 @@ protected: void cacheLandmarkPosition(); protected: - LLTabContainerCommon* mTabs; + LLTabContainer* mTabs; // Sets gMapScale, in pixels per region F32 mCurZoomVal; diff --git a/linden/indra/newview/llfolderview.cpp b/linden/indra/newview/llfolderview.cpp index ca3c9c1..586c466 100644 --- a/linden/indra/newview/llfolderview.cpp +++ b/linden/indra/newview/llfolderview.cpp @@ -40,6 +40,7 @@ #include "llfocusmgr.h" #include "llfontgl.h" #include "llgl.h" +#include "llglimmediate.h" #include "llinventory.h" #include "llcallbacklist.h" @@ -87,6 +88,11 @@ const F32 FOLDER_CLOSE_TIME_CONSTANT = 0.02f; const F32 FOLDER_OPEN_TIME_CONSTANT = 0.03f; const S32 MAX_FOLDER_ITEM_OVERLAP = 2; +enum { + SIGNAL_NO_KEYBOARD_FOCUS = 1, + SIGNAL_KEYBOARD_FOCUS = 2 +}; + F32 LLFolderView::sAutoOpenTime = 1.f; void delete_selected_item(void* user_data); @@ -600,16 +606,6 @@ const LLString& LLFolderViewItem::getName( void ) const return mLabel; } -LLFolderViewFolder* LLFolderViewItem::getParentFolder( void ) -{ - return mParentFolder; -} - -LLFolderViewEventListener* LLFolderViewItem::getListener( void ) -{ - return mListener; -} - // LLView functionality BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask ) { @@ -814,10 +810,9 @@ void LLFolderViewItem::draw() } if(/*mControlLabel[0] != '\0' && */possibly_has_children) { - LLGLSTexture gls_texture; if (mArrowImage) { - gl_draw_scaled_rotated_image(mIndentation, mRect.getHeight() - ARROW_SIZE - TEXT_PAD, + gl_draw_scaled_rotated_image(mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD, ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, mArrowImage, sFgColor); } } @@ -853,33 +848,33 @@ void LLFolderViewItem::draw() gl_rect_2d( 0, - mRect.getHeight(), - mRect.getWidth() - 2, - llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD), + getRect().getHeight(), + getRect().getWidth() - 2, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), bg_color, filled); if (mIsCurSelection) { gl_rect_2d( 0, - mRect.getHeight(), - mRect.getWidth() - 2, - llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD), + getRect().getHeight(), + getRect().getWidth() - 2, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), sHighlightFgColor, FALSE); } - if (mRect.getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) + if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) { gl_rect_2d( 0, - llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, - mRect.getWidth() - 2, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, + getRect().getWidth() - 2, 2, sHighlightFgColor, FALSE); if (show_context) { gl_rect_2d( 0, - llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, - mRect.getWidth() - 2, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, + getRect().getWidth() - 2, 2, sHighlightBgColor, TRUE); } @@ -890,17 +885,17 @@ void LLFolderViewItem::draw() LLGLSNoTexture gls_no_texture; gl_rect_2d( 0, - mRect.getHeight(), - mRect.getWidth() - 2, - llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD), + getRect().getHeight(), + getRect().getWidth() - 2, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD), sHighlightBgColor, FALSE); - if (mRect.getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) + if (getRect().getHeight() > llround(sFont->getLineHeight()) + ICON_PAD + 2) { gl_rect_2d( 0, - llfloor(mRect.getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, - mRect.getWidth() - 2, + llfloor(getRect().getHeight() - sFont->getLineHeight() - ICON_PAD) - 2, + getRect().getWidth() - 2, 2, sHighlightBgColor, FALSE); } @@ -910,7 +905,7 @@ void LLFolderViewItem::draw() if(mIcon) { - gl_draw_image(mIndentation + ARROW_SIZE + TEXT_PAD, mRect.getHeight() - mIcon->getHeight(), mIcon); + gl_draw_image(mIndentation + ARROW_SIZE + TEXT_PAD, getRect().getHeight() - mIcon->getHeight(), mIcon); mIcon->addTextureStats( (F32)(mIcon->getWidth() * mIcon->getHeight())); } @@ -920,7 +915,7 @@ void LLFolderViewItem::draw() BOOL debug_filters = getRoot()->getDebugFilters(); LLColor4 color = ( (mIsSelected && filled) ? sHighlightFgColor : sFgColor ); F32 right_x; - F32 y = (F32)mRect.getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; + F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; if (debug_filters) { @@ -963,14 +958,14 @@ void LLFolderViewItem::draw() LLString combined_string = mLabel + mLabelSuffix; S32 left = llround(text_left) + sFont->getWidth(combined_string, 0, mStringMatchOffset) - 1; S32 right = left + sFont->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2; - S32 bottom = llfloor(mRect.getHeight() - sFont->getLineHeight() - 3); - S32 top = mRect.getHeight(); + S32 bottom = llfloor(getRect().getHeight() - sFont->getLineHeight() - 3); + S32 top = getRect().getHeight(); LLViewerImage::bindTexture(mBoxImage); - glColor4fv(sFilterBGColor.mV); + gGL.color4fv(sFilterBGColor.mV); gl_segmented_rect_2d_tex(left, top, right, bottom, mBoxImage->getWidth(), mBoxImage->getHeight(), 16); F32 match_string_left = text_left + sFont->getWidthF32(combined_string, 0, mStringMatchOffset); - F32 y = (F32)mRect.getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; + F32 y = (F32)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD; sFont->renderUTF8( combined_string, mStringMatchOffset, match_string_left, y, sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, mLabelStyle, filter_string_length, S32_MAX, &right_x, FALSE ); @@ -1074,7 +1069,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation) if (mIsOpen) { // Add sizes of children - S32 parent_item_height = mRect.getHeight(); + S32 parent_item_height = getRect().getHeight(); folders_t::iterator fit = mFolders.begin(); folders_t::iterator fend = mFolders.end(); @@ -1158,7 +1153,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation) { folders_t::iterator fit = iter++; // number of pixels that bottom of folder label is from top of parent folder - if (mRect.getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight() + if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight() > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP) { // hide if beyond current folder height @@ -1171,7 +1166,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation) { items_t::iterator iit = iter++; // number of pixels that bottom of item label is from top of parent folder - if (mRect.getHeight() - (*iit)->getRect().mBottom + if (getRect().getHeight() - (*iit)->getRect().mBottom > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP) { (*iit)->setVisible(FALSE); @@ -1184,7 +1179,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation) } // don't change width as this item is already as wide as its parent folder - reshape(mRect.getWidth(),llround(mCurHeight)); + reshape(getRect().getWidth(),llround(mCurHeight)); // pass current height value back to parent *height = llround(mCurHeight); @@ -1903,7 +1898,7 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item) item, mSortFunction); mItems.insert(it,item); - item->setRect(LLRect(0, 0, mRect.getWidth(), 0)); + item->setRect(LLRect(0, 0, getRect().getWidth(), 0)); item->setVisible(FALSE); addChild( item ); item->dirtyFilter(); @@ -1921,7 +1916,7 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder) mSortFunction); mFolders.insert(it,folder); folder->setOrigin(0, 0); - folder->reshape(mRect.getWidth(), 0); + folder->reshape(getRect().getWidth(), 0); folder->setVisible(FALSE); addChild( folder ); folder->dirtyFilter(); @@ -1972,6 +1967,7 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL open, ERecurseType recur mListener->openItem(); } } + if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN) { for (folders_t::iterator iter = mFolders.begin(); @@ -2131,7 +2127,7 @@ BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask) handled = LLFolderViewItem::handleHover(x, y, mask); } - //if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD && y > mRect.getHeight() - ) + //if(x < LEFT_INDENTATION + mIndentation && x > mIndentation - LEFT_PAD && y > getRect().getHeight() - ) //{ // gViewerWindow->setCursor(UI_CURSOR_ARROW); // mExpanderHighlighted = TRUE; @@ -2544,7 +2540,7 @@ LLFolderView::LLFolderView( const LLString& name, LLViewerImage* root_folder_ico #pragma warning( pop ) #endif mScrollContainer( NULL ), - mPopupMenuHandle( LLViewHandle::sDeadHandle ), + mPopupMenuHandle(), mAllowMultiSelect(TRUE), mShowFolderHierarchy(FALSE), mSourceID(source_id), @@ -2562,11 +2558,11 @@ LLFolderView::LLFolderView( const LLString& name, LLViewerImage* root_folder_ico mArrangeGeneration(0), mUserData(NULL), mSelectCallback(NULL), - mSelectionChanged(FALSE), + mSignalSelectCallback(0), mMinWidth(0), mDragAndDropThisFrame(FALSE) { - LLRect new_rect(rect.mLeft, rect.mBottom + mRect.getHeight(), rect.mLeft + mRect.getWidth(), rect.mBottom); + LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom); setRect( rect ); reshape(rect.getWidth(), rect.getHeight()); mIsOpen = TRUE; // this view is always open. @@ -2582,7 +2578,7 @@ LLFolderView::LLFolderView( const LLString& name, LLViewerImage* root_folder_ico // just make sure the label ("Inventory Folder") never shows up mLabel = LLString::null; - mRenamer = new LLLineEditor("ren", mRect, "", sFont, + mRenamer = new LLLineEditor("ren", getRect(), "", sFont, DB_INV_ITEM_NAME_STR_LEN, &LLFolderView::commitRename, NULL, @@ -2606,7 +2602,7 @@ LLFolderView::LLFolderView( const LLString& name, LLViewerImage* root_folder_ico } menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor")); menu->setVisible(FALSE); - mPopupMenuHandle = menu->mViewHandle; + mPopupMenuHandle = menu->getHandle(); setTabStop(TRUE); } @@ -2710,7 +2706,7 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder) mFolders.insert(mFolders.begin(), folder); } folder->setOrigin(0, 0); - folder->reshape(mRect.getWidth(), 0); + folder->reshape(getRect().getWidth(), 0); folder->setVisible(FALSE); addChild( folder ); folder->dirtyFilter(); @@ -2726,7 +2722,7 @@ void LLFolderView::closeAllFolders() void LLFolderView::openFolder(const LLString& foldername) { - LLFolderViewFolder* inv = (LLFolderViewFolder*)getChildByName(foldername); + LLFolderViewFolder* inv = getChild(foldername); if (inv) { setSelection(inv, FALSE, FALSE); @@ -2759,7 +2755,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen S32 total_width = LEFT_PAD; S32 running_height = mDebugFilters ? llceil(sSmallFont->getLineHeight()) : 0; S32 target_height = running_height; - S32 parent_item_height = mRect.getHeight(); + S32 parent_item_height = getRect().getHeight(); for (folders_t::iterator iter = mFolders.begin(); iter != mFolders.end();) @@ -2943,7 +2939,7 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL open, /* Flaw llassert(mSelectedItems.size() <= 1); - mSelectionChanged = TRUE; + mSignalSelectCallback = take_keyboard_focus ? SIGNAL_KEYBOARD_FOCUS : SIGNAL_NO_KEYBOARD_FOCUS; return rv; } @@ -2985,7 +2981,7 @@ BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected) rv = LLFolderViewFolder::changeSelection(selection, selected); - mSelectionChanged = TRUE; + mSignalSelectCallback = SIGNAL_KEYBOARD_FOCUS; return rv; } @@ -3011,7 +3007,7 @@ S32 LLFolderView::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* rv++; } - mSelectionChanged = TRUE; + mSignalSelectCallback = SIGNAL_KEYBOARD_FOCUS; return rv; } @@ -3181,7 +3177,7 @@ void LLFolderView::draw() LLString current_filter_string = llformat("Current Filter: %d, Least Filter: %d, Auto-accept Filter: %d", mFilter.getCurrentGeneration(), mFilter.getMinRequiredGeneration(), mFilter.getMustPassGeneration()); sSmallFont->renderUTF8(current_filter_string, 0, 2, - mRect.getHeight() - sSmallFont->getLineHeight(), LLColor4(0.5f, 0.5f, 0.8f, 1.f), + getRect().getHeight() - sSmallFont->getLineHeight(), LLColor4(0.5f, 0.5f, 0.8f, 1.f), LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, S32_MAX, S32_MAX, NULL, FALSE ); } @@ -3287,7 +3283,7 @@ void LLFolderView::revertRenamingItem( void ) void LLFolderView::removeSelectedItems( void ) { - if(getVisible() && mEnabled) + if(getVisible() && getEnabled()) { // just in case we're removing the renaming item. mRenameItem = NULL; @@ -3392,7 +3388,7 @@ void LLFolderView::removeSelectedItems( void ) // open the selected item. void LLFolderView::openSelectedItems( void ) { - if(getVisible() && mEnabled) + if(getVisible() && getEnabled()) { if (mSelectedItems.size() == 1) { @@ -3432,7 +3428,7 @@ void LLFolderView::openSelectedItems( void ) void LLFolderView::propertiesSelectedItems( void ) { - if(getVisible() && mEnabled) + if(getVisible() && getEnabled()) { if (mSelectedItems.size() == 1) { @@ -3531,17 +3527,16 @@ BOOL LLFolderView::autoOpenTest(LLFolderViewFolder* folder) return FALSE; } -BOOL LLFolderView::canCopy() +BOOL LLFolderView::canCopy() const { - if (!(getVisible() && mEnabled && (mSelectedItems.size() > 0))) + if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0))) { return FALSE; } - - selected_items_t::iterator selected_it; - for (selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it) + + for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it) { - LLFolderViewItem* item = *selected_it; + const LLFolderViewItem* item = *selected_it; if (!item->getListener()->isItemCopyable()) { return FALSE; @@ -3556,7 +3551,7 @@ void LLFolderView::copy() // *NOTE: total hack to clear the inventory clipboard LLInventoryClipboard::instance().reset(); S32 count = mSelectedItems.size(); - if(getVisible() && mEnabled && (count > 0)) + if(getVisible() && getEnabled() && (count > 0)) { LLFolderViewEventListener* listener = NULL; selected_items_t::iterator item_it; @@ -3572,7 +3567,7 @@ void LLFolderView::copy() mSearchString.clear(); } -BOOL LLFolderView::canCut() +BOOL LLFolderView::canCut() const { return FALSE; } @@ -3582,24 +3577,24 @@ void LLFolderView::cut() // implement Windows-style cut-and-leave } -BOOL LLFolderView::canPaste() +BOOL LLFolderView::canPaste() const { if (mSelectedItems.empty()) { return FALSE; } - if(getVisible() && mEnabled) + if(getVisible() && getEnabled()) { - selected_items_t::iterator item_it; - for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) + for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); + item_it != mSelectedItems.end(); ++item_it) { // *TODO: only check folders and parent folders of items - LLFolderViewItem* item = (*item_it); - LLFolderViewEventListener* listener = item->getListener(); + const LLFolderViewItem* item = (*item_it); + const LLFolderViewEventListener* listener = item->getListener(); if(!listener || !listener->isClipboardPasteable()) { - LLFolderViewFolder* folderp = item->getParentFolder(); + const LLFolderViewFolder* folderp = item->getParentFolder(); listener = folderp->getListener(); if (!listener || !listener->isClipboardPasteable()) { @@ -3615,7 +3610,7 @@ BOOL LLFolderView::canPaste() // paste selected item void LLFolderView::paste() { - if(getVisible() && mEnabled) + if(getVisible() && getEnabled()) { // find set of unique folders to paste into std::set folder_set; @@ -3657,7 +3652,7 @@ void LLFolderView::startRenamingSelectedItem( void ) { item = mSelectedItems.front(); } - if(getVisible() && mEnabled && (count == 1) && item && item->getListener() && + if(getVisible() && getEnabled() && (count == 1) && item && item->getListener() && item->getListener()->isItemRenameable()) { mRenameItem = item; @@ -3676,7 +3671,7 @@ void LLFolderView::startRenamingSelectedItem( void ) mScrollContainer->calcVisibleSize( &scroller_width, &scroller_height, &dummy_bool, &dummy_bool); } - S32 width = llmax(llmin(item->getRect().getWidth() - x, scroller_width - x - mRect.mLeft), MINIMUM_RENAMER_WIDTH); + S32 width = llmax(llmin(item->getRect().getWidth() - x, scroller_width - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH); S32 height = llfloor(sFont->getLineHeight() + RENAME_HEIGHT_PAD); mRenamer->reshape( width, height, TRUE ); @@ -3709,7 +3704,7 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) // SL-51858: Key presses are not being passed to the Popup menu. // A proper fix is non-trivial so instead just close the menu. - LLMenuGL* menu = (LLMenuGL*)LLView::getViewByHandle(mPopupMenuHandle); + LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu && menu->isOpen()) { LLMenuGL::sMenuContainer->hideMenus(); @@ -3721,7 +3716,7 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) item = *(getChildList()->begin()); } - if( getVisible() && mEnabled && !called_from_parent ) + if( getVisible() && getEnabled() && !called_from_parent ) { switch( key ) { @@ -3952,7 +3947,7 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_pare { // SL-51858: Key presses are not being passed to the Popup menu. // A proper fix is non-trivial so instead just close the menu. - LLMenuGL* menu = (LLMenuGL*)LLView::getViewByHandle(mPopupMenuHandle); + LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu && menu->isOpen()) { LLMenuGL::sMenuContainer->hideMenus(); @@ -3977,11 +3972,11 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_pare } -BOOL LLFolderView::canDoDelete() +BOOL LLFolderView::canDoDelete() const { if (mSelectedItems.size() == 0) return FALSE; - selected_items_t::iterator item_it; - for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) + + for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) { if (!(*item_it)->getListener()->isItemRemovable()) { @@ -4103,7 +4098,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask ) BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL; S32 count = mSelectedItems.size(); - LLMenuGL* menu = (LLMenuGL*)LLView::getViewByHandle(mPopupMenuHandle); + LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if(handled && (count > 0) && menu) { //menu->empty(); @@ -4179,7 +4174,7 @@ void LLFolderView::deleteAllChildren() gViewerWindow->setTopCtrl(NULL); } LLView::deleteViewByHandle(mPopupMenuHandle); - mPopupMenuHandle = LLViewHandle::sDeadHandle; + mPopupMenuHandle = LLHandle(); mRenamer = NULL; mRenameItem = NULL; clearSelection(); @@ -4247,7 +4242,7 @@ LLRect LLFolderView::getVisibleRect() S32 visible_height = mScrollContainer->getRect().getHeight(); S32 visible_width = mScrollContainer->getRect().getWidth(); LLRect visible_rect; - visible_rect.setLeftTopAndSize(-mRect.mLeft, visible_height - mRect.mBottom, visible_width, visible_height); + visible_rect.setLeftTopAndSize(-getRect().mLeft, visible_height - getRect().mBottom, visible_width, visible_height); return visible_rect; } @@ -4257,7 +4252,7 @@ BOOL LLFolderView::getShowSelectionContext() { return TRUE; } - LLMenuGL* menu = (LLMenuGL*)LLView::getViewByHandle(mPopupMenuHandle); + LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu && menu->getVisible()) { return TRUE; @@ -4364,12 +4359,13 @@ void LLFolderView::doIdle() } } - if (mSelectionChanged && mSelectCallback) + if (mSignalSelectCallback && mSelectCallback) { //RN: we use keyboard focus as a proxy for user-explicit actions - mSelectCallback(mSelectedItems, gFocusMgr.childHasKeyboardFocus(this), mUserData); + BOOL take_keyboard_focus = (mSignalSelectCallback == SIGNAL_KEYBOARD_FOCUS); + mSelectCallback(mSelectedItems, take_keyboard_focus, mUserData); } - mSelectionChanged = FALSE; + mSignalSelectCallback = FALSE; } diff --git a/linden/indra/newview/llfolderview.h b/linden/indra/newview/llfolderview.h index 062f710..0f26dfa 100644 --- a/linden/indra/newview/llfolderview.h +++ b/linden/indra/newview/llfolderview.h @@ -108,7 +108,7 @@ public: // This method should be called when a drag begins. returns TRUE // if the drag can begin, otherwise FALSE. - virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) = 0; + virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0; // This method will be called to determine if a drop can be // performed, and will set drop to TRUE if a drop is @@ -465,11 +465,14 @@ public: // Used for sorting, like getLabel() above. virtual U32 getCreationDate() const { return mCreationDate; } - LLFolderViewFolder* getParentFolder( void ); + LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; } + const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; } + LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE ); LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE ); - LLFolderViewEventListener* getListener( void ); + const LLFolderViewEventListener* getListener( void ) const { return mListener; } + LLFolderViewEventListener* getListener( void ) { return mListener; } // just rename the object. void rename(const LLString& new_name); @@ -803,16 +806,16 @@ public: // copy & paste virtual void copy(); - virtual BOOL canCopy(); + virtual BOOL canCopy() const; virtual void cut(); - virtual BOOL canCut(); + virtual BOOL canCut() const; virtual void paste(); - virtual BOOL canPaste(); + virtual BOOL canPaste() const; virtual void doDelete(); - virtual BOOL canDoDelete(); + virtual BOOL canDoDelete() const; // public rename functionality - can only start the process void startRenamingSelectedItem( void ); @@ -885,7 +888,7 @@ protected: void revertRenamingItem( void ); protected: - LLViewHandle mPopupMenuHandle; + LLHandle mPopupMenuHandle; typedef std::deque selected_items_t; selected_items_t mSelectedItems; @@ -920,7 +923,7 @@ protected: void* mUserData; SelectCallback mSelectCallback; - BOOL mSelectionChanged; + S32 mSignalSelectCallback; S32 mMinWidth; std::map mItemMap; BOOL mDragAndDropThisFrame; diff --git a/linden/indra/newview/llframestats.cpp b/linden/indra/newview/llframestats.cpp index 26a1960..f67c3b8 100644 --- a/linden/indra/newview/llframestats.cpp +++ b/linden/indra/newview/llframestats.cpp @@ -141,7 +141,6 @@ void LLFrameStats::addFrameData() frame_data.mTotalDuration = total_duration; frame_data.mNumTriangles = gPipeline.mTrianglesDrawn; frame_data.mNumObjects = gObjectList.getNumObjects(); - frame_data.mNumVisibleObjects = gPipeline.getVisibleCount(); frame_data.mNumFullUpdates = gFullObjectUpdates; frame_data.mNumTerseUpdates = gTerseObjectUpdates; @@ -168,7 +167,6 @@ void LLFrameStats::dump() S64 total_triangles = 0; S32 total_frames = mFrameData.count(); S32 total_num_objects = 0; - S32 total_visible_objects = 0; time_t cur_time; char time_str[24]; /* Flawfinder: ignore */ @@ -209,7 +207,6 @@ void LLFrameStats::dump() total_time += mFrameData[i].mTotalDuration; total_triangles += mFrameData[i].mNumTriangles; total_num_objects += mFrameData[i].mNumObjects; - total_visible_objects += mFrameData[i].mNumVisibleObjects; fprintf(fp, "%f\t%d\t", mFrameData[i].mTotalDuration, mFrameData[i].mNumTriangles); S32 j; @@ -246,7 +243,6 @@ void LLFrameStats::dump() fprintf(fp, "Triangles/sec: %f\n", total_triangles/total_time); fprintf(fp, "Triangles/frame: %f\n", (F32)total_triangles/(F32)total_frames); fprintf(fp, "All Objects/frame: %f\n", (F32)total_num_objects/(F32)total_frames); - fprintf(fp, "Vis Objects/frame: %f\n", (F32)total_visible_objects/(F32)total_frames); fprintf(fp, "\n"); fclose(fp); } diff --git a/linden/indra/newview/llframestats.h b/linden/indra/newview/llframestats.h index d54d409..7b4da19 100644 --- a/linden/indra/newview/llframestats.h +++ b/linden/indra/newview/llframestats.h @@ -100,7 +100,6 @@ private: F32 mTotalDuration; S32 mNumTriangles; S32 mNumObjects; - S32 mNumVisibleObjects; S32 mNumFullUpdates; S32 mNumTerseUpdates; F32 mTotalVorbisTime; diff --git a/linden/indra/newview/llframestatview.cpp b/linden/indra/newview/llframestatview.cpp index 416bf26..33a3265 100644 --- a/linden/indra/newview/llframestatview.cpp +++ b/linden/indra/newview/llframestatview.cpp @@ -117,19 +117,19 @@ void LLFrameStatView::draw() } S32 num_bins = llmin(statp->getNumValues(), (U32)32); - F32 total_width = mRect.getWidth() - 20.f; - F32 total_height = mRect.getHeight() - 30.f; + F32 total_width = getRect().getWidth() - 20.f; + F32 total_height = getRect().getHeight() - 30.f; S32 left, top, right, bottom; F32 key_height = 16; S32 bar_spacing = 2; F32 time_scale = total_width / mTotalTime; // Draw the window background - gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); // Render the key left = 10; - top = mRect.getHeight() - 10; + top = getRect().getHeight() - 10; BOOL is_active[MAX_STATS]; S32 bin = mStats[0]->getCurBin() - 1; @@ -181,7 +181,7 @@ void LLFrameStatView::draw() left = left + LLFontGL::sMonospace->getWidth(mLabels[i]) + 10; if ((i + 1) < mNumStats) { - if ((left + LLFontGL::sMonospace->getWidth(mLabels[i+1])) > (mRect.getWidth() - 10)) + if ((left + LLFontGL::sMonospace->getWidth(mLabels[i+1])) > (getRect().getWidth() - 10)) { left = 10; top -= llfloor(LLFontGL::sMonospace->getLineHeight()); @@ -246,7 +246,7 @@ void LLFrameStatView::draw() S32 graph_height = bar_height * num_bins + bar_spacing * num_bins - 1; // Draw the tick marks. - top = mRect.getHeight() - llfloor(key_height) - 20; + top = getRect().getHeight() - llfloor(key_height) - 20; bottom = top - graph_height - 2; // Render the ticks and labels @@ -313,7 +313,7 @@ void LLFrameStatView::draw() // Determine which stats are active. - top = mRect.getHeight() - llfloor(key_height) - 20; + top = getRect().getHeight() - llfloor(key_height) - 20; bottom = top - bar_height; for (i = 0; i < 32; i++) { diff --git a/linden/indra/newview/llgenepool.cpp b/linden/indra/newview/llgenepool.cpp index 9974aa8..553bcad 100644 --- a/linden/indra/newview/llgenepool.cpp +++ b/linden/indra/newview/llgenepool.cpp @@ -248,7 +248,7 @@ void LLGenePool::spawn( EWearableType type ) do { i = rand() % mArchetypes.count(); - cur_sex_weight = *(mArchetypes[i]->mParamMap[ male_param_id ]); + cur_sex_weight = mArchetypes[i]->getParam(male_param_id, 0.f); cycles++; if (cur_sex_weight != sex_weight) { @@ -271,7 +271,7 @@ void LLGenePool::spawn( EWearableType type ) do { j = rand() % mArchetypes.count(); - cur_sex_weight = *(mArchetypes[j]->mParamMap[ male_param_id ]); + cur_sex_weight = mArchetypes[j]->getParam(male_param_id, 0.f); cycles++; } while( @@ -293,7 +293,7 @@ void LLGenePool::spawn( EWearableType type ) do { k = rand() % mArchetypes.count(); - cur_sex_weight = *(mArchetypes[k]->mParamMap[ male_param_id ]); + cur_sex_weight = mArchetypes[k]->getParam(male_param_id, 0.f); cycles++; } while( (cycles < MAX_CYCLES) && @@ -326,18 +326,13 @@ void LLGenePool::spawn( EWearableType type ) if (param_id != male_param_id) { - F32* weight1p = arch1->getParam( param_id ); - F32 weight1 = weight1p ? *weight1p : param->getDefaultWeight(); + F32 weight1 = arch1->getParam( param_id, param->getDefaultWeight() ); F32 net_weight = weight1; if( arch2 && arch3 ) { - F32* weight2p = arch2->getParam( param_id ); - F32 weight2 = weight2p ? *weight2p : param->getDefaultWeight(); - - F32* weight3p = arch3->getParam( param_id ); - F32 weight3 = weight3p ? *weight3p : param->getDefaultWeight(); - + F32 weight2 = arch2->getParam( param_id, param->getDefaultWeight() ); + F32 weight3 = arch3->getParam( param_id, param->getDefaultWeight() ); net_weight = b1 * weight1 + b2 * weight2 + b3 * weight3; } diff --git a/linden/indra/newview/llgivemoney.cpp b/linden/indra/newview/llgivemoney.cpp index 6b2b5bd..8abda4b 100644 --- a/linden/indra/newview/llgivemoney.cpp +++ b/linden/indra/newview/llgivemoney.cpp @@ -311,7 +311,7 @@ void LLFloaterPay::processPayPriceReply(LLMessageSystem* msg, void **userdata) self->mQuickPayButton[i]->setVisible(FALSE); } - self->reshape( self->mRect.getWidth() + padding_required, self->mRect.getHeight(), FALSE ); + self->reshape( self->getRect().getWidth() + padding_required, self->getRect().getHeight(), FALSE ); } msg->setHandlerFunc("PayPriceReply",NULL,NULL); } @@ -490,3 +490,4 @@ void LLFloaterPay::give(S32 amount) ///---------------------------------------------------------------------------- + diff --git a/linden/indra/newview/llgivemoney.h b/linden/indra/newview/llgivemoney.h index ab4da19..e150679 100644 --- a/linden/indra/newview/llgivemoney.h +++ b/linden/indra/newview/llgivemoney.h @@ -95,7 +95,7 @@ protected: LLButton* mQuickPayButton[MAX_PAY_BUTTONS]; LLGiveMoneyInfo* mQuickPayInfo[MAX_PAY_BUTTONS]; - LLHandle mObjectSelection; + LLSafeHandle mObjectSelection; static S32 sLastAmount; }; diff --git a/linden/indra/newview/llglsandbox.cpp b/linden/indra/newview/llglsandbox.cpp index 6c2d34a..31e1935 100644 --- a/linden/indra/newview/llglsandbox.cpp +++ b/linden/indra/newview/llglsandbox.cpp @@ -39,6 +39,7 @@ #include "llviewercontrol.h" #include "llgl.h" +#include "llglimmediate.h" #include "llglheaders.h" #include "llparcel.h" #include "llui.h" @@ -65,6 +66,7 @@ #include "llpreviewtexture.h" #include "llresmgr.h" #include "pipeline.h" +#include "llspatialpartition.h" BOOL LLAgent::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position) { @@ -137,7 +139,7 @@ void LLAgent::renderAutoPilotTarget() LLVector3d target_global; glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gGL.pushMatrix(); // not textured LLGLSNoTexture no_texture; @@ -147,31 +149,15 @@ void LLAgent::renderAutoPilotTarget() target_global = mAutoPilotTargetGlobal; - glTranslatef((F32)(target_global.mdV[VX]), (F32)(target_global.mdV[VY]), (F32)(target_global.mdV[VZ])); + gGL.translatef((F32)(target_global.mdV[VX]), (F32)(target_global.mdV[VY]), (F32)(target_global.mdV[VZ])); - /* - LLVector3 offset = target_global - mCamera.getOrigin(); - F32 range = offset.magVec(); - if (range > 0.001f) - { - // range != zero - F32 fraction_of_fov = height_pixels / (F32) mCamera.getViewHeightInPixels(); - F32 apparent_angle = fraction_of_fov * mCamera.getView(); - height_meters = range * tan(apparent_angle); - } - else - { - // range == zero - height_meters = 1.0f; - } - */ height_meters = 1.f; glScalef(height_meters, height_meters, height_meters); gSphere.render(1500.f); - glPopMatrix(); + gGL.popMatrix(); } } @@ -227,7 +213,7 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) // save drawing mode glMatrixMode(GL_PROJECTION); - glPushMatrix(); + gGL.pushMatrix(); BOOL limit_select_distance = gSavedSettings.getBOOL("LimitSelectDistance"); if (limit_select_distance) @@ -284,14 +270,18 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) if (grow_selection) { std::vector potentials; - - - for (U32 i = 0; i < LLPipeline::NUM_PARTITIONS-1; i++) + + for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); + iter != gWorldp->getRegionList().end(); ++iter) { - LLSpatialPartition* part = gPipeline.getSpatialPartition(i); - if (part) + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { - part->cull(*gCamera, &potentials, TRUE); + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->cull(*gCamera, &potentials, TRUE); + } } } @@ -338,7 +328,7 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) // restore drawing mode glMatrixMode(GL_PROJECTION); - glPopMatrix(); + gGL.popMatrix(); glMatrixMode(GL_MODELVIEW); // restore camera @@ -358,35 +348,35 @@ void LLCompass::draw() if (!getVisible()) return; glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gGL.pushMatrix(); S32 width = 32; S32 height = 32; LLGLSUIDefault gls_ui; - glTranslatef( COMPASS_SIZE/2.f, COMPASS_SIZE/2.f, 0.f); + gGL.translatef( COMPASS_SIZE/2.f, COMPASS_SIZE/2.f, 0.f); if (mBkgndTexture) { mBkgndTexture->bind(); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); - glTexCoord2f(1.f, 1.f); - glVertex2i(width, height); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(width, height); - glTexCoord2f(0.f, 1.f); - glVertex2i(-width, height); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(-width, height); - glTexCoord2f(0.f, 0.f); - glVertex2i(-width, -height); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(-width, -height); - glTexCoord2f(1.f, 0.f); - glVertex2i(width, -height); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(width, -height); - glEnd(); + gGL.end(); } // rotate subsequent draws to agent rotation @@ -396,26 +386,26 @@ void LLCompass::draw() if (mTexture) { mTexture->bind(); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); - glTexCoord2f(1.f, 1.f); - glVertex2i(width, height); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(width, height); - glTexCoord2f(0.f, 1.f); - glVertex2i(-width, height); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(-width, height); - glTexCoord2f(0.f, 0.f); - glVertex2i(-width, -height); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(-width, -height); - glTexCoord2f(1.f, 0.f); - glVertex2i(width, -height); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(width, -height); - glEnd(); + gGL.end(); } - glPopMatrix(); + gGL.popMatrix(); } @@ -427,8 +417,8 @@ void LLHorizontalCompass::draw() LLGLSUIDefault gls_ui; - S32 width = mRect.getWidth(); - S32 height = mRect.getHeight(); + S32 width = getRect().getWidth(); + S32 height = getRect().getHeight(); S32 half_width = width / 2; if( mTexture ) @@ -443,28 +433,28 @@ void LLHorizontalCompass::draw() F32 right = center + COMPASS_RANGE; mTexture->bind(); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f ); - glBegin( GL_QUADS ); + gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f ); + gGL.begin( GL_QUADS ); - glTexCoord2f(right, 1.f); - glVertex2i(width, height); + gGL.texCoord2f(right, 1.f); + gGL.vertex2i(width, height); - glTexCoord2f(left, 1.f); - glVertex2i(0, height); + gGL.texCoord2f(left, 1.f); + gGL.vertex2i(0, height); - glTexCoord2f(left, 0.f); - glVertex2i(0, 0); + gGL.texCoord2f(left, 0.f); + gGL.vertex2i(0, 0); - glTexCoord2f(right, 0.f); - glVertex2i(width, 0); + gGL.texCoord2f(right, 0.f); + gGL.vertex2i(width, 0); - glEnd(); + gGL.end(); } // Draw the focus line { LLGLSNoTexture gls_no_texture; - glColor4fv( mFocusColor.mV ); + gGL.color4fv( mFocusColor.mV ); gl_line_2d( half_width, 0, half_width, height ); } } @@ -482,31 +472,31 @@ void LLWind::renderVectors() F32 region_width_meters = gWorldPointer->getRegionWidthInMeters(); LLGLSNoTexture gls_no_texture; - glPushMatrix(); + gGL.pushMatrix(); LLVector3 origin_agent; origin_agent = gAgent.getPosAgentFromGlobal(mOriginGlobal); - glTranslatef(origin_agent.mV[VX], origin_agent.mV[VY], WIND_ALTITUDE); + gGL.translatef(origin_agent.mV[VX], origin_agent.mV[VY], WIND_ALTITUDE); for (j = 0; j < mSize; j++) { for (i = 0; i < mSize; i++) { x = mCloudVelX[i + j*mSize] * WIND_SCALE_HACK; y = mCloudVelY[i + j*mSize] * WIND_SCALE_HACK; - glPushMatrix(); - glTranslatef((F32)i * region_width_meters/mSize, (F32)j * region_width_meters/mSize, 0.0); - glColor3f(0,1,0); - glBegin(GL_POINTS); - glVertex3f(0,0,0); - glEnd(); - glColor3f(1,0,0); - glBegin(GL_LINES); - glVertex3f(x * 0.1f, y * 0.1f ,0.f); - glVertex3f(x, y, 0.f); - glEnd(); - glPopMatrix(); + gGL.pushMatrix(); + gGL.translatef((F32)i * region_width_meters/mSize, (F32)j * region_width_meters/mSize, 0.0); + gGL.color3f(0,1,0); + gGL.begin(GL_POINTS); + gGL.vertex3f(0,0,0); + gGL.end(); + gGL.color3f(1,0,0); + gGL.begin(GL_LINES); + gGL.vertex3f(x * 0.1f, y * 0.1f ,0.f); + gGL.vertex3f(x, y, 0.f); + gGL.end(); + gGL.popMatrix(); } } - glPopMatrix(); + gGL.popMatrix(); } @@ -545,49 +535,49 @@ void LLViewerParcelMgr::renderRect(const LLVector3d &west_south_bottom_global, F32 nw_top = nw_bottom + PARCEL_POST_HEIGHT; LLUI::setLineWidth(2.f); - glColor4f(1.f, 1.f, 0.f, 1.f); + gGL.color4f(1.f, 1.f, 0.f, 1.f); // Cheat and give this the same pick-name as land - glBegin(GL_LINES); + gGL.begin(GL_LINES); - glVertex3f(west, north, nw_bottom); - glVertex3f(west, north, nw_top); + gGL.vertex3f(west, north, nw_bottom); + gGL.vertex3f(west, north, nw_top); - glVertex3f(east, north, ne_bottom); - glVertex3f(east, north, ne_top); + gGL.vertex3f(east, north, ne_bottom); + gGL.vertex3f(east, north, ne_top); - glVertex3f(east, south, se_bottom); - glVertex3f(east, south, se_top); + gGL.vertex3f(east, south, se_bottom); + gGL.vertex3f(east, south, se_top); - glVertex3f(west, south, sw_bottom); - glVertex3f(west, south, sw_top); + gGL.vertex3f(west, south, sw_bottom); + gGL.vertex3f(west, south, sw_top); - glEnd(); + gGL.end(); - glColor4f(1.f, 1.f, 0.f, 0.2f); - glBegin(GL_QUADS); + gGL.color4f(1.f, 1.f, 0.f, 0.2f); + gGL.begin(GL_QUADS); - glVertex3f(west, north, nw_bottom); - glVertex3f(west, north, nw_top); - glVertex3f(east, north, ne_top); - glVertex3f(east, north, ne_bottom); + gGL.vertex3f(west, north, nw_bottom); + gGL.vertex3f(west, north, nw_top); + gGL.vertex3f(east, north, ne_top); + gGL.vertex3f(east, north, ne_bottom); - glVertex3f(east, north, ne_bottom); - glVertex3f(east, north, ne_top); - glVertex3f(east, south, se_top); - glVertex3f(east, south, se_bottom); + gGL.vertex3f(east, north, ne_bottom); + gGL.vertex3f(east, north, ne_top); + gGL.vertex3f(east, south, se_top); + gGL.vertex3f(east, south, se_bottom); - glVertex3f(east, south, se_bottom); - glVertex3f(east, south, se_top); - glVertex3f(west, south, sw_top); - glVertex3f(west, south, sw_bottom); + gGL.vertex3f(east, south, se_bottom); + gGL.vertex3f(east, south, se_top); + gGL.vertex3f(west, south, sw_top); + gGL.vertex3f(west, south, sw_bottom); - glVertex3f(west, south, sw_bottom); - glVertex3f(west, south, sw_top); - glVertex3f(west, north, nw_top); - glVertex3f(west, north, nw_bottom); + gGL.vertex3f(west, south, sw_bottom); + gGL.vertex3f(west, south, sw_top); + gGL.vertex3f(west, north, nw_top); + gGL.vertex3f(west, north, nw_bottom); - glEnd(); + gGL.end(); LLUI::setLineWidth(1.f); } @@ -629,49 +619,49 @@ void LLViewerParcelMgr::renderParcel(LLParcel* parcel ) LLGLDepthTest gls_depth(GL_TRUE); LLUI::setLineWidth(2.f); - glColor4f(0.f, 1.f, 1.f, 1.f); + gGL.color4f(0.f, 1.f, 1.f, 1.f); // Cheat and give this the same pick-name as land - glBegin(GL_LINES); + gGL.begin(GL_LINES); - glVertex3f(west, north, nw_bottom); - glVertex3f(west, north, nw_top); + gGL.vertex3f(west, north, nw_bottom); + gGL.vertex3f(west, north, nw_top); - glVertex3f(east, north, ne_bottom); - glVertex3f(east, north, ne_top); + gGL.vertex3f(east, north, ne_bottom); + gGL.vertex3f(east, north, ne_top); - glVertex3f(east, south, se_bottom); - glVertex3f(east, south, se_top); + gGL.vertex3f(east, south, se_bottom); + gGL.vertex3f(east, south, se_top); - glVertex3f(west, south, sw_bottom); - glVertex3f(west, south, sw_top); + gGL.vertex3f(west, south, sw_bottom); + gGL.vertex3f(west, south, sw_top); - glEnd(); + gGL.end(); - glColor4f(0.f, 1.f, 1.f, 0.2f); - glBegin(GL_QUADS); + gGL.color4f(0.f, 1.f, 1.f, 0.2f); + gGL.begin(GL_QUADS); - glVertex3f(west, north, nw_bottom); - glVertex3f(west, north, nw_top); - glVertex3f(east, north, ne_top); - glVertex3f(east, north, ne_bottom); + gGL.vertex3f(west, north, nw_bottom); + gGL.vertex3f(west, north, nw_top); + gGL.vertex3f(east, north, ne_top); + gGL.vertex3f(east, north, ne_bottom); - glVertex3f(east, north, ne_bottom); - glVertex3f(east, north, ne_top); - glVertex3f(east, south, se_top); - glVertex3f(east, south, se_bottom); + gGL.vertex3f(east, north, ne_bottom); + gGL.vertex3f(east, north, ne_top); + gGL.vertex3f(east, south, se_top); + gGL.vertex3f(east, south, se_bottom); - glVertex3f(east, south, se_bottom); - glVertex3f(east, south, se_top); - glVertex3f(west, south, sw_top); - glVertex3f(west, south, sw_bottom); + gGL.vertex3f(east, south, se_bottom); + gGL.vertex3f(east, south, se_top); + gGL.vertex3f(west, south, sw_top); + gGL.vertex3f(west, south, sw_bottom); - glVertex3f(west, south, sw_bottom); - glVertex3f(west, south, sw_top); - glVertex3f(west, north, nw_top); - glVertex3f(west, north, nw_bottom); + gGL.vertex3f(west, south, sw_bottom); + gGL.vertex3f(west, south, sw_top); + gGL.vertex3f(west, north, nw_top); + gGL.vertex3f(west, north, nw_bottom); - glEnd(); + gGL.end(); LLUI::setLineWidth(1.f); } @@ -714,14 +704,14 @@ void LLViewerParcelMgr::renderOneSegment(F32 x1, F32 y1, F32 x2, F32 y2, F32 hei if (height < 1.f) { z = z1+height; - glVertex3f(x1, y1, z); + gGL.vertex3f(x1, y1, z); - glVertex3f(x1, y1, z1); + gGL.vertex3f(x1, y1, z1); - glVertex3f(x2, y2, z2); + gGL.vertex3f(x2, y2, z2); z = z2+height; - glVertex3f(x2, y2, z); + gGL.vertex3f(x2, y2, z); } else { @@ -750,19 +740,19 @@ void LLViewerParcelMgr::renderOneSegment(F32 x1, F32 y1, F32 x2, F32 y2, F32 hei } - glTexCoord2f(tex_coord1*0.5f+0.5f, z1*0.5f); - glVertex3f(x1, y1, z1); + gGL.texCoord2f(tex_coord1*0.5f+0.5f, z1*0.5f); + gGL.vertex3f(x1, y1, z1); - glTexCoord2f(tex_coord2*0.5f+0.5f, z2*0.5f); - glVertex3f(x2, y2, z2); + gGL.texCoord2f(tex_coord2*0.5f+0.5f, z2*0.5f); + gGL.vertex3f(x2, y2, z2); // top edge stairsteps z = llmax(z2+height, z1+height); - glTexCoord2f(tex_coord2*0.5f+0.5f, z*0.5f); - glVertex3f(x2, y2, z); + gGL.texCoord2f(tex_coord2*0.5f+0.5f, z*0.5f); + gGL.vertex3f(x2, y2, z); - glTexCoord2f(tex_coord1*0.5f+0.5f, z*0.5f); - glVertex3f(x1, y1, z); + gGL.texCoord2f(tex_coord1*0.5f+0.5f, z*0.5f); + gGL.vertex3f(x1, y1, z); } } @@ -772,17 +762,19 @@ void LLViewerParcelMgr::renderHighlightSegments(const U8* segments, LLViewerRegi S32 x, y; F32 x1, y1; // start point F32 x2, y2; // end point + bool has_segments = false; LLGLSUIDefault gls_ui; LLGLSNoTexture gls_no_texture; LLGLDepthTest gls_depth(GL_TRUE); - glColor4f(1.f, 1.f, 0.f, 0.2f); - - // Cheat and give this the same pick-name as land - glBegin(GL_QUADS); + gGL.color4f(1.f, 1.f, 0.f, 0.2f); const S32 STRIDE = (mParcelsPerEdge+1); + + // Cheat and give this the same pick-name as land + + for (y = 0; y < STRIDE; y++) { for (x = 0; x < STRIDE; x++) @@ -796,7 +788,12 @@ void LLViewerParcelMgr::renderHighlightSegments(const U8* segments, LLViewerRegi x2 = x1 + PARCEL_GRID_STEP_METERS; y2 = y1; - + + if (!has_segments) + { + has_segments = true; + gGL.begin(GL_QUADS); + } renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, SOUTH_MASK, regionp); } @@ -808,12 +805,20 @@ void LLViewerParcelMgr::renderHighlightSegments(const U8* segments, LLViewerRegi x2 = x1; y2 = y1 + PARCEL_GRID_STEP_METERS; + if (!has_segments) + { + has_segments = true; + gGL.begin(GL_QUADS); + } renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, WEST_MASK, regionp); } } } - glEnd(); + if (has_segments) + { + gGL.end(); + } } @@ -851,14 +856,14 @@ void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLV if (use_pass && (mCollisionBanned == BA_NOT_ON_LIST)) { - LLViewerImage::bindTexture(mPassImage); + LLViewerImage::bindTexture( getPassImage() ); } else { - LLViewerImage::bindTexture(mBlockedImage); + LLViewerImage::bindTexture( getBlockedImage() ); } - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); for (y = 0; y < STRIDE; y++) { @@ -882,7 +887,7 @@ void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLV if (gRenderForSelect) { LLColor4U color((U8)(GL_NAME_PARCEL_WALL >> 16), (U8)(GL_NAME_PARCEL_WALL >> 8), (U8)GL_NAME_PARCEL_WALL); - glColor4ubv(color.mV); + gGL.color4ubv(color.mV); } else { @@ -906,7 +911,7 @@ void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLV alpha = llclamp(alpha, 0.0f, MAX_ALPHA); - glColor4f(1.f, 1.f, 1.f, alpha); + gGL.color4f(1.f, 1.f, 1.f, alpha); } if ((pos_y - y1) < 0) direction = SOUTH_MASK; @@ -928,7 +933,7 @@ void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLV if (gRenderForSelect) { LLColor4U color((U8)(GL_NAME_PARCEL_WALL >> 16), (U8)(GL_NAME_PARCEL_WALL >> 8), (U8)GL_NAME_PARCEL_WALL); - glColor4ubv(color.mV); + gGL.color4ubv(color.mV); } else { @@ -952,7 +957,7 @@ void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLV alpha = llclamp(alpha, 0.0f, MAX_ALPHA); - glColor4f(1.f, 1.f, 1.f, alpha); + gGL.color4f(1.f, 1.f, 1.f, alpha); } if ((pos_x - x1) > 0) direction = WEST_MASK; @@ -965,43 +970,48 @@ void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLV } } - glEnd(); + gGL.end(); } void draw_line_cube(F32 width, const LLVector3& center) { width = 0.5f * width; - glVertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width); - glVertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width); - glVertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width); - glVertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width); - glVertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width); - glVertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width); - glVertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width); - glVertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width); - - glVertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width); - glVertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width); - glVertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width); - glVertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width); - glVertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width); - glVertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width); - glVertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width); - glVertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width); - - glVertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width); - glVertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width); - glVertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width); - glVertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width); - glVertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width); - glVertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width); - glVertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width); - glVertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width); + gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width); + gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width); + gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width); + gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width); + gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width); + gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width); + gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width); + gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width); + + gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width); + gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width); + gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width); + gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width); + gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width); + gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width); + gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width); + gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width); + + gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] + width); + gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] + width,center.mV[VZ] - width); + gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] + width); + gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] + width,center.mV[VZ] - width); + gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] + width); + gGL.vertex3f(center.mV[VX] - width ,center.mV[VY] - width,center.mV[VZ] - width); + gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] + width); + gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width); } void LLViewerObjectList::renderObjectBeacons() { + if (mDebugBeacons.empty()) + { + return; + } + S32 i; //const LLFontGL *font = gResMgr->getRes(LLFONT_SANSSERIF); @@ -1011,7 +1021,7 @@ void LLViewerObjectList::renderObjectBeacons() { LLGLSNoTexture gls_ui_no_texture; - glBegin(GL_LINES); + gGL.begin(GL_LINES); for (i = 0; i < mDebugBeacons.count(); i++) { const LLDebugBeacon &debug_beacon = mDebugBeacons[i]; @@ -1020,31 +1030,32 @@ void LLViewerObjectList::renderObjectBeacons() S32 line_width = debug_beacon.mLineWidth; if (line_width != last_line_width) { - glEnd(); + gGL.end(); + gGL.flush(); glLineWidth( (F32)line_width ); last_line_width = line_width; - glBegin(GL_LINES); + gGL.begin(GL_LINES); } const LLVector3 &thisline = debug_beacon.mPositionAgent; - glColor4fv(color.mV); - glVertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 50.f); - glVertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 50.f); - glVertex3f(thisline.mV[VX] - 2.f,thisline.mV[VY],thisline.mV[VZ]); - glVertex3f(thisline.mV[VX] + 2.f,thisline.mV[VY],thisline.mV[VZ]); - glVertex3f(thisline.mV[VX],thisline.mV[VY] - 2.f,thisline.mV[VZ]); - glVertex3f(thisline.mV[VX],thisline.mV[VY] + 2.f,thisline.mV[VZ]); + gGL.color4fv(color.mV); + gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 50.f); + gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 50.f); + gGL.vertex3f(thisline.mV[VX] - 2.f,thisline.mV[VY],thisline.mV[VZ]); + gGL.vertex3f(thisline.mV[VX] + 2.f,thisline.mV[VY],thisline.mV[VZ]); + gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 2.f,thisline.mV[VZ]); + gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 2.f,thisline.mV[VZ]); draw_line_cube(0.10f, thisline); } - glEnd(); + gGL.end(); } { LLGLSNoTexture gls_ui_no_texture; LLGLDepthTest gls_depth(GL_TRUE); - glBegin(GL_LINES); + gGL.begin(GL_LINES); last_line_width = -1; for (i = 0; i < mDebugBeacons.count(); i++) { @@ -1053,25 +1064,27 @@ void LLViewerObjectList::renderObjectBeacons() S32 line_width = debug_beacon.mLineWidth; if (line_width != last_line_width) { - glEnd(); + gGL.end(); + gGL.flush(); glLineWidth( (F32)line_width ); last_line_width = line_width; - glBegin(GL_LINES); + gGL.begin(GL_LINES); } const LLVector3 &thisline = debug_beacon.mPositionAgent; - glColor4fv(debug_beacon.mColor.mV); - glVertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 0.5f); - glVertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 0.5f); - glVertex3f(thisline.mV[VX] - 0.5f,thisline.mV[VY],thisline.mV[VZ]); - glVertex3f(thisline.mV[VX] + 0.5f,thisline.mV[VY],thisline.mV[VZ]); - glVertex3f(thisline.mV[VX],thisline.mV[VY] - 0.5f,thisline.mV[VZ]); - glVertex3f(thisline.mV[VX],thisline.mV[VY] + 0.5f,thisline.mV[VZ]); + gGL.color4fv(debug_beacon.mColor.mV); + gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 0.5f); + gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 0.5f); + gGL.vertex3f(thisline.mV[VX] - 0.5f,thisline.mV[VY],thisline.mV[VZ]); + gGL.vertex3f(thisline.mV[VX] + 0.5f,thisline.mV[VY],thisline.mV[VZ]); + gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 0.5f,thisline.mV[VZ]); + gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 0.5f,thisline.mV[VZ]); draw_line_cube(0.10f, thisline); } - glEnd(); + gGL.end(); + gGL.flush(); glLineWidth(1.f); for (i = 0; i < mDebugBeacons.count(); i++) diff --git a/linden/indra/newview/llglslshader.cpp b/linden/indra/newview/llglslshader.cpp index 98f33e6..2a688e4 100644 --- a/linden/indra/newview/llglslshader.cpp +++ b/linden/indra/newview/llglslshader.cpp @@ -31,32 +31,66 @@ #include "llviewerprecompiledheaders.h" -#include "llviewerwindow.h" #include "llfeaturemanager.h" #include "llglslshader.h" + +#include "llviewerwindow.h" #include "llviewercontrol.h" #include "pipeline.h" #include "llworld.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" +#include "llsky.h" +#include "llvosky.h" +#include "llglimmediate.h" + +#if LL_DARWIN +#include "OpenGL/OpenGL.h" +#endif + +#ifdef LL_RELEASE_FOR_DOWNLOAD +#define UNIFORM_ERRS llwarns +#else +#define UNIFORM_ERRS llerrs +#endif + +// Lots of STL stuff in here, using namespace std to keep things more readable +using std::vector; +using std::pair; +using std::make_pair; +using std::string; +/* //utility shader objects (not shader programs) +GLhandleARB gSumLightsVertex; GLhandleARB gLightVertex; +GLhandleARB gLightFuncVertex; GLhandleARB gLightFragment; -GLhandleARB gScatterVertex; -GLhandleARB gScatterFragment; +GLhandleARB gWaterFogFragment; + +//utility WindLight shader objects (not shader programs) +GLhandleARB gWindLightVertex; +GLhandleARB gWindLightFragment; +GLhandleARB gGammaFragment; +*/ LLVector4 gShinyOrigin; //object shaders LLGLSLShader gObjectSimpleProgram; -LLGLSLShader gObjectAlphaProgram; -LLGLSLShader gObjectBumpProgram; +LLGLSLShader gObjectSimpleWaterProgram; +LLGLSLShader gObjectFullbrightProgram; +LLGLSLShader gObjectFullbrightWaterProgram; + +LLGLSLShader gObjectFullbrightShinyProgram; LLGLSLShader gObjectShinyProgram; +LLGLSLShader gObjectShinyWaterProgram; //environment shaders LLGLSLShader gTerrainProgram; -LLGLSLShader gGlowProgram; -LLGLSLShader gGroundProgram; +LLGLSLShader gTerrainWaterProgram; LLGLSLShader gWaterProgram; +LLGLSLShader gUnderWaterProgram; //interface shaders LLGLSLShader gHighlightProgram; @@ -66,108 +100,382 @@ GLhandleARB gAvatarSkinVertex; //avatar shader handles LLGLSLShader gAvatarProgram; +LLGLSLShader gAvatarWaterProgram; LLGLSLShader gAvatarEyeballProgram; LLGLSLShader gAvatarPickProgram; +// WindLight shader handles +LLGLSLShader gWLSkyProgram; +LLGLSLShader gWLCloudProgram; + +// Effects Shaders +LLGLSLShader gGlowProgram; +LLGLSLShader gGlowExtractProgram; +LLGLSLShader gPostColorFilterProgram; +LLGLSLShader gPostNightVisionProgram; + //current avatar shader parameter pointer GLint gAvatarMatrixParam; -GLint gMaterialIndex; -GLint gSpecularIndex; S32 LLShaderMgr::sVertexShaderLevel[SHADER_COUNT] = { 0 }; -S32 LLShaderMgr::sMaxVertexShaderLevel[SHADER_COUNT] = { 0 }; -//glsl parameter tables -const char* LLShaderMgr::sReservedAttribs[] = +S32 LLShaderMgr::sMaxAvatarShaderLevel = 0; + +std::map LLShaderMgr::sShaderObjects; +vector LLShaderMgr::sReservedAttribs; +vector LLShaderMgr::sWLUniforms; +vector LLShaderMgr::sTerrainUniforms; +vector LLShaderMgr::sReservedUniforms; +vector LLShaderMgr::sShinyUniforms; +vector LLShaderMgr::sWaterUniforms; +vector LLShaderMgr::sGlowUniforms; +vector LLShaderMgr::sGlowExtractUniforms; +vector LLShaderMgr::sAvatarAttribs; +vector LLShaderMgr::sAvatarUniforms; +//vector< GLhandleARB > LLShaderMgr::sBaseObjects; + +/// Make sure WL Sky is the first program +LLGLSLShader * const LLShaderMgr::sShaderList[] = { - "materialColor", - "specularColor", - "binormal" + &gWLSkyProgram, + &gWLCloudProgram, + &gAvatarProgram, + &gObjectShinyProgram, + &gWaterProgram, + &gAvatarEyeballProgram, + &gObjectSimpleProgram, + &gObjectFullbrightProgram, + &gObjectFullbrightShinyProgram, + &gTerrainProgram, + &gTerrainWaterProgram, + &gObjectSimpleWaterProgram, + &gObjectFullbrightWaterProgram, + &gAvatarWaterProgram, + &gObjectShinyWaterProgram, + &gUnderWaterProgram, }; +const size_t LLShaderMgr::sNumShaders = sizeof(sShaderList) / sizeof(sShaderList[0]); -U32 LLShaderMgr::sReservedAttribCount = LLShaderMgr::END_RESERVED_ATTRIBS; -const char* LLShaderMgr::sAvatarAttribs[] = +BOOL shouldChange(const LLVector4& v1, const LLVector4& v2) { - "weight", - "clothing", - "gWindDir", - "gSinWaveParams", - "gGravity" -}; + /*F32 dot = v1.mV[0] * v2.mV[0] + + v1.mV[1] * v2.mV[1] + + v1.mV[2] * v2.mV[2] + + v1.mV[3] * v2.mV[3]; -U32 LLShaderMgr::sAvatarAttribCount = sizeof(LLShaderMgr::sAvatarAttribs)/sizeof(char*); + F32 mag = v1.mV[0] * v1.mV[0] + + v1.mV[1] * v1.mV[1] + + v1.mV[2] * v1.mV[2] + + v1.mV[3] * v1.mV[3]; -const char* LLShaderMgr::sAvatarUniforms[] = -{ - "matrixPalette" -}; + F32 val = (dot/mag); -U32 LLShaderMgr::sAvatarUniformCount = 1; + if (val > 2.0f || val < 0.1f) + { + return TRUE; + } -const char* LLShaderMgr::sReservedUniforms[] = -{ - "diffuseMap", - "specularMap", - "bumpMap", - "environmentMap", - "scatterMap" -}; + return FALSE;*/ -U32 LLShaderMgr::sReservedUniformCount = LLShaderMgr::END_RESERVED_UNIFORMS; + return v1 != v2; +} -const char* LLShaderMgr::sTerrainUniforms[] = +LLShaderFeatures::LLShaderFeatures() +: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false), +hasTransport(false), hasSkinning(false), hasAtmospherics(false), isSpecular(false), +hasGamma(false), hasLighting(false), calculatesAtmospherics(false) { - "detail0", - "detail1", - "alphaRamp" -}; +} -U32 LLShaderMgr::sTerrainUniformCount = sizeof(LLShaderMgr::sTerrainUniforms)/sizeof(char*); +void LLShaderMgr::initAttribsAndUniforms(void) +{ + if (sReservedAttribs.empty()) + { + sReservedAttribs.push_back("materialColor"); + sReservedAttribs.push_back("specularColor"); + sReservedAttribs.push_back("binormal"); + + sAvatarAttribs.reserve(5); + sAvatarAttribs.push_back("weight"); + sAvatarAttribs.push_back("clothing"); + sAvatarAttribs.push_back("gWindDir"); + sAvatarAttribs.push_back("gSinWaveParams"); + sAvatarAttribs.push_back("gGravity"); + + sAvatarUniforms.push_back("matrixPalette"); + + sReservedUniforms.reserve(24); + sReservedUniforms.push_back("diffuseMap"); + sReservedUniforms.push_back("specularMap"); + sReservedUniforms.push_back("bumpMap"); + sReservedUniforms.push_back("environmentMap"); + sReservedUniforms.push_back("cloude_noise_texture"); + sReservedUniforms.push_back("fullbright"); + sReservedUniforms.push_back("lightnorm"); + sReservedUniforms.push_back("sunlight_color"); + sReservedUniforms.push_back("ambient"); + sReservedUniforms.push_back("blue_horizon"); + sReservedUniforms.push_back("blue_density"); + sReservedUniforms.push_back("haze_horizon"); + sReservedUniforms.push_back("haze_density"); + sReservedUniforms.push_back("cloud_shadow"); + sReservedUniforms.push_back("density_multiplier"); + sReservedUniforms.push_back("distance_multiplier"); + sReservedUniforms.push_back("max_y"); + sReservedUniforms.push_back("glow"); + sReservedUniforms.push_back("cloud_color"); + sReservedUniforms.push_back("cloud_pos_density1"); + sReservedUniforms.push_back("cloud_pos_density2"); + sReservedUniforms.push_back("cloud_scale"); + sReservedUniforms.push_back("gamma"); + sReservedUniforms.push_back("scene_light_strength"); + + sWLUniforms.push_back("camPosLocal"); + + sTerrainUniforms.reserve(5); + sTerrainUniforms.push_back("detail_0"); + sTerrainUniforms.push_back("detail_1"); + sTerrainUniforms.push_back("detail_2"); + sTerrainUniforms.push_back("detail_3"); + sTerrainUniforms.push_back("alpha_ramp"); + + sGlowUniforms.push_back("glowDelta"); + sGlowUniforms.push_back("glowStrength"); + + sGlowExtractUniforms.push_back("minLuminance"); + sGlowExtractUniforms.push_back("maxExtractAlpha"); + sGlowExtractUniforms.push_back("lumWeights"); + sGlowExtractUniforms.push_back("warmthWeights"); + sGlowExtractUniforms.push_back("warmthAmount"); + + sShinyUniforms.push_back("origin"); + + sWaterUniforms.reserve(12); + sWaterUniforms.push_back("screenTex"); + sWaterUniforms.push_back("screenDepth"); + sWaterUniforms.push_back("refTex"); + sWaterUniforms.push_back("eyeVec"); + sWaterUniforms.push_back("time"); + sWaterUniforms.push_back("d1"); + sWaterUniforms.push_back("d2"); + sWaterUniforms.push_back("lightDir"); + sWaterUniforms.push_back("specular"); + sWaterUniforms.push_back("lightExp"); + sWaterUniforms.push_back("fogCol"); + sWaterUniforms.push_back("kd"); + sWaterUniforms.push_back("refScale"); + sWaterUniforms.push_back("waterHeight"); + } +} -const char* LLShaderMgr::sGlowUniforms[] = +BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) { - "delta" -}; + llassert_always(shader != NULL); + LLShaderFeatures *features = & shader->mFeatures; + + ////////////////////////////////////// + // Attach Vertex Shader Features First + ////////////////////////////////////// + + // NOTE order of shader object attaching is VERY IMPORTANT!!! + if (features->calculatesAtmospherics) + { + if (!shader->attachObject("windlight/atmosphericsVarsV.glsl")) + { + return FALSE; + } + } -U32 LLShaderMgr::sGlowUniformCount = sizeof(LLShaderMgr::sGlowUniforms)/sizeof(char*); + if (features->calculatesLighting) + { + if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl")) + { + return FALSE; + } + + if (features->isSpecular) + { + if (!shader->attachObject("lighting/lightFuncSpecularV.glsl")) + { + return FALSE; + } + + if (!shader->attachObject("lighting/sumLightsSpecularV.glsl")) + { + return FALSE; + } + + if (!shader->attachObject("lighting/lightSpecularV.glsl")) + { + return FALSE; + } + } + else + { + if (!shader->attachObject("lighting/lightFuncV.glsl")) + { + return FALSE; + } + + if (!shader->attachObject("lighting/sumLightsV.glsl")) + { + return FALSE; + } + + if (!shader->attachObject("lighting/lightV.glsl")) + { + return FALSE; + } + } + } + + // NOTE order of shader object attaching is VERY IMPORTANT!!! + if (features->calculatesAtmospherics) + { + if (!shader->attachObject("windlight/atmosphericsV.glsl")) + { + return FALSE; + } + } -const char* LLShaderMgr::sShinyUniforms[] = -{ - "origin" -}; + if (features->hasSkinning) + { + if (!shader->attachObject("avatar/avatarSkinV.glsl")) + { + return FALSE; + } + } + + /////////////////////////////////////// + // Attach Fragment Shader Features Next + /////////////////////////////////////// -U32 LLShaderMgr::sShinyUniformCount = sizeof(LLShaderMgr::sShinyUniforms)/sizeof(char*); + if(features->calculatesAtmospherics) + { + if (!shader->attachObject("windlight/atmosphericsVarsF.glsl")) + { + return FALSE; + } + } -const char* LLShaderMgr::sWaterUniforms[] = -{ - "screenTex", - "eyeVec", - "time", - "d1", - "d2", - "lightDir", - "specular", - "lightExp", - "fbScale", - "refScale" -}; + // NOTE order of shader object attaching is VERY IMPORTANT!!! + if (features->hasGamma) + { + if (!shader->attachObject("windlight/gammaF.glsl")) + { + return FALSE; + } + } + + if (features->hasAtmospherics) + { + if (!shader->attachObject("windlight/atmosphericsF.glsl")) + { + return FALSE; + } + } + + if (features->hasTransport) + { + if (!shader->attachObject("windlight/transportF.glsl")) + { + return FALSE; + } -U32 LLShaderMgr::sWaterUniformCount = sizeof(LLShaderMgr::sWaterUniforms)/sizeof(char*); + // Test hasFullbright and hasShiny and attach fullbright and + // fullbright shiny atmos transport if we split them out. + } + + // NOTE order of shader object attaching is VERY IMPORTANT!!! + if (features->hasWaterFog) + { + if (!shader->attachObject("environment/waterFogF.glsl")) + { + return FALSE; + } + } + + if (features->hasLighting) + { + + if (features->hasWaterFog) + { + if (!shader->attachObject("lighting/lightWaterF.glsl")) + { + return FALSE; + } + } + + else + { + if (!shader->attachObject("lighting/lightF.glsl")) + { + return FALSE; + } + } + } + + // NOTE order of shader object attaching is VERY IMPORTANT!!! + else if (features->isFullbright) + { + + if (features->hasWaterFog) + { + if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl")) + { + return FALSE; + } + } + + else if (features->isShiny) + { + if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl")) + { + return FALSE; + } + } + + else + { + if (!shader->attachObject("lighting/lightFullbrightF.glsl")) + { + return FALSE; + } + } + } + // NOTE order of shader object attaching is VERY IMPORTANT!!! + else if (features->isShiny) + { + + if (features->hasWaterFog) + { + if (!shader->attachObject("lighting/lightShinyWaterF.glsl")) + { + return FALSE; + } + } + + else + { + if (!shader->attachObject("lighting/lightShinyF.glsl")) + { + return FALSE; + } + } + } + return TRUE; +} //============================================================================ // Set Levels S32 LLShaderMgr::getVertexShaderLevel(S32 type) { - return sVertexShaderLevel[type]; + return LLPipeline::sDisableShaders ? 0 : sVertexShaderLevel[type]; } -S32 LLShaderMgr::getMaxVertexShaderLevel(S32 type) -{ - return sMaxVertexShaderLevel[type]; -} //============================================================================ // Load Shader @@ -176,7 +484,7 @@ static LLString get_object_log(GLhandleARB ret) { LLString res; - //get log length + //get log length GLint length; glGetObjectParameterivARB(ret, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); if (length > 0) @@ -203,16 +511,16 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns) } } -GLhandleARB LLShaderMgr::loadShader(const LLString& filename, S32 cls, GLenum type) +GLhandleARB LLShaderMgr::loadShaderFile(const LLString& filename, S32 & shader_level, GLenum type) { GLenum error; error = glGetError(); if (error != GL_NO_ERROR) { - llwarns << "GL ERROR entering loadShader(): " << error << llendl; + llwarns << "GL ERROR entering loadShaderFile(): " << error << llendl; } - llinfos << "Loading shader file: " << filename << llendl; + llinfos << "Loading shader file: " << filename << " class " << shader_level << llendl; if (filename.empty()) { @@ -223,7 +531,7 @@ GLhandleARB LLShaderMgr::loadShader(const LLString& filename, S32 cls, GLenum ty //read in from file FILE* file = NULL; - S32 try_gpu_class = sVertexShaderLevel[cls]; + S32 try_gpu_class = shader_level; S32 gpu_class; //find the most relevant file @@ -233,10 +541,13 @@ GLhandleARB LLShaderMgr::loadShader(const LLString& filename, S32 cls, GLenum ty fname << gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); fname << gpu_class << "/" << filename; -// llinfos << "Looking in " << fname.str().c_str() << llendl; + llinfos << "Looking in " << fname.str().c_str() << llendl; file = fopen(fname.str().c_str(), "r"); /* Flawfinder: ignore */ if (file) { +#if !LL_RELEASE_FOR_DOWNLOAD + llinfos << "Found shader file: " << fname.str() << llendl; +#endif break; // done } } @@ -258,7 +569,7 @@ GLhandleARB LLShaderMgr::loadShader(const LLString& filename, S32 cls, GLenum ty while(fgets((char *)buff, 1024, file) != NULL && count < (sizeof(buff)/sizeof(buff[0]))) { text[count++] = (GLcharARB *)strdup((char *)buff); - } + } fclose(file); //create shader object @@ -314,46 +625,21 @@ GLhandleARB LLShaderMgr::loadShader(const LLString& filename, S32 cls, GLenum ty stop_glerror(); //successfully loaded, save results -#if 1 // 1.9.1 - if (ret) - { - sVertexShaderLevel[cls] = try_gpu_class; - } - else - { - if (sVertexShaderLevel[cls] > 1) - { - sVertexShaderLevel[cls] = sVertexShaderLevel[cls] - 1; - ret = loadShader(filename,cls,type); - if (ret && sMaxVertexShaderLevel[cls] > sVertexShaderLevel[cls]) - { - sMaxVertexShaderLevel[cls] = sVertexShaderLevel[cls]; - } - } - } -#else if (ret) { - S32 max = -1; - /*if (try_gpu_class == sMaxVertexShaderLevel[cls]) - { - max = gpu_class; - }*/ - saveVertexShaderLevel(cls,try_gpu_class,max); + // Add shader file to map + sShaderObjects[filename] = ret; + shader_level = try_gpu_class; } else { - if (sVertexShaderLevel[cls] > 1) + if (shader_level > 1) { - sVertexShaderLevel[cls] = sVertexShaderLevel[cls] - 1; - ret = loadShader(f,cls,type); - if (ret && sMaxVertexShaderLevel[cls] > sVertexShaderLevel[cls]) - { - saveVertexShaderLevel(cls, sVertexShaderLevel[cls], sVertexShaderLevel[cls]); - } + shader_level--; + return loadShaderFile(filename,shader_level,type); } + llwarns << "Failed to load " << filename << llendl; } -#endif return ret; } @@ -369,6 +655,29 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors) llwarns << "GLSL Linker Error:" << llendl; } +// NOTE: Removing LL_DARWIN block as it doesn't seem to actually give the correct answer, +// but want it for reference once I move it. +#if 0 + // Force an evaluation of the gl state so the driver can tell if the shader will run in hardware or software + // per Apple's suggestion + glBegin(gGL.mMode); + glEnd(); + + // Query whether the shader can or cannot run in hardware + // http://developer.apple.com/qa/qa2007/qa1502.html + long vertexGPUProcessing; + CGLContextObj ctx = CGLGetCurrentContext(); + CGLGetParameter (ctx, kCGLCPGPUVertexProcessing, &vertexGPUProcessing); + long fragmentGPUProcessing; + CGLGetParameter (ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing); + if (!fragmentGPUProcessing || !vertexGPUProcessing) + { + llwarns << "GLSL Linker: Running in Software:" << llendl; + success = GL_FALSE; + suppress_errors = FALSE; + } + +#else LLString log = get_object_log(obj); LLString::toLower(log); if (log.find("software") != LLString::npos) @@ -377,6 +686,7 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors) success = GL_FALSE; suppress_errors = FALSE; } +#endif if (!suppress_errors) { dumpObjectLog(obj, !success); @@ -413,15 +723,24 @@ void LLShaderMgr::setShaders() { return; } + // Make sure the compiled shader map is cleared before we recompile shaders. + sShaderObjects.clear(); - if (gGLManager.mHasFramebufferObject) + initAttribsAndUniforms(); + gPipeline.releaseGLBuffers(); + + if (gGLManager.mHasFramebufferObject && + gSavedSettings.getBOOL("VertexShaderEnable")) { LLPipeline::sDynamicReflections = gSavedSettings.getBOOL("RenderDynamicReflections") && gGLManager.mHasCubeMap && gFeatureManagerp->isFeatureAvailable("RenderCubeMap"); - LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); + LLPipeline::sWaterReflections = gGLManager.mHasCubeMap; + LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); } else { - LLPipeline::sDynamicReflections = LLPipeline::sRenderGlow = FALSE; + LLPipeline::sDynamicReflections = + LLPipeline::sRenderGlow = + LLPipeline::sWaterReflections = FALSE; } //hack to reset buffers that change behavior with shaders @@ -436,30 +755,67 @@ void LLShaderMgr::setShaders() gPipeline.setLightingDetail(-1); // Shaders - for (S32 i=0; iisFeatureAvailable("VertexShaderEnable") + && gSavedSettings.getBOOL("VertexShaderEnable")) { S32 light_class = 2; S32 env_class = 2; - S32 obj_class = 0; + S32 obj_class = 2; + S32 effect_class = 2; + S32 wl_class = 2; + S32 water_class = 2; + + if (!gSavedSettings.getBOOL("WindLightUseAtmosShaders")) + { + // user has disabled WindLight in their settings, downgrade + // windlight shaders to stub versions. + wl_class = 1; + + // if class one or less, turn off more shaders + // since higher end cards won't see any real gain + // from turning off most of the shaders, + // but class one would + // TODO: Make water on class one cards color things + // beneath it properly + if(gFeatureManagerp->getGPUClass() < GPU_CLASS_2) + { + // use lesser water and other stuff + light_class = 2; + env_class = 0; + obj_class = 0; + effect_class = 1; + water_class = 1; + } + } + + if(!gSavedSettings.getBOOL("EnableRippleWater")) + { + water_class = 0; + } - if (gPipeline.getLightingDetail() == 0) + // Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders + if (sVertexShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull()) { - light_class = 1; + gSky.mVOSkyp->forceSkyUpdate(); } + // Load lighting shaders sVertexShaderLevel[SHADER_LIGHTING] = light_class; - sMaxVertexShaderLevel[SHADER_LIGHTING] = light_class; + sVertexShaderLevel[SHADER_INTERFACE] = light_class; sVertexShaderLevel[SHADER_ENVIRONMENT] = env_class; - sMaxVertexShaderLevel[SHADER_ENVIRONMENT] = env_class; + sVertexShaderLevel[SHADER_WATER] = water_class; sVertexShaderLevel[SHADER_OBJECT] = obj_class; - sMaxVertexShaderLevel[SHADER_OBJECT] = obj_class; + sVertexShaderLevel[SHADER_EFFECT] = effect_class; + sVertexShaderLevel[SHADER_WINDLIGHT] = wl_class; - BOOL loaded = loadShadersLighting(); + BOOL loaded = loadBasicShaders(); if (loaded) { @@ -468,34 +824,32 @@ void LLShaderMgr::setShaders() // Load all shaders to set max levels loadShadersEnvironment(); + loadShadersWater(); loadShadersObject(); + loadShadersWindLight(); + loadShadersEffects(); + loadShadersInterface(); + // Load max avatar shaders to set the max level sVertexShaderLevel[SHADER_AVATAR] = 3; - sMaxVertexShaderLevel[SHADER_AVATAR] = 3; + sMaxAvatarShaderLevel = 3; loadShadersAvatar(); - - // Load shaders to correct levels - if (!(gSavedSettings.getBOOL("RenderRippleWater") && gGLManager.mHasCubeMap && gFeatureManagerp->isFeatureAvailable("RenderCubeMap"))) - { - if (gSavedSettings.getBOOL("RenderGlow")) - { - sVertexShaderLevel[SHADER_ENVIRONMENT] = 1; - } - else - { - sVertexShaderLevel[SHADER_ENVIRONMENT] = 0; - loadShadersEnvironment(); // unloads - } - } - -#if LL_DARWIN // force avatar shaders off for mac + +#if 0 && LL_DARWIN // force avatar shaders off for mac sVertexShaderLevel[SHADER_AVATAR] = 0; - sMaxVertexShaderLevel[SHADER_AVATAR] = 0; + sMaxAvatarShaderLevel = 0; #else if (gSavedSettings.getBOOL("RenderAvatarVP")) { - S32 avatar = gSavedSettings.getS32("RenderAvatarMode"); - S32 avatar_class = 1 + avatar; + BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth"); + S32 avatar_class = 1; + + // cloth is a class3 shader + if(avatar_cloth) + { + avatar_class = 3; + } + // Set the actual level sVertexShaderLevel[SHADER_AVATAR] = avatar_class; loadShadersAvatar(); @@ -505,14 +859,21 @@ void LLShaderMgr::setShaders() { gSavedSettings.setBOOL("RenderAvatarVP", FALSE); } - avatar = llmax(sVertexShaderLevel[SHADER_AVATAR]-1,0); - gSavedSettings.setS32("RenderAvatarMode", avatar); + if(llmax(sVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3) + { + avatar_cloth = true; + } + else + { + avatar_cloth = false; + } + gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth); } } else { sVertexShaderLevel[SHADER_AVATAR] = 0; - gSavedSettings.setS32("RenderAvatarMode", 0); + gSavedSettings.setBOOL("RenderAvatarCloth", FALSE); loadShadersAvatar(); // unloads } #endif @@ -521,310 +882,494 @@ void LLShaderMgr::setShaders() { gPipeline.mVertexShadersEnabled = FALSE; gPipeline.mVertexShadersLoaded = 0; + sVertexShaderLevel[SHADER_LIGHTING] = 0; + sVertexShaderLevel[SHADER_INTERFACE] = 0; + sVertexShaderLevel[SHADER_ENVIRONMENT] = 0; + sVertexShaderLevel[SHADER_WATER] = 0; + sVertexShaderLevel[SHADER_OBJECT] = 0; + sVertexShaderLevel[SHADER_EFFECT] = 0; + sVertexShaderLevel[SHADER_WINDLIGHT] = 0; } } + else + { + gPipeline.mVertexShadersEnabled = FALSE; + gPipeline.mVertexShadersLoaded = 0; + sVertexShaderLevel[SHADER_LIGHTING] = 0; + sVertexShaderLevel[SHADER_INTERFACE] = 0; + sVertexShaderLevel[SHADER_ENVIRONMENT] = 0; + sVertexShaderLevel[SHADER_WATER] = 0; + sVertexShaderLevel[SHADER_OBJECT] = 0; + sVertexShaderLevel[SHADER_EFFECT] = 0; + sVertexShaderLevel[SHADER_WINDLIGHT] = 0; + } + if (gViewerWindow) { gViewerWindow->setCursor(UI_CURSOR_ARROW); } + gPipeline.createGLBuffers(); } void LLShaderMgr::unloadShaders() { gObjectSimpleProgram.unload(); + gObjectSimpleWaterProgram.unload(); + gObjectFullbrightProgram.unload(); + gObjectFullbrightWaterProgram.unload(); + gObjectShinyProgram.unload(); - gObjectBumpProgram.unload(); - gObjectAlphaProgram.unload(); + gObjectFullbrightShinyProgram.unload(); + gObjectShinyWaterProgram.unload(); gWaterProgram.unload(); + gUnderWaterProgram.unload(); gTerrainProgram.unload(); + gTerrainWaterProgram.unload(); gGlowProgram.unload(); - gGroundProgram.unload(); + gGlowExtractProgram.unload(); gAvatarProgram.unload(); + gAvatarWaterProgram.unload(); gAvatarEyeballProgram.unload(); gAvatarPickProgram.unload(); gHighlightProgram.unload(); + gWLSkyProgram.unload(); + gWLCloudProgram.unload(); + + gPostColorFilterProgram.unload(); + gPostNightVisionProgram.unload(); + sVertexShaderLevel[SHADER_LIGHTING] = 0; sVertexShaderLevel[SHADER_OBJECT] = 0; sVertexShaderLevel[SHADER_AVATAR] = 0; sVertexShaderLevel[SHADER_ENVIRONMENT] = 0; + sVertexShaderLevel[SHADER_WATER] = 0; sVertexShaderLevel[SHADER_INTERFACE] = 0; - gLightVertex = gLightFragment = gScatterVertex = gScatterFragment = 0; gPipeline.mVertexShadersLoaded = 0; } -BOOL LLShaderMgr::loadShadersLighting() +BOOL LLShaderMgr::loadBasicShaders() { - // Load light dependency shaders first + // Load basic dependency shaders first // All of these have to load for any shaders to function - std::string lightvertex = "lighting/lightV.glsl"; - //get default light function implementation - gLightVertex = loadShader(lightvertex, SHADER_LIGHTING, GL_VERTEX_SHADER_ARB); - if( !gLightVertex ) +#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 + // class zero we're not going to think about + // since a class zero card COULD be a ridiculous new card + // and old cards should have the features masked + if(gFeatureManagerp->getGPUClass() == GPU_CLASS_1) { - llwarns << "Failed to load " << lightvertex << llendl; - return FALSE; + sum_lights_class = 2; } - - std::string lightfragment = "lighting/lightF.glsl"; - gLightFragment = loadShader(lightfragment, SHADER_LIGHTING, GL_FRAGMENT_SHADER_ARB); - if ( !gLightFragment ) +#endif + + // If we have sun and moon only checked, then only sum those lights. + if (gPipeline.getLightingDetail() == 0) { - llwarns << "Failed to load " << lightfragment << llendl; - return FALSE; + sum_lights_class = 1; } - // NOTE: Scatter shaders use the ENVIRONMENT detail level - - std::string scattervertex = "environment/scatterV.glsl"; - gScatterVertex = loadShader(scattervertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB); - if ( !gScatterVertex ) + // Load the Basic Vertex Shaders at the appropriate level. + // (in order of shader function call depth for reference purposes, deepest level first) + + vector< pair > shaders; + shaders.reserve(10); + shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "lighting/lightFuncV.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) ); + shaders.push_back( make_pair( "lighting/lightV.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) ); + shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) ); + + // 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++) { - llwarns << "Failed to load " << scattervertex << llendl; - return FALSE; + // Note usage of GL_VERTEX_SHADER_ARB + if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB) == 0) + { + return FALSE; + } } - std::string scatterfragment = "environment/scatterF.glsl"; - gScatterFragment = loadShader(scatterfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB); - if ( !gScatterFragment ) + // Load the Basic Fragment Shaders at the appropriate level. + // (in order of shader function call depth for reference purposes, deepest level first) + + shaders.clear(); + shaders.reserve(12); + shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "windlight/gammaF.glsl", sVertexShaderLevel[SHADER_WINDLIGHT]) ); + shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "windlight/transportF.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) ); + shaders.push_back( make_pair( "environment/waterFogF.glsl", sVertexShaderLevel[SHADER_WATER] ) ); + shaders.push_back( make_pair( "lighting/lightF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/lightWaterF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/lightShinyF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); + + for (U32 i = 0; i < shaders.size(); i++) { - llwarns << "Failed to load " << scatterfragment << llendl; - return FALSE; + // Note usage of GL_FRAGMENT_SHADER_ARB + if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB) == 0) + { + return FALSE; + } } - + return TRUE; } BOOL LLShaderMgr::loadShadersEnvironment() { - GLhandleARB baseObjects[] = - { - gLightFragment, - gLightVertex, - gScatterFragment, - gScatterVertex - }; - S32 baseCount = 4; - BOOL success = TRUE; if (sVertexShaderLevel[SHADER_ENVIRONMENT] == 0) { - gWaterProgram.unload(); - gGroundProgram.unload(); gTerrainProgram.unload(); - gGlowProgram.unload(); return FALSE; } - + if (success) { - //load water vertex shader - std::string waterfragment = "environment/waterF.glsl"; - std::string watervertex = "environment/waterV.glsl"; - gWaterProgram.mProgramObject = glCreateProgramObjectARB(); - gWaterProgram.attachObjects(baseObjects, baseCount); - gWaterProgram.attachObject(loadShader(watervertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB)); - gWaterProgram.attachObject(loadShader(waterfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB)); + gTerrainProgram.mName = "Terrain Shader"; + gTerrainProgram.mFeatures.calculatesLighting = true; + gTerrainProgram.mFeatures.calculatesAtmospherics = true; + gTerrainProgram.mFeatures.hasAtmospherics = true; + gTerrainProgram.mFeatures.hasGamma = true; + gTerrainProgram.mShaderFiles.clear(); + gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB)); + gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); + gTerrainProgram.mShaderLevel = sVertexShaderLevel[SHADER_ENVIRONMENT]; + success = gTerrainProgram.createShader(NULL, &sTerrainUniforms); + } - success = gWaterProgram.mapAttributes(); - if (success) - { - success = gWaterProgram.mapUniforms(sWaterUniforms, sWaterUniformCount); - } - if (!success) - { - llwarns << "Failed to load " << watervertex << llendl; - } + if (!success) + { + sVertexShaderLevel[SHADER_ENVIRONMENT] = 0; + return FALSE; } - if (success) + + if (gWorldPointer) { - //load ground vertex shader - std::string groundvertex = "environment/groundV.glsl"; - std::string groundfragment = "environment/groundF.glsl"; - gGroundProgram.mProgramObject = glCreateProgramObjectARB(); - gGroundProgram.attachObjects(baseObjects, baseCount); - gGroundProgram.attachObject(loadShader(groundvertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB)); - gGroundProgram.attachObject(loadShader(groundfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB)); + gWorldPointer->updateWaterObjects(); + } - success = gGroundProgram.mapAttributes(); - if (success) - { - success = gGroundProgram.mapUniforms(); - } - if (!success) - { - llwarns << "Failed to load " << groundvertex << llendl; - } + return TRUE; +} + +BOOL LLShaderMgr::loadShadersWater() +{ + BOOL success = TRUE; + BOOL terrainWaterSuccess = TRUE; + + if (sVertexShaderLevel[SHADER_WATER] == 0) + { + gWaterProgram.unload(); + gUnderWaterProgram.unload(); + gTerrainWaterProgram.unload(); + return FALSE; } if (success) { - //load terrain vertex shader - std::string terrainvertex = "environment/terrainV.glsl"; - std::string terrainfragment = "environment/terrainF.glsl"; - gTerrainProgram.mProgramObject = glCreateProgramObjectARB(); - gTerrainProgram.attachObjects(baseObjects, baseCount); - gTerrainProgram.attachObject(loadShader(terrainvertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB)); - gTerrainProgram.attachObject(loadShader(terrainfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB)); - success = gTerrainProgram.mapAttributes(); - if (success) - { - success = gTerrainProgram.mapUniforms(sTerrainUniforms, sTerrainUniformCount); - } - if (!success) - { - llwarns << "Failed to load " << terrainvertex << llendl; - } + // load water shader + gWaterProgram.mName = "Water Shader"; + gWaterProgram.mFeatures.calculatesAtmospherics = true; + gWaterProgram.mFeatures.hasGamma = true; + gWaterProgram.mFeatures.hasTransport = true; + gWaterProgram.mShaderFiles.clear(); + gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB)); + gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_WATER]; + success = gWaterProgram.createShader(NULL, &sWaterUniforms); } if (success) { - //load glow shader - std::string glowvertex = "environment/glowV.glsl"; - std::string glowfragment = "environment/glowF.glsl"; - gGlowProgram.mProgramObject = glCreateProgramObjectARB(); - gGlowProgram.attachObjects(baseObjects, baseCount); - gGlowProgram.attachObject(loadShader(glowvertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB)); - gGlowProgram.attachObject(loadShader(glowfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB)); - success = gGlowProgram.mapAttributes(); - if (success) - { - success = gGlowProgram.mapUniforms(sGlowUniforms, sGlowUniformCount); - } - if (!success) - { - llwarns << "Failed to load " << glowvertex << llendl; - } + //load under water vertex shader + gUnderWaterProgram.mName = "Underwater Shader"; + gUnderWaterProgram.mFeatures.calculatesAtmospherics = true; + gUnderWaterProgram.mShaderFiles.clear(); + gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB)); + gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gUnderWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_WATER]; + gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + + success = gUnderWaterProgram.createShader(NULL, &sWaterUniforms); } - if( !success ) + if (success) { - sVertexShaderLevel[SHADER_ENVIRONMENT] = 0; - sMaxVertexShaderLevel[SHADER_ENVIRONMENT] = 0; + //load terrain water shader + gTerrainWaterProgram.mName = "Terrain Water Shader"; + gTerrainWaterProgram.mFeatures.calculatesLighting = true; + gTerrainWaterProgram.mFeatures.calculatesAtmospherics = true; + gTerrainWaterProgram.mFeatures.hasAtmospherics = true; + gTerrainWaterProgram.mFeatures.hasWaterFog = true; + gTerrainWaterProgram.mShaderFiles.clear(); + gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB)); + gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gTerrainWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_ENVIRONMENT]; + gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, &sTerrainUniforms); + } + + /// Keep track of water shader levels + if (gWaterProgram.mShaderLevel != sVertexShaderLevel[SHADER_WATER] + || gUnderWaterProgram.mShaderLevel != sVertexShaderLevel[SHADER_WATER]) + { + sVertexShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel); + } + + if (!success) + { + sVertexShaderLevel[SHADER_WATER] = 0; return FALSE; } + + // if we failed to load the terrain water shaders and we need them (using class2 water), + // then drop down to class1 water. + if (sVertexShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess) + { + sVertexShaderLevel[SHADER_WATER]--; + return loadShadersWater(); + } if (gWorldPointer) { gWorldPointer->updateWaterObjects(); } - return TRUE; } -BOOL LLShaderMgr::loadShadersObject() +BOOL LLShaderMgr::loadShadersEffects() { - GLhandleARB baseObjects[] = - { - gLightFragment, - gLightVertex, - gScatterFragment, - gScatterVertex - }; - S32 baseCount = 4; - BOOL success = TRUE; - if (sVertexShaderLevel[SHADER_OBJECT] == 0) + if (sVertexShaderLevel[SHADER_EFFECT] == 0) { - gObjectShinyProgram.unload(); - gObjectSimpleProgram.unload(); - gObjectBumpProgram.unload(); - gObjectAlphaProgram.unload(); + gGlowProgram.unload(); + gGlowExtractProgram.unload(); + gPostColorFilterProgram.unload(); + gPostNightVisionProgram.unload(); return FALSE; } -#if 0 if (success) { - //load object (volume/tree) vertex shader - std::string simplevertex = "objects/simpleV.glsl"; - std::string simplefragment = "objects/simpleF.glsl"; - gObjectSimpleProgram.mProgramObject = glCreateProgramObjectARB(); - gObjectSimpleProgram.attachObjects(baseObjects, baseCount); - gObjectSimpleProgram.attachObject(loadShader(simplevertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB)); - gObjectSimpleProgram.attachObject(loadShader(simplefragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB)); - success = gObjectSimpleProgram.mapAttributes(); - if (success) - { - success = gObjectSimpleProgram.mapUniforms(); - } - if( !success ) + gGlowProgram.mName = "Glow Shader (Post)"; + gGlowProgram.mShaderFiles.clear(); + gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB)); + gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB)); + gGlowProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT]; + success = gGlowProgram.createShader(NULL, &sGlowUniforms); + if (!success) { - llwarns << "Failed to load " << simplevertex << llendl; + LLPipeline::sRenderGlow = FALSE; } } if (success) { - //load object bumpy vertex shader - std::string bumpshinyvertex = "objects/bumpshinyV.glsl"; - std::string bumpshinyfragment = "objects/bumpshinyF.glsl"; - gObjectBumpProgram.mProgramObject = glCreateProgramObjectARB(); - gObjectBumpProgram.attachObjects(baseObjects, baseCount); - gObjectBumpProgram.attachObject(loadShader(bumpshinyvertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB)); - gObjectBumpProgram.attachObject(loadShader(bumpshinyfragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB)); - success = gObjectBumpProgram.mapAttributes(); - if (success) - { - success = gObjectBumpProgram.mapUniforms(); - } - if( !success ) + gGlowExtractProgram.mName = "Glow Extract Shader (Post)"; + gGlowExtractProgram.mShaderFiles.clear(); + gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB)); + gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB)); + gGlowExtractProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT]; + success = gGlowExtractProgram.createShader(NULL, &sGlowExtractUniforms); + if (!success) { - llwarns << "Failed to load " << bumpshinyvertex << llendl; + LLPipeline::sRenderGlow = FALSE; } } + +#if 0 + // disabling loading of postprocess shaders until we fix + // ATI sampler2DRect compatibility. + + //load Color Filter Shader + if (success) + { + vector shaderUniforms; + shaderUniforms.reserve(7); + shaderUniforms.push_back("RenderTexture"); + shaderUniforms.push_back("gamma"); + shaderUniforms.push_back("brightness"); + shaderUniforms.push_back("contrast"); + shaderUniforms.push_back("contrastBase"); + shaderUniforms.push_back("saturation"); + shaderUniforms.push_back("lumWeights"); + + gPostColorFilterProgram.mName = "Color Filter Shader (Post)"; + gPostColorFilterProgram.mShaderFiles.clear(); + gPostColorFilterProgram.mShaderFiles.push_back(make_pair("effects/colorFilterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gPostColorFilterProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB)); + gPostColorFilterProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT]; + success = gPostColorFilterProgram.createShader(NULL, &shaderUniforms); + } + + //load Night Vision Shader + if (success) + { + vector shaderUniforms; + shaderUniforms.reserve(5); + shaderUniforms.push_back("RenderTexture"); + shaderUniforms.push_back("NoiseTexture"); + shaderUniforms.push_back("brightMult"); + shaderUniforms.push_back("noiseStrength"); + shaderUniforms.push_back("lumWeights"); + + gPostNightVisionProgram.mName = "Night Vision Shader (Post)"; + gPostNightVisionProgram.mShaderFiles.clear(); + gPostNightVisionProgram.mShaderFiles.push_back(make_pair("effects/nightVisionF.glsl", GL_FRAGMENT_SHADER_ARB)); + gPostNightVisionProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB)); + gPostNightVisionProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT]; + success = gPostNightVisionProgram.createShader(NULL, &shaderUniforms); + } + #endif + + return success; + +} + +BOOL LLShaderMgr::loadShadersObject() +{ + BOOL success = TRUE; + + if (sVertexShaderLevel[SHADER_OBJECT] == 0) + { + gObjectShinyProgram.unload(); + gObjectFullbrightShinyProgram.unload(); + gObjectShinyWaterProgram.unload(); + gObjectSimpleProgram.unload(); + gObjectSimpleWaterProgram.unload(); + gObjectFullbrightProgram.unload(); + gObjectFullbrightWaterProgram.unload(); + return FALSE; + } if (success) { - //load object alpha vertex shader - std::string alphavertex = "objects/alphaV.glsl"; - std::string alphafragment = "objects/alphaF.glsl"; - gObjectAlphaProgram.mProgramObject = glCreateProgramObjectARB(); - gObjectAlphaProgram.attachObjects(baseObjects, baseCount); - gObjectAlphaProgram.attachObject(loadShader(alphavertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB)); - gObjectAlphaProgram.attachObject(loadShader(alphafragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleProgram.mName = "Simple Shader"; + gObjectSimpleProgram.mFeatures.calculatesLighting = true; + gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleProgram.mFeatures.hasGamma = true; + gObjectSimpleProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleProgram.mFeatures.hasLighting = true; + gObjectSimpleProgram.mShaderFiles.clear(); + gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; + success = gObjectSimpleProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectSimpleWaterProgram.mName = "Simple Water Shader"; + gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true; + gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectSimpleWaterProgram.mFeatures.hasWaterFog = true; + gObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true; + gObjectSimpleWaterProgram.mFeatures.hasLighting = true; + gObjectSimpleWaterProgram.mShaderFiles.clear(); + gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectSimpleWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; + gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectSimpleWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gObjectFullbrightProgram.mName = "Fullbright Shader"; + gObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightProgram.mFeatures.hasGamma = true; + gObjectFullbrightProgram.mFeatures.hasTransport = true; + gObjectFullbrightProgram.mFeatures.isFullbright = true; + gObjectFullbrightProgram.mShaderFiles.clear(); + gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; + success = gObjectFullbrightProgram.createShader(NULL, NULL); + } - success = gObjectAlphaProgram.mapAttributes(); - if (success) - { - success = gObjectAlphaProgram.mapUniforms(); - } - if( !success ) - { - llwarns << "Failed to load " << alphavertex << llendl; - } + if (success) + { + gObjectFullbrightWaterProgram.mName = "Fullbright Water Shader"; + gObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightWaterProgram.mFeatures.isFullbright = true; + gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; + gObjectFullbrightWaterProgram.mFeatures.hasTransport = true; + gObjectFullbrightWaterProgram.mShaderFiles.clear(); + gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; + gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectFullbrightWaterProgram.createShader(NULL, NULL); } -#endif if (success) { - //load shiny vertex shader - std::string shinyvertex = "objects/shinyV.glsl"; - std::string shinyfragment = "objects/shinyF.glsl"; - gObjectShinyProgram.mProgramObject = glCreateProgramObjectARB(); - gObjectShinyProgram.attachObjects(baseObjects, baseCount); - gObjectShinyProgram.attachObject(loadShader(shinyvertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB)); - gObjectShinyProgram.attachObject(loadShader(shinyfragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB)); + gObjectShinyProgram.mName = "Shiny Shader"; + gObjectShinyProgram.mFeatures.calculatesAtmospherics = true; + gObjectShinyProgram.mFeatures.calculatesLighting = true; + gObjectShinyProgram.mFeatures.hasGamma = true; + gObjectShinyProgram.mFeatures.hasAtmospherics = true; + gObjectShinyProgram.mFeatures.isShiny = true; + gObjectShinyProgram.mShaderFiles.clear(); + gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectShinyProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; + success = gObjectShinyProgram.createShader(NULL, &sShinyUniforms); + } - success = gObjectShinyProgram.mapAttributes(); - if (success) - { - success = gObjectShinyProgram.mapUniforms(sShinyUniforms, sShinyUniformCount); - } - if( !success ) - { - llwarns << "Failed to load " << shinyvertex << llendl; - } + if (success) + { + gObjectShinyWaterProgram.mName = "Shiny Water Shader"; + gObjectShinyWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectShinyWaterProgram.mFeatures.calculatesLighting = true; + gObjectShinyWaterProgram.mFeatures.isShiny = true; + gObjectShinyWaterProgram.mFeatures.hasWaterFog = true; + gObjectShinyWaterProgram.mFeatures.hasAtmospherics = true; + gObjectShinyWaterProgram.mShaderFiles.clear(); + gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectShinyWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; + gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectShinyWaterProgram.createShader(NULL, &sShinyUniforms); } + + if (success) + { + gObjectFullbrightShinyProgram.mName = "Fullbright Shiny Shader"; + gObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightShinyProgram.mFeatures.isFullbright = true; + gObjectFullbrightShinyProgram.mFeatures.isShiny = true; + gObjectFullbrightShinyProgram.mFeatures.hasGamma = true; + gObjectFullbrightShinyProgram.mFeatures.hasTransport = true; + gObjectFullbrightShinyProgram.mShaderFiles.clear(); + gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightShinyProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; + success = gObjectFullbrightShinyProgram.createShader(NULL, &sShinyUniforms); + } + if( !success ) { sVertexShaderLevel[SHADER_OBJECT] = 0; - sMaxVertexShaderLevel[SHADER_OBJECT] = 0; return FALSE; } @@ -833,94 +1378,88 @@ BOOL LLShaderMgr::loadShadersObject() BOOL LLShaderMgr::loadShadersAvatar() { - GLhandleARB baseObjects[] = - { - gLightFragment, - gLightVertex, - gScatterFragment, - gScatterVertex - }; - S32 baseCount = 4; - BOOL success = TRUE; if (sVertexShaderLevel[SHADER_AVATAR] == 0) { gAvatarProgram.unload(); + gAvatarWaterProgram.unload(); gAvatarEyeballProgram.unload(); gAvatarPickProgram.unload(); return FALSE; } - - /*if (success) - { - //load specular (eyeball) vertex program - std::string eyeballvertex = "avatar/eyeballV.glsl"; - std::string eyeballfragment = "avatar/eyeballF.glsl"; - gAvatarEyeballProgram.mProgramObject = glCreateProgramObjectARB(); - gAvatarEyeballProgram.attachObjects(baseObjects, baseCount); - gAvatarEyeballProgram.attachObject(loadShader(eyeballvertex, SHADER_AVATAR, GL_VERTEX_SHADER_ARB)); - gAvatarEyeballProgram.attachObject(loadShader(eyeballfragment, SHADER_AVATAR, GL_FRAGMENT_SHADER_ARB)); - success = gAvatarEyeballProgram.mapAttributes(); - if (success) - { - success = gAvatarEyeballProgram.mapUniforms(); - } - if( !success ) - { - llwarns << "Failed to load " << eyeballvertex << llendl; - } - }*/ if (success) { - gAvatarSkinVertex = loadShader("avatar/avatarSkinV.glsl", SHADER_AVATAR, GL_VERTEX_SHADER_ARB); - //load avatar vertex shader - std::string avatarvertex = "avatar/avatarV.glsl"; - std::string avatarfragment = "avatar/avatarF.glsl"; - - gAvatarProgram.mProgramObject = glCreateProgramObjectARB(); - gAvatarProgram.attachObjects(baseObjects, baseCount); - gAvatarProgram.attachObject(gAvatarSkinVertex); - gAvatarProgram.attachObject(loadShader(avatarvertex, SHADER_AVATAR, GL_VERTEX_SHADER_ARB)); - gAvatarProgram.attachObject(loadShader(avatarfragment, SHADER_AVATAR, GL_FRAGMENT_SHADER_ARB)); - - success = gAvatarProgram.mapAttributes(sAvatarAttribs, sAvatarAttribCount); + gAvatarProgram.mName = "Avatar Shader"; + gAvatarProgram.mFeatures.hasSkinning = true; + gAvatarProgram.mFeatures.calculatesAtmospherics = true; + gAvatarProgram.mFeatures.calculatesLighting = true; + gAvatarProgram.mFeatures.hasGamma = true; + gAvatarProgram.mFeatures.hasAtmospherics = true; + gAvatarProgram.mFeatures.hasLighting = true; + gAvatarProgram.mShaderFiles.clear(); + gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB)); + gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); + gAvatarProgram.mShaderLevel = sVertexShaderLevel[SHADER_AVATAR]; + success = gAvatarProgram.createShader(&sAvatarAttribs, &sAvatarUniforms); + if (success) { - success = gAvatarProgram.mapUniforms(sAvatarUniforms, sAvatarUniformCount); + gAvatarWaterProgram.mName = "Avatar Water Shader"; + gAvatarWaterProgram.mFeatures.hasSkinning = true; + gAvatarWaterProgram.mFeatures.calculatesAtmospherics = true; + gAvatarWaterProgram.mFeatures.calculatesLighting = true; + gAvatarWaterProgram.mFeatures.hasWaterFog = true; + gAvatarWaterProgram.mFeatures.hasAtmospherics = true; + gAvatarWaterProgram.mFeatures.hasLighting = true; + gAvatarWaterProgram.mShaderFiles.clear(); + gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB)); + gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + // Note: no cloth under water: + gAvatarWaterProgram.mShaderLevel = llmin(sVertexShaderLevel[SHADER_AVATAR], 1); + gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gAvatarWaterProgram.createShader(&sAvatarAttribs, &sAvatarUniforms); } - if( !success ) + + /// Keep track of avatar levels + if (gAvatarProgram.mShaderLevel != sVertexShaderLevel[SHADER_AVATAR]) { - llwarns << "Failed to load " << avatarvertex << llendl; + sMaxAvatarShaderLevel = sVertexShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel; } } if (success) { - //load avatar picking shader - std::string pickvertex = "avatar/pickAvatarV.glsl"; - std::string pickfragment = "avatar/pickAvatarF.glsl"; - gAvatarPickProgram.mProgramObject = glCreateProgramObjectARB(); - gAvatarPickProgram.attachObject(loadShader(pickvertex, SHADER_AVATAR, GL_VERTEX_SHADER_ARB)); - gAvatarPickProgram.attachObject(loadShader(pickfragment, SHADER_AVATAR, GL_FRAGMENT_SHADER_ARB)); - gAvatarPickProgram.attachObject(gAvatarSkinVertex); + gAvatarPickProgram.mName = "Avatar Pick Shader"; + gAvatarPickProgram.mFeatures.hasSkinning = true; + gAvatarPickProgram.mShaderFiles.clear(); + gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB)); + gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB)); + gAvatarPickProgram.mShaderLevel = sVertexShaderLevel[SHADER_AVATAR]; + success = gAvatarPickProgram.createShader(&sAvatarAttribs, &sAvatarUniforms); + } - success = gAvatarPickProgram.mapAttributes(sAvatarAttribs, sAvatarAttribCount); - if (success) - { - success = gAvatarPickProgram.mapUniforms(sAvatarUniforms, sAvatarUniformCount); - } - if( !success ) - { - llwarns << "Failed to load " << pickvertex << llendl; - } + if (success) + { + gAvatarEyeballProgram.mName = "Avatar Eyeball Program"; + gAvatarEyeballProgram.mFeatures.calculatesLighting = true; + gAvatarEyeballProgram.mFeatures.isSpecular = true; + gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true; + gAvatarEyeballProgram.mFeatures.hasGamma = true; + gAvatarEyeballProgram.mFeatures.hasAtmospherics = true; + gAvatarEyeballProgram.mFeatures.hasLighting = true; + gAvatarEyeballProgram.mShaderFiles.clear(); + gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB)); + gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB)); + gAvatarEyeballProgram.mShaderLevel = sVertexShaderLevel[SHADER_AVATAR]; + success = gAvatarEyeballProgram.createShader(NULL, NULL); } if( !success ) { sVertexShaderLevel[SHADER_AVATAR] = 0; - sMaxVertexShaderLevel[SHADER_AVATAR] = 0; + sMaxAvatarShaderLevel = 0; return FALSE; } @@ -939,41 +1478,69 @@ BOOL LLShaderMgr::loadShadersInterface() if (success) { - //load highlighting shader - std::string highlightvertex = "interface/highlightV.glsl"; - std::string highlightfragment = "interface/highlightF.glsl"; - gHighlightProgram.mProgramObject = glCreateProgramObjectARB(); - gHighlightProgram.attachObject(loadShader(highlightvertex, SHADER_INTERFACE, GL_VERTEX_SHADER_ARB)); - gHighlightProgram.attachObject(loadShader(highlightfragment, SHADER_INTERFACE, GL_FRAGMENT_SHADER_ARB)); - - success = gHighlightProgram.mapAttributes(); - if (success) - { - success = gHighlightProgram.mapUniforms(); - } - if( !success ) - { - llwarns << "Failed to load " << highlightvertex << llendl; - } + gHighlightProgram.mName = "Highlight Shader"; + gHighlightProgram.mShaderFiles.clear(); + gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB)); + gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gHighlightProgram.mShaderLevel = sVertexShaderLevel[SHADER_INTERFACE]; + success = gHighlightProgram.createShader(NULL, NULL); } if( !success ) { sVertexShaderLevel[SHADER_INTERFACE] = 0; - sMaxVertexShaderLevel[SHADER_INTERFACE] = 0; return FALSE; } return TRUE; } +BOOL LLShaderMgr::loadShadersWindLight() +{ + BOOL success = TRUE; + + if (sVertexShaderLevel[SHADER_WINDLIGHT] < 2) + { + gWLSkyProgram.unload(); + gWLCloudProgram.unload(); + return FALSE; + } + + if (success) + { + gWLSkyProgram.mName = "Windlight Sky Shader"; + //gWLSkyProgram.mFeatures.hasGamma = true; + gWLSkyProgram.mShaderFiles.clear(); + gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyV.glsl", GL_VERTEX_SHADER_ARB)); + gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gWLSkyProgram.mShaderLevel = sVertexShaderLevel[SHADER_WINDLIGHT]; + gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; + success = gWLSkyProgram.createShader(NULL, &sWLUniforms); + } + + if (success) + { + gWLCloudProgram.mName = "Windlight Cloud Program"; + //gWLCloudProgram.mFeatures.hasGamma = true; + gWLCloudProgram.mShaderFiles.clear(); + gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsV.glsl", GL_VERTEX_SHADER_ARB)); + gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); + gWLCloudProgram.mShaderLevel = sVertexShaderLevel[SHADER_WINDLIGHT]; + gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; + success = gWLCloudProgram.createShader(NULL, &sWLUniforms); + } + + return success; +} + //=============================== // LLGLSL Shader implementation //=============================== LLGLSLShader::LLGLSLShader() -: mProgramObject(0) -{ } +: mProgramObject(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT) +{ +} void LLGLSLShader::unload() { @@ -981,6 +1548,7 @@ void LLGLSLShader::unload() mAttribute.clear(); mTexture.clear(); mUniform.clear(); + mShaderFiles.clear(); if (mProgramObject) { @@ -1004,6 +1572,76 @@ void LLGLSLShader::unload() stop_glerror(); } +BOOL LLGLSLShader::createShader(vector * attributes, + vector * uniforms) +{ + llassert_always(!mShaderFiles.empty()); + BOOL success = TRUE; + + // Create program + mProgramObject = glCreateProgramObjectARB(); + + // Attach existing objects + if (!LLShaderMgr::attachShaderFeatures(this)) + { + return FALSE; + } + + vector< pair >::iterator fileIter = mShaderFiles.begin(); + for ( ; fileIter != mShaderFiles.end(); fileIter++ ) + { + GLhandleARB shaderhandle = LLShaderMgr::loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second); + lldebugs << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << llendl; + if (mShaderLevel > 0) + { + attachObject(shaderhandle); + } + else + { + success = FALSE; + } + } + + // Map attributes and uniforms + if (success) + { + success = mapAttributes(attributes); + } + if (success) + { + success = mapUniforms(uniforms); + } + if( !success ) + { + llwarns << "Failed to link shader: " << mName << llendl; + + // Try again using a lower shader level; + if (mShaderLevel > 0) + { + llwarns << "Failed to link using shader level " << mShaderLevel << ". Trying again using shader level " << (mShaderLevel - 1) << "." << llendl; + mShaderLevel--; + return createShader(attributes,uniforms); + } + } + return success; +} + +BOOL LLGLSLShader::attachObject(std::string object) +{ + if (LLShaderMgr::sShaderObjects.count(object) > 0) + { + stop_glerror(); + glAttachObjectARB(mProgramObject, LLShaderMgr::sShaderObjects[object]); + stop_glerror(); + return TRUE; + } + else + { + llwarns << "Attempting to attach shader object that hasn't been compiled: " << object << llendl; + return FALSE; + } +} + void LLGLSLShader::attachObject(GLhandleARB object) { if (object != 0) @@ -1026,37 +1664,40 @@ void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count) } } -BOOL LLGLSLShader::mapAttributes(const char** attrib_names, S32 count) +BOOL LLGLSLShader::mapAttributes(const vector * attributes) { //link the program BOOL res = link(); mAttribute.clear(); - mAttribute.resize(LLShaderMgr::sReservedAttribCount + count, -1); + U32 numAttributes = (attributes == NULL) ? 0 : attributes->size(); + mAttribute.resize(LLShaderMgr::sReservedAttribs.size() + numAttributes, -1); if (res) { //read back channel locations //read back reserved channels first - for (S32 i = 0; i < (S32) LLShaderMgr::sReservedAttribCount; i++) + for (U32 i = 0; i < (S32) LLShaderMgr::sReservedAttribs.size(); i++) { - const char* name = LLShaderMgr::sReservedAttribs[i]; + const char* name = LLShaderMgr::sReservedAttribs[i].c_str(); S32 index = glGetAttribLocationARB(mProgramObject, (GLcharARB *)name); if (index != -1) { mAttribute[i] = index; - llinfos << "Attribute " << name << " assigned to channel " << index << llendl; + // llinfos << "Attribute " << name << " assigned to channel " << index << llendl; } } - - for (S32 i = 0; i < count; i++) + if (attributes != NULL) { - const char* name = attrib_names[i]; - S32 index = glGetAttribLocationARB(mProgramObject, (GLcharARB *)name); - if (index != -1) + for (U32 i = 0; i < numAttributes; i++) { - mAttribute[LLShaderMgr::sReservedAttribCount + i] = index; - llinfos << "Attribute " << name << " assigned to channel " << index << llendl; + const char* name = (*attributes)[i].c_str(); + S32 index = glGetAttribLocationARB(mProgramObject, name); + if (index != -1) + { + mAttribute[LLShaderMgr::sReservedAttribs.size() + i] = index; + // llinfos << "Attribute " << name << " assigned to channel " << index << llendl; + } } } @@ -1066,7 +1707,7 @@ BOOL LLGLSLShader::mapAttributes(const char** attrib_names, S32 count) return FALSE; } -void LLGLSLShader::mapUniform(GLint index, const char** uniform_names, S32 count) +void LLGLSLShader::mapUniform(GLint index, const vector * uniforms) { if (index == -1) { @@ -1080,37 +1721,42 @@ void LLGLSLShader::mapUniform(GLint index, const char** uniform_names, S32 count name[0] = 0; glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name); - - //find the index of this uniform - for (S32 i = 0; i < (S32) LLShaderMgr::sReservedUniformCount; i++) + S32 location = glGetUniformLocationARB(mProgramObject, name); + if (location != -1) { - if (mUniform[i] == -1 && !strncmp(LLShaderMgr::sReservedUniforms[i],name, strlen(LLShaderMgr::sReservedUniforms[i]))) /* Flawfinder: ignore */ + mUniformMap[name] = location; +#if 0 // !LL_RELEASE_FOR_DOWNLOAD + llinfos << "Uniform " << name << " is at location " << location << llendl; +#endif + + //find the index of this uniform + for (S32 i = 0; i < (S32) LLShaderMgr::sReservedUniforms.size(); i++) { - //found it - S32 location = glGetUniformLocationARB(mProgramObject, (GLcharARB *)name); - mUniform[i] = location; - llinfos << "Uniform " << name << " is at location " << location << llendl; - mTexture[i] = mapUniformTextureChannel(location, type); - return; + if ( (mUniform[i] == -1) + && (LLShaderMgr::sReservedUniforms[i].compare(0, length, name, LLShaderMgr::sReservedUniforms[i].length()) == 0)) + { + //found it + mUniform[i] = location; + mTexture[i] = mapUniformTextureChannel(location, type); + return; + } } - } - for (S32 i = 0; i < count; i++) - { - if (mUniform[i+LLShaderMgr::sReservedUniformCount] == -1 && - !strncmp(uniform_names[i],name, strlen(uniform_names[i]))) /* Flawfinder: ignore */ + if (uniforms != NULL) { - //found it - S32 location = glGetUniformLocationARB(mProgramObject, (GLcharARB *)name); - mUniform[i+LLShaderMgr::sReservedUniformCount] = location; - llinfos << "Uniform " << name << " is at location " << location << " stored in index " << - (i+LLShaderMgr::sReservedUniformCount) << llendl; - mTexture[i+LLShaderMgr::sReservedUniformCount] = mapUniformTextureChannel(location, type); - return; + for (U32 i = 0; i < uniforms->size(); i++) + { + if ( (mUniform[i+LLShaderMgr::sReservedUniforms.size()] == -1) + && ((*uniforms)[i].compare(0, length, name, (*uniforms)[i].length()) == 0)) + { + //found it + mUniform[i+LLShaderMgr::sReservedUniforms.size()] = location; + mTexture[i+LLShaderMgr::sReservedUniforms.size()] = mapUniformTextureChannel(location, type); + return; + } + } } } - - //llinfos << "Unknown uniform: " << name << llendl; } GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) @@ -1124,17 +1770,19 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) return -1; } -BOOL LLGLSLShader::mapUniforms(const char** uniform_names, S32 count) +BOOL LLGLSLShader::mapUniforms(const vector * uniforms) { BOOL res = TRUE; mActiveTextureChannels = 0; mUniform.clear(); + mUniformMap.clear(); mTexture.clear(); - + mValue.clear(); //initialize arrays - mUniform.resize(count + LLShaderMgr::sReservedUniformCount, -1); - mTexture.resize(count + LLShaderMgr::sReservedUniformCount, -1); + U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size(); + mUniform.resize(numUniforms + LLShaderMgr::sReservedUniforms.size(), -1); + mTexture.resize(numUniforms + LLShaderMgr::sReservedUniforms.size(), -1); bind(); @@ -1144,9 +1792,9 @@ BOOL LLGLSLShader::mapUniforms(const char** uniform_names, S32 count) for (S32 i = 0; i < activeCount; i++) { - mapUniform(i, uniform_names, count); + mapUniform(i, uniforms); } - + unbind(); return res; @@ -1159,27 +1807,37 @@ BOOL LLGLSLShader::link(BOOL suppress_errors) void LLGLSLShader::bind() { - glUseProgramObjectARB(mProgramObject); - if (mAttribute.size() > 0) + if (gGLManager.mHasShaderObjects) { - gMaterialIndex = mAttribute[0]; + glUseProgramObjectARB(mProgramObject); + + if (mUniformsDirty) + { + LLWLParamManager::instance()->updateShaderUniforms(this); + LLWaterParamManager::instance()->updateShaderUniforms(this); + mUniformsDirty = FALSE; + } } } void LLGLSLShader::unbind() { - for (U32 i = 0; i < mAttribute.size(); ++i) + if (gGLManager.mHasShaderObjects) { - vertexAttrib4f(i, 0,0,0,1); + for (U32 i = 0; i < mAttribute.size(); ++i) + { + vertexAttrib4f(i, 0,0,0,1); + } + glUseProgramObjectARB(0); } - glUseProgramObjectARB(0); } S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode) { if (uniform < 0 || uniform >= (S32)mTexture.size()) { - llerrs << "LLGLSLShader::enableTexture: uniform out of range: " << uniform << llendl; + UNIFORM_ERRS << "LLGLSLShader::enableTexture: uniform out of range: " << uniform << llendl; + return -1; } S32 index = mTexture[uniform]; if (index != -1) @@ -1192,6 +1850,11 @@ S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode) S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode) { + if (uniform < 0 || uniform >= (S32)mTexture.size()) + { + UNIFORM_ERRS << "LLGLSLShader::disableTexture: uniform out of range: " << uniform << llendl; + return -1; + } S32 index = mTexture[uniform]; if (index != -1) { @@ -1201,6 +1864,415 @@ S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode) return index; } +void LLGLSLShader::uniform1f(U32 index, GLfloat x) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << llendl; + return; + } + + if (mUniform[index] >= 0) + { + std::map::iterator iter = mValue.find(mUniform[index]); + if (iter == mValue.end() || iter->second.mV[0] != x) + { + glUniform1fARB(mUniform[index], x); + mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f); + } + } + } +} + +void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << llendl; + return; + } + + if (mUniform[index] >= 0) + { + std::map::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(x,y,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform2fARB(mUniform[index], x, y); + mValue[mUniform[index]] = vec; + } + } + } +} + +void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << llendl; + return; + } + + if (mUniform[index] >= 0) + { + std::map::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(x,y,z,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform3fARB(mUniform[index], x, y, z); + mValue[mUniform[index]] = vec; + } + } + } +} + +void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << llendl; + return; + } + + if (mUniform[index] >= 0) + { + std::map::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(x,y,z,w); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform4fARB(mUniform[index], x, y, z, w); + mValue[mUniform[index]] = vec; + } + } + } +} + +void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << llendl; + return; + } + + if (mUniform[index] >= 0) + { + std::map::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(v[0],0.f,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform1fvARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; + } + } + } +} + +void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << llendl; + return; + } + + if (mUniform[index] >= 0) + { + std::map::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(v[0],v[1],0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform2fvARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; + } + } + } +} + +void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << llendl; + return; + } + + if (mUniform[index] >= 0) + { + std::map::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(v[0],v[1],v[2],0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform3fvARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; + } + } + } +} + +void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << llendl; + return; + } + + if (mUniform[index] >= 0) + { + std::map::iterator iter = mValue.find(mUniform[index]); + LLVector4 vec(v[0],v[1],v[2],v[3]); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform4fvARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; + } + } + } +} + +void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << llendl; + return; + } + + if (mUniform[index] >= 0) + { + glUniformMatrix2fvARB(mUniform[index], count, transpose, v); + } + } +} + +void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << llendl; + return; + } + + if (mUniform[index] >= 0) + { + glUniformMatrix3fvARB(mUniform[index], count, transpose, v); + } + } +} + +void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) +{ + if (mProgramObject > 0) + { + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << llendl; + return; + } + + if (mUniform[index] >= 0) + { + glUniformMatrix4fvARB(mUniform[index], count, transpose, v); + } + } +} + +GLint LLGLSLShader::getUniformLocation(const string& uniform) +{ + if (mProgramObject > 0) + { + std::map::iterator iter = mUniformMap.find(uniform); + if (iter != mUniformMap.end()) + { + llassert(iter->second == glGetUniformLocationARB(mProgramObject, uniform.c_str())); + return iter->second; + } + } + + return -1; +} + +void LLGLSLShader::uniform1f(const string& uniform, GLfloat v) +{ + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map::iterator iter = mValue.find(location); + LLVector4 vec(v,0.f,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform1fARB(location, v); + mValue[location] = vec; + } + } +} + +void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y) +{ + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map::iterator iter = mValue.find(location); + LLVector4 vec(x,y,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform2fARB(location, x,y); + mValue[location] = vec; + } + } + +} + +void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloat z) +{ + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map::iterator iter = mValue.find(location); + LLVector4 vec(x,y,z,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform3fARB(location, x,y,z); + mValue[location] = vec; + } + } +} + +void LLGLSLShader::uniform4f(const string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map::iterator iter = mValue.find(location); + LLVector4 vec(x,y,z,w); + if (iter == mValue.end() || shouldChange(iter->second,vec)) + { + glUniform4fARB(location, x,y,z,w); + mValue[location] = vec; + } + } +} + +void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v) +{ + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map::iterator iter = mValue.find(location); + LLVector4 vec(v[0],0.f,0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform1fvARB(location, count, v); + mValue[location] = vec; + } + } +} + +void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v) +{ + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map::iterator iter = mValue.find(location); + LLVector4 vec(v[0],v[1],0.f,0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform2fvARB(location, count, v); + mValue[location] = vec; + } + } +} + +void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v) +{ + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + std::map::iterator iter = mValue.find(location); + LLVector4 vec(v[0],v[1],v[2],0.f); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform3fvARB(location, count, v); + mValue[location] = vec; + } + } +} + +void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v) +{ + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + LLVector4 vec(v); + std::map::iterator iter = mValue.find(location); + if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) + { + glUniform4fvARB(location, count, v); + mValue[location] = vec; + } + } +} + +void LLGLSLShader::uniformMatrix2fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v) +{ + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + glUniformMatrix2fvARB(location, count, transpose, v); + } +} + +void LLGLSLShader::uniformMatrix3fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v) +{ + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + glUniformMatrix3fvARB(location, count, transpose, v); + } +} + +void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v) +{ + GLint location = getUniformLocation(uniform); + + if (location >= 0) + { + glUniformMatrix4fvARB(location, count, transpose, v); + } +} + + void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { if (mAttribute[index] > 0) @@ -1216,11 +2288,3 @@ void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v) glVertexAttrib4fvARB(mAttribute[index], v); } } - -void LLScatterShader::init(GLhandleARB shader, int map_stage) -{ - glUseProgramObjectARB(shader); - glUniform1iARB(glGetUniformLocationARB(shader, (GLcharARB *)"scatterMap"), map_stage); - glUseProgramObjectARB(0); -} - diff --git a/linden/indra/newview/llglslshader.h b/linden/indra/newview/llglslshader.h index 0bd90c3..41b0c59 100644 --- a/linden/indra/newview/llglslshader.h +++ b/linden/indra/newview/llglslshader.h @@ -34,20 +34,76 @@ #include "llgl.h" +class LLShaderFeatures +{ +public: + bool calculatesLighting; + bool calculatesAtmospherics; + bool hasLighting; // implies no transport (it's possible to have neither though) + bool isShiny; + bool isFullbright; // implies no lighting + bool isSpecular; + bool hasWaterFog; // implies no gamma + bool hasTransport; // implies no lighting (it's possible to have neither though) + bool hasSkinning; + bool hasAtmospherics; + bool hasGamma; + + // char numLights; + + LLShaderFeatures(); +}; + class LLGLSLShader { public: + + enum + { + SG_DEFAULT = 0, + SG_SKY, + SG_WATER + }; + LLGLSLShader(); void unload(); + BOOL createShader(std::vector * attributes, + std::vector * uniforms); + BOOL attachObject(std::string object); void attachObject(GLhandleARB object); void attachObjects(GLhandleARB* objects = NULL, S32 count = 0); - BOOL mapAttributes(const char** attrib_names = NULL, S32 count = 0); - BOOL mapUniforms(const char** uniform_names = NULL, S32 count = 0); - void mapUniform(GLint index, const char** uniform_names = NULL, S32 count = 0); + BOOL mapAttributes(const std::vector * attributes); + BOOL mapUniforms(const std::vector * uniforms); + void mapUniform(GLint index, const std::vector * uniforms); + void uniform1f(U32 index, GLfloat v); + void uniform2f(U32 index, GLfloat x, GLfloat y); + void uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z); + void uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void uniform1fv(U32 index, U32 count, const GLfloat* v); + void uniform2fv(U32 index, U32 count, const GLfloat* v); + void uniform3fv(U32 index, U32 count, const GLfloat* v); + void uniform4fv(U32 index, U32 count, const GLfloat* v); + 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); + void uniform4f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void uniform1fv(const std::string& uniform, U32 count, const GLfloat* v); + void uniform2fv(const std::string& uniform, U32 count, const GLfloat* v); + void uniform3fv(const std::string& uniform, U32 count, const GLfloat* v); + void uniform4fv(const std::string& uniform, U32 count, const GLfloat* v); + void uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v); + void uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v); + void uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v); + void uniformMatrix2fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v); + void uniformMatrix3fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v); + void uniformMatrix4fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v); + void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void vertexAttrib4fv(U32 index, GLfloat* v); + GLint getUniformLocation(const std::string& uniform); + GLint mapUniformTextureChannel(GLint location, GLenum type); @@ -63,39 +119,95 @@ public: void unbind(); GLhandleARB mProgramObject; - std::vector mAttribute; - std::vector mUniform; + std::vector mAttribute; //lookup table of attribute enum to attribute channel + std::vector mUniform; //lookup table of uniform enum to uniform location + std::map mUniformMap; //lookup map of uniform name to uniform location + std::map mValue; //lookup map of uniform location to last known value std::vector mTexture; S32 mActiveTextureChannels; -}; - -class LLScatterShader -{ -public: - static void init(GLhandleARB shader, int map_stage); + S32 mShaderLevel; + S32 mShaderGroup; + BOOL mUniformsDirty; + LLShaderFeatures mFeatures; + std::vector< std::pair< std::string, GLenum > > mShaderFiles; + std::string mName; }; class LLShaderMgr { + friend class LLGLSLShader; + public: + static void initAttribsAndUniforms(void); + static BOOL attachShaderFeatures(LLGLSLShader * shader); static void setShaders(); static void unloadShaders(); static void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE); static BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE); static BOOL validateProgramObject(GLhandleARB obj); - static GLhandleARB loadShader(const LLString& filename, S32 cls, GLenum type); + static GLhandleARB loadShaderFile(const LLString& filename, S32 & shader_level, GLenum type); static S32 getVertexShaderLevel(S32 type); - static S32 getMaxVertexShaderLevel(S32 type); - static BOOL loadShadersLighting(); + static BOOL loadBasicShaders(); + static BOOL loadShadersEffects(); static BOOL loadShadersObject(); static BOOL loadShadersAvatar(); static BOOL loadShadersEnvironment(); + static BOOL loadShadersWater(); static BOOL loadShadersInterface(); + static BOOL loadShadersWindLight(); + + // simple model of forward iterator + // http://www.sgi.com/tech/stl/ForwardIterator.html + class shader_iter + { + friend bool operator == (shader_iter const & a, shader_iter const & b); + friend bool operator != (shader_iter const & a, shader_iter const & b); + public: + shader_iter() : mPtr(NULL) + { + } + + shader_iter(LLGLSLShader * const * ptr) : mPtr(ptr) + { + } + + LLGLSLShader & operator * () const + { + return **mPtr; + } + + LLGLSLShader * operator -> () const + { + return *mPtr; + } + + shader_iter & operator++ () + { + ++mPtr; + return *this; + } + + shader_iter operator++ (int) + { + return mPtr++; + } + + private: + LLGLSLShader * const * mPtr; + }; + + static shader_iter beginShaders() + { + return sShaderList; + } + + static shader_iter endShaders() + { + return sShaderList + sNumShaders; + } + static S32 sVertexShaderLevel[]; - static S32 sMaxVertexShaderLevel[]; - //global (reserved slot) shader parameters - static const char* sReservedAttribs[]; - static U32 sReservedAttribCount; + static S32 sMaxAvatarShaderLevel; enum EShaderClass { @@ -104,6 +216,9 @@ public: SHADER_AVATAR, SHADER_ENVIRONMENT, SHADER_INTERFACE, + SHADER_EFFECT, + SHADER_WINDLIGHT, + SHADER_WATER, SHADER_COUNT }; @@ -114,9 +229,6 @@ public: BINORMAL, END_RESERVED_ATTRIBS } eGLSLReservedAttribs; - - static const char* sReservedUniforms[]; - static U32 sReservedUniformCount; typedef enum { @@ -124,24 +236,39 @@ public: SPECULAR_MAP, BUMP_MAP, ENVIRONMENT_MAP, + CLOUD_NOISE_MAP, + FULLBRIGHT, + LIGHTNORM, + SUNLIGHT_COLOR, + AMBIENT, + BLUE_HORIZON, + BLUE_DENSITY, + HAZE_HORIZON, + HAZE_DENSITY, + CLOUD_SHADOW, + DENSITY_MULTIPLIER, + DISTANCE_MULTIPLIER, + MAX_Y, + GLOW, + CLOUD_COLOR, + CLOUD_POS_DENSITY1, + CLOUD_POS_DENSITY2, + CLOUD_SCALE, + GAMMA, + SCENE_LIGHT_STRENGTH, END_RESERVED_UNIFORMS } eGLSLReservedUniforms; - static const char* sShinyUniforms[]; - static U32 sShinyUniformCount; - typedef enum { SHINY_ORIGIN = END_RESERVED_UNIFORMS } eShinyUniforms; - //water parameters - static const char* sWaterUniforms[]; - static U32 sWaterUniformCount; - typedef enum { WATER_SCREENTEX = END_RESERVED_UNIFORMS, + WATER_SCREENDEPTH, + WATER_REFTEX, WATER_EYEVEC, WATER_TIME, WATER_WAVE_DIR1, @@ -149,34 +276,32 @@ public: WATER_LIGHT_DIR, WATER_SPECULAR, WATER_SPECULAR_EXP, - WATER_FBSCALE, - WATER_REFSCALE + WATER_FOGCOLOR, + WATER_FOGDENSITY, + WATER_REFSCALE, + WATER_WATERHEIGHT, } eWaterUniforms; - //terrain parameters - static const char* sTerrainUniforms[]; - static U32 sTerrainUniformCount; + typedef enum + { + WL_CAMPOSLOCAL = END_RESERVED_UNIFORMS, + WL_WATERHEIGHT + } eWLUniforms; typedef enum { TERRAIN_DETAIL0 = END_RESERVED_UNIFORMS, TERRAIN_DETAIL1, + TERRAIN_DETAIL2, + TERRAIN_DETAIL3, TERRAIN_ALPHARAMP } eTerrainUniforms; - //glow parameters - static const char* sGlowUniforms[]; - static U32 sGlowUniformCount; - typedef enum { GLOW_DELTA = END_RESERVED_UNIFORMS } eGlowUniforms; - //avatar shader parameter tables - static const char* sAvatarAttribs[]; - static U32 sAvatarAttribCount; - typedef enum { AVATAR_WEIGHT = END_RESERVED_ATTRIBS, @@ -186,50 +311,102 @@ public: AVATAR_GRAVITY } eAvatarAttribs; - static const char* sAvatarUniforms[]; - static U32 sAvatarUniformCount; - typedef enum { AVATAR_MATRIX = END_RESERVED_UNIFORMS } eAvatarUniforms; -}; //LLSL +private: + + // Map of shader names to compiled + static std::map sShaderObjects; + + //global (reserved slot) shader parameters + static std::vector sReservedAttribs; + + static std::vector sReservedUniforms; + + static std::vector sShinyUniforms; + + //water parameters + static std::vector sWaterUniforms; + + static std::vector sWLUniforms; + + //terrain parameters + static std::vector sTerrainUniforms; + + //glow parameters + static std::vector sGlowUniforms; + + static std::vector sGlowExtractUniforms; + + //avatar shader parameter tables + static std::vector sAvatarAttribs; + + static std::vector sAvatarUniforms; + // static std::vector< GLhandleARB > sBaseObjects; + + // the list of shaders we need to propagate parameters to. + static LLGLSLShader * const sShaderList[]; + + // the size of our shader list for convenience. + static const size_t sNumShaders; + +}; //LLShaderMgr + +inline bool operator == (LLShaderMgr::shader_iter const & a, LLShaderMgr::shader_iter const & b) +{ + return a.mPtr == b.mPtr; +} + +inline bool operator != (LLShaderMgr::shader_iter const & a, LLShaderMgr::shader_iter const & b) +{ + return a.mPtr != b.mPtr; +} -//utility shader objects (not shader programs) -extern GLhandleARB gLightVertex; -extern GLhandleARB gLightFragment; -extern GLhandleARB gScatterVertex; -extern GLhandleARB gScatterFragment; extern LLVector4 gShinyOrigin; //object shaders extern LLGLSLShader gObjectSimpleProgram; -extern LLGLSLShader gObjectAlphaProgram; -extern LLGLSLShader gObjectBumpProgram; +extern LLGLSLShader gObjectSimpleWaterProgram; +extern LLGLSLShader gObjectFullbrightProgram; +extern LLGLSLShader gObjectFullbrightWaterProgram; + +extern LLGLSLShader gObjectSimpleLODProgram; +extern LLGLSLShader gObjectFullbrightLODProgram; + +extern LLGLSLShader gObjectFullbrightShinyProgram; extern LLGLSLShader gObjectShinyProgram; +extern LLGLSLShader gObjectShinyWaterProgram; //environment shaders extern LLGLSLShader gTerrainProgram; -extern LLGLSLShader gGlowProgram; -extern LLGLSLShader gGroundProgram; +extern LLGLSLShader gTerrainWaterProgram; extern LLGLSLShader gWaterProgram; +extern LLGLSLShader gUnderWaterProgram; +extern LLGLSLShader gGlowProgram; +extern LLGLSLShader gGlowExtractProgram; //interface shaders extern LLGLSLShader gHighlightProgram; -//avatar skinning utility shader object -extern GLhandleARB gAvatarSkinVertex; - -//avatar shader handles +// avatar shader handles extern LLGLSLShader gAvatarProgram; +extern LLGLSLShader gAvatarWaterProgram; extern LLGLSLShader gAvatarEyeballProgram; extern LLGLSLShader gAvatarPickProgram; +// WindLight shader handles +extern LLGLSLShader gWLSkyProgram; +extern LLGLSLShader gWLCloudProgram; + +// Post Process Shaders +extern LLGLSLShader gPostColorFilterProgram; +extern LLGLSLShader gPostNightVisionProgram; + //current avatar shader parameter pointer extern GLint gAvatarMatrixParam; -extern GLint gMaterialIndex; -extern GLint gSpecularIndex; - + #endif diff --git a/linden/indra/newview/llgroupnotify.cpp b/linden/indra/newview/llgroupnotify.cpp index e6f535f..cae784b 100644 --- a/linden/indra/newview/llgroupnotify.cpp +++ b/linden/indra/newview/llgroupnotify.cpp @@ -129,7 +129,7 @@ LLGroupNotifyBox::LLGroupNotifyBox(const char* subject, mHasInventory(has_inventory), mInventoryOffer(inventory_offer) { - mIsFocusRoot = TRUE; + setFocusRoot(TRUE); time_t timestamp = (time_t)t; @@ -147,10 +147,10 @@ LLGroupNotifyBox::LLGroupNotifyBox(const char* subject, LLTextEditor* text; const S32 VPAD = 2; - const S32 TOP = mRect.getHeight() - 32; // Get past the top menu bar + const S32 TOP = getRect().getHeight() - 32; // Get past the top menu bar const S32 BOTTOM_PAD = VPAD * 2; const S32 BTN_TOP = BOTTOM_PAD + BTN_HEIGHT + VPAD; - const S32 RIGHT = mRect.getWidth() - HPAD - HPAD; + const S32 RIGHT = getRect().getWidth() - HPAD - HPAD; const S32 LINE_HEIGHT = 16; const S32 LABEL_WIDTH = 64; @@ -230,7 +230,7 @@ LLGroupNotifyBox::LLGroupNotifyBox(const char* subject, text->setEnabled(FALSE); text->setWordWrap(TRUE); text->setTabStop(FALSE); - text->setTabToNextField(TRUE); + text->setTabsToNextField(TRUE); text->setMouseOpaque(TRUE); text->setBorderVisible(TRUE); text->setTakesNonScrollClicks(TRUE); @@ -278,7 +278,7 @@ LLGroupNotifyBox::LLGroupNotifyBox(const char* subject, LLButton* btn; btn = new LLButton("next", - LLRect(mRect.getWidth()-24, BOTTOM_PAD+16, mRect.getWidth()-8, BOTTOM_PAD), + LLRect(getRect().getWidth()-24, BOTTOM_PAD+16, getRect().getWidth()-8, BOTTOM_PAD), "notify_next.tga", "notify_next.tga", "", @@ -377,7 +377,7 @@ void LLGroupNotifyBox::draw() glMatrixMode(GL_MODELVIEW); glPushMatrix(); - S32 height = mRect.getHeight(); + S32 height = getRect().getHeight(); F32 fraction = display_time / ANIMATION_TIME; F32 voffset = (1.f - fraction) * height; diff --git a/linden/indra/newview/llhoverview.cpp b/linden/indra/newview/llhoverview.cpp index cadd11a..316ba0b 100644 --- a/linden/indra/newview/llhoverview.cpp +++ b/linden/indra/newview/llhoverview.cpp @@ -38,6 +38,7 @@ #include "llfontgl.h" #include "message.h" #include "llgl.h" +#include "llglimmediate.h" #include "llfontgl.h" #include "llparcel.h" #include "lldbstrings.h" @@ -103,8 +104,6 @@ LLHoverView::LLHoverView(const std::string& name, const LLRect& rect) LLHoverView::~LLHoverView() { - // children all deleted by LLView destructor - mText.deleteAllData(); } EWidgetType LLHoverView::getWidgetType() const @@ -135,8 +134,8 @@ void LLHoverView::updateHover(LLTool* current_tool) { mStartHoverTimer.reset(); mStartHoverPickTimer = TRUE; - // Delete the existing text so that we do not briefly show the wrong data. - mText.deleteAllData(); + // Clear the existing text so that we do not briefly show the wrong data. + mText.clear(); } if (mDoneHoverPick) @@ -216,13 +215,10 @@ void LLHoverView::resetLastHoverObject() void LLHoverView::updateText() { - char first_name[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last_name[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char group_name[DB_GROUP_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - LLViewerObject* hit_object = getLastHoverObject(); + std::string line; - mText.deleteAllData(); + mText.clear(); if ( hit_object ) { if ( hit_object->isHUDAttachment() ) @@ -249,9 +245,9 @@ void LLHoverView::updateText() } } + line.clear(); if (hit_object->isAvatar()) { - LLString *line = new LLString(""); LLNameValue* title = hit_object->getNVPair("Title"); LLNameValue* firstname = hit_object->getNVPair("FirstName"); LLNameValue* lastname = hit_object->getNVPair("LastName"); @@ -259,18 +255,18 @@ void LLHoverView::updateText() { if (title) { - line->append(title->getString()); - line->append(1, ' '); + line.append(title->getString()); + line.append(1, ' '); } - line->append(firstname->getString()); - line->append(1, ' '); - line->append(lastname->getString()); + line.append(firstname->getString()); + line.append(1, ' '); + line.append(lastname->getString()); } else { - line->append("Person"); + line.append("Person"); } - mText.addDataAtEnd(line); + mText.push_back(line); } else { @@ -286,75 +282,69 @@ void LLHoverView::updateText() LLSelectNode *nodep = gSelectMgr->getHoverNode();; if (nodep) { - char cstring[256]; /*Flawfinder: ignore*/ - LLString *temp_str = NULL; - - temp_str = new LLString(); + line.clear(); if (nodep->mName.empty()) { - temp_str->append("(no name)"); + line.append("(no name)"); } else { - temp_str->append( nodep->mName ); + line.append( nodep->mName ); } - - mText.addDataAtEnd(temp_str); + mText.push_back(line); if (!nodep->mDescription.empty() && nodep->mDescription != DEFAULT_DESC) { - temp_str = new LLString( nodep->mDescription ); - mText.addDataAtEnd( temp_str ); + mText.push_back( nodep->mDescription ); } // Line: "Owner: James Linden" - temp_str = new LLString(); - temp_str->append("Owner: "); + line.clear(); + line.append("Owner: "); if (nodep->mValid) { LLUUID owner; + std::string name; if (!nodep->mPermissions->isGroupOwned()) { owner = nodep->mPermissions->getOwner(); if (LLUUID::null == owner) { - temp_str->append("Public"); + line.append("Public"); } - else if(gCacheName->getName( - owner, first_name, last_name)) + else if(gCacheName->getFullName(owner, name)) { - temp_str->append(first_name); - temp_str->append(" "); - temp_str->append(last_name); + line.append(name); } else { - temp_str->append("Retrieving..."); + line.append("Retrieving..."); } - }else + } + else { + std::string name; owner = nodep->mPermissions->getGroup(); - if (gCacheName->getGroupName(owner, group_name)) + if (gCacheName->getGroupName(owner, name)) { - temp_str->append(group_name); - temp_str->append("(Group)"); + line.append(name); + line.append("(Group)"); } else { - temp_str->append("Retrieving..."); + line.append("Retrieving..."); } } } else { - temp_str->append("Retrieving..."); + line.append("Retrieving..."); } - mText.addDataAtEnd(temp_str); + mText.push_back(line); - // Build a line describing any special properties - // of this object. + // Build a line describing any special properties of this object. LLViewerObject *object = hit_object; LLViewerObject *parent = (LLViewerObject *)object->getParent(); @@ -367,54 +357,56 @@ void LLHoverView::updateText() object->flagTemporary() || object->flagPhantom()) ) { - temp_str = new LLString(); + line.clear(); if (object->flagScripted()) { - temp_str->append("Script "); + line.append("Script "); } if (object->usePhysics()) { - temp_str->append("Physics "); + line.append("Physics "); } if (object->flagHandleTouch() || (parent && parent->flagHandleTouch()) ) { - temp_str->append("Touch "); + line.append("Touch "); suppressObjectHoverDisplay = FALSE; // Show tip } if (object->flagTakesMoney() || (parent && parent->flagTakesMoney()) ) { - temp_str->append("L$ "); + line.append("L$ "); suppressObjectHoverDisplay = FALSE; // Show tip } if (object->flagAllowInventoryAdd()) { - temp_str->append("Drop Inventory "); + line.append("Drop Inventory "); suppressObjectHoverDisplay = FALSE; // Show tip } if (object->flagPhantom()) { - temp_str->append("Phantom "); + line.append("Phantom "); } if (object->flagTemporary()) { - temp_str->append("Temporary "); + line.append("Temporary "); } if (object->usePhysics() || object->flagHandleTouch() || (parent && parent->flagHandleTouch()) ) { - temp_str->append("(Right-click for menu) "); + line.append("(Right-click for menu) "); } - mText.addDataAtEnd(temp_str); + mText.push_back(line); } + // Free to copy / For Sale: L$ + line.clear(); if (nodep->mValid) { BOOL for_copy = nodep->mPermissions->getMaskEveryone() & PERM_COPY && object->permCopy(); @@ -424,44 +416,36 @@ void LLHoverView::updateText() nodep->mSaleInfo.getSaleType() != LLSaleInfo::FS_COPY); if (for_copy) { - temp_str = new LLString(); - temp_str->append("Free to copy"); - mText.addDataAtEnd(temp_str); + line.append("Free to copy"); suppressObjectHoverDisplay = FALSE; // Show tip } else if (for_sale) { - temp_str = new LLString(); - temp_str->append("For Sale: "); - snprintf(cstring, sizeof(cstring), "L$%d", nodep->mSaleInfo.getSalePrice()); /* Flawfinder: ignore */ - temp_str->append(cstring); - mText.addDataAtEnd(temp_str); + line.append(llformat("For Sale: L$%d", nodep->mSaleInfo.getSalePrice())); suppressObjectHoverDisplay = FALSE; // Show tip } else { // Nothing if not for sale - // temp_str = new LLString(); - // temp_str->append("Not for sale"); + // line.append("Not for sale"); } } else { - temp_str = new LLString(); - temp_str->append("For Sale: Retrieving..."); - mText.addDataAtEnd(temp_str); + line.append("For Sale: Retrieving..."); } + mText.push_back(line); } + // If the hover tip shouldn't be shown, delete all the object text if (suppressObjectHoverDisplay) { - mText.deleteAllData(); + mText.clear(); } } } else if ( mHoverLandGlobal != LLVector3d::zero ) { - // // Do not show hover for land unless prefs are set to allow it. // @@ -470,7 +454,6 @@ void LLHoverView::updateText() // Didn't hit an object, but since we have a land point we // must be hovering over land. - LLString *line = NULL; LLParcel* hover_parcel = gParcelMgr->getHoverParcel(); LLUUID owner; @@ -485,54 +468,51 @@ void LLHoverView::updateText() } // Line: "Land" - line = new LLString(); - mText.addDataAtEnd(line); - - line->append("Land: "); + line.clear(); + line.append("Land: "); if (hover_parcel) { - line->append(hover_parcel->getName()); + line.append(hover_parcel->getName()); } + mText.push_back(line); // Line: "Owner: James Linden" - line = new LLString(); - mText.addDataAtEnd(line); - - line->append("Owner: "); + line.clear(); + line.append("Owner: "); if ( hover_parcel ) { + std::string name; if (LLUUID::null == owner) { - line->append("Public"); + line.append("Public"); } else if (hover_parcel->getIsGroupOwned()) { - if (gCacheName->getGroupName(owner, group_name)) + if (gCacheName->getGroupName(owner, name)) { - line->append(group_name); - line->append("(Group)"); + line.append(name); + line.append("(Group)"); } else { - line->append("Retrieving..."); + line.append("Retrieving..."); } } - else if(gCacheName->getName(owner, first_name, last_name)) + else if(gCacheName->getFullName(owner, name)) { - line->append(first_name); - line->append(" "); - line->append(last_name); + line.append(name); } else { - line->append("Retrieving..."); + line.append("Retrieving..."); } } else { - line->append("Retrieving..."); + line.append("Retrieving..."); } + mText.push_back(line); // Line: "no fly, not safe, no build" @@ -541,19 +521,19 @@ void LLHoverView::updateText() if ( hover_parcel && owner != gAgent.getID() ) { S32 words = 0; - line = new LLString(""); - + + line.clear(); // JC - Keep this in the same order as the checkboxes // on the land info panel if ( !hover_parcel->getAllowModify() ) { if ( hover_parcel->getAllowGroupModify() ) { - line->append("Group Build"); + line.append("Group Build"); } else { - line->append("No Build"); + line.append("No Build"); } words++; @@ -561,36 +541,36 @@ void LLHoverView::updateText() if ( !hover_parcel->getAllowTerraform() ) { - if (words) line->append(", "); - line->append("No Edit"); + if (words) line.append(", "); + line.append("No Edit"); words++; } if ( hover_parcel->getAllowDamage() ) { - if (words) line->append(", "); - line->append("Not Safe"); + if (words) line.append(", "); + line.append("Not Safe"); words++; } // Maybe we should reflect the estate's block fly bit here as well? DK 12/1/04 if ( !hover_parcel->getAllowFly() ) { - if (words) line->append(", "); - line->append("No Fly"); + if (words) line.append(", "); + line.append("No Fly"); words++; } if ( !hover_parcel->getAllowOtherScripts() ) { - if (words) line->append(", "); + if (words) line.append(", "); if ( hover_parcel->getAllowGroupScripts() ) { - line->append("Group Scripts"); + line.append("Group Scripts"); } else { - line->append("No Scripts"); + line.append("No Scripts"); } words++; @@ -598,12 +578,7 @@ void LLHoverView::updateText() if (words) { - mText.addDataAtEnd(line); - } - else - { - delete line; - line = NULL; + mText.push_back(line); } } @@ -612,21 +587,14 @@ void LLHoverView::updateText() /* if ( hover_parcel && LLUUID::null != owner) { - line = new LLString(); - mText.addDataAtEnd(line); - - char buffer[MAX_STRING]; - sprintf(buffer, "Size: %dx%d", width, height ); - line->append(buffer); + line = llformat("Size: %dx%d", width, height ); + mText.push_back(line); } */ if (hover_parcel && hover_parcel->getParcelFlag(PF_FOR_SALE)) { - char buffer[MAX_STRING]; /*Flawfinder: ignore*/ - snprintf(buffer, sizeof(buffer), "For Sale: L$%d", hover_parcel->getSalePrice() ); /* Flawfinder: ignore */ - - line = new LLString(buffer); - mText.addDataAtEnd(line); + line = llformat("For Sale: L$%d", hover_parcel->getSalePrice() ); + mText.push_back(line); } } } @@ -683,7 +651,7 @@ void LLHoverView::draw() } // Bail out if no text to display - if (mText.isEmpty()) + if (mText.empty()) { return; } @@ -711,11 +679,10 @@ void LLHoverView::draw() //bg_color.mV[VALPHA] = alpha; S32 max_width = 0; - S32 num_lines = mText.getLength(); - LLString *cur_stringp; - for (cur_stringp = mText.getFirstData(); cur_stringp; cur_stringp = mText.getNextData()) + S32 num_lines = mText.size(); + for (text_list_t::iterator iter = mText.begin(); iter != mText.end(); ++iter) { - max_width = llmax(max_width, (S32)fontp->getWidth(*cur_stringp)); + max_width = llmax(max_width, (S32)fontp->getWidth(*iter)); } S32 left = mHoverPos.mX + 10; @@ -734,32 +701,32 @@ void LLHoverView::draw() } // Make sure the rect is completely visible - LLRect old_rect = mRect; - mRect.set( left, top, right, bottom ); + LLRect old_rect = getRect(); + setRect( LLRect(left, top, right, bottom ) ); translateIntoRect( gViewerWindow->getVirtualWindowRect(), FALSE ); - left = mRect.mLeft; - top = mRect.mTop; - right = mRect.mRight; - bottom = mRect.mBottom; - mRect = old_rect; + left = getRect().mLeft; + top = getRect().mTop; + right = getRect().mRight; + bottom = getRect().mBottom; + setRect(old_rect); LLGLSUIDefault gls_ui; shadow_color.mV[VALPHA] = 0.7f * alpha; S32 shadow_offset = gSavedSettings.getS32("DropShadowTooltip"); - glColor4fv(shadow_color.mV); + gGL.color4fv(shadow_color.mV); LLViewerImage::bindTexture(shadow_imagep); gl_segmented_rect_2d_tex(left + shadow_offset, top - shadow_offset, right + shadow_offset, bottom - shadow_offset, shadow_imagep->getWidth(), shadow_imagep->getHeight(), 16); bg_color.mV[VALPHA] = alpha; - glColor4fv(bg_color.mV); + gGL.color4fv(bg_color.mV); LLViewerImage::bindTexture(box_imagep); gl_segmented_rect_2d_tex(left, top, right, bottom, box_imagep->getWidth(), box_imagep->getHeight(), 16); S32 cur_offset = top - 4; - for (cur_stringp = mText.getFirstData(); cur_stringp; cur_stringp = mText.getNextData()) + for (text_list_t::iterator iter = mText.begin(); iter != mText.end(); ++iter) { - fontp->renderUTF8(*cur_stringp, 0, left + 10, cur_offset, text_color, LLFontGL::LEFT, LLFontGL::TOP); + fontp->renderUTF8(*iter, 0, left + 10, cur_offset, text_color, LLFontGL::LEFT, LLFontGL::TOP); cur_offset -= llfloor(fontp->getLineHeight()); } } diff --git a/linden/indra/newview/llhoverview.h b/linden/indra/newview/llhoverview.h index ee41f88..ae74c44 100644 --- a/linden/indra/newview/llhoverview.h +++ b/linden/indra/newview/llhoverview.h @@ -37,15 +37,15 @@ #include "llview.h" #include "llframetimer.h" #include "llstring.h" -#include "linked_lists.h" #include "llcoord.h" #include "v3dmath.h" #include "lldarray.h" -#include "llhudconnector.h" +#include "llviewerobject.h" class LLTool; + // // Classes // @@ -97,7 +97,8 @@ protected: // How long has the hover popup been visible? LLFrameTimer mHoverTimer; - LLLinkedList mText; + typedef std::list text_list_t; + text_list_t mText; BOOL mUseHover; diff --git a/linden/indra/newview/llhudconnector.cpp b/linden/indra/newview/llhudconnector.cpp deleted file mode 100644 index 2dce48c..0000000 --- a/linden/indra/newview/llhudconnector.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/** - * @file llhudconnector.cpp - * @brief LLHUDConnector class implementation - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llhudconnector.h" -#include "llviewercamera.h" -#include "llviewerobject.h" - -#include "llgl.h" -#include "llimagegl.h" -#include "llsphere.h" -#include "llhudrender.h" -#include "llfontgl.h" -#include "llglheaders.h" - -LLHUDConnector::LLHUDConnector(const U8 type) : - LLHUDObject(type), - mZCompare(TRUE) -{ - mColor = LLColor4(1.f, 1.f, 1.f, 1.f); - mFirstColor = mColor; - mSecondColor = mColor; - mDoFade = TRUE; - mFadeDistance = 40.f; - mFadeRange = 10.f; - mDrawFirst = mDrawSecond = TRUE; - - mLabel = "Foo!"; -} - -LLHUDConnector::~LLHUDConnector() -{ -} - -void LLHUDConnector::setLabel(const LLString &label) -{ - mLabel = label; -} - -void LLHUDConnector::setTargets(LLViewerObject *first_object, LLViewerObject *second_object) -{ - setSourceObject(first_object); - setTargetObject(second_object); -} - -void LLHUDConnector::render() -{ - if (mSourceObject.isNull() || mTargetObject.isNull()) - { - mSourceObject = NULL; - mTargetObject = NULL; - return; - } - - if (mSourceObject->isDead() || mTargetObject->isDead()) - { - mSourceObject = NULL; - mTargetObject = NULL; - return; - } - - LLVector3 first_pos_agent = mSourceObject->getPositionAgent(); - LLVector3 second_pos_agent = mTargetObject->getPositionAgent(); - - LLVector3 center_agent = 0.5f*(first_pos_agent + second_pos_agent); - F32 dist = (center_agent - gCamera->getOrigin()).magVec(); - F32 alpha_factor = 1.f; - - if (mDoFade) - { - if (dist > mFadeDistance) - { - alpha_factor = llmax(0.f, 1.f - (dist - mFadeDistance)/mFadeRange); - } - } - - if (alpha_factor < 0.01f) - { - return; - } - - LLGLSPipelineAlpha gls_pipeline_alpha; - LLImageGL::unbindTexture(0, GL_TEXTURE_2D); - - LLVector3 dir_vec = first_pos_agent - second_pos_agent; - dir_vec.normVec(); - dir_vec *= 0.05f; - - LLVector3 first_line_pos = first_pos_agent - dir_vec; - LLVector3 second_line_pos = second_pos_agent + dir_vec; - - LLColor4 color; - - // Spheres on ends of connectors - if (mDrawFirst) - { - color = mFirstColor; - color.mV[3] *= alpha_factor; - glColor4fv(color.mV); - glPushMatrix(); - glTranslatef(first_pos_agent.mV[0], first_pos_agent.mV[1], first_pos_agent.mV[2]); - glScalef(0.1f, 0.1f, 0.1f); - gSphere.render(); - glPopMatrix(); - } - - if (mDrawSecond) - { - color = mSecondColor; - color.mV[3] *= alpha_factor; - glColor4fv(color.mV); - glPushMatrix(); - glTranslatef(second_pos_agent.mV[0], second_pos_agent.mV[1], second_pos_agent.mV[2]); - glScalef(0.1f, 0.1f, 0.1f); - gSphere.render(); - glPopMatrix(); - } - - color = mColor; - color.mV[3] *= alpha_factor; - glColor4fv(color.mV); - glBegin(GL_LINES); - glVertex3fv(first_line_pos.mV); - glVertex3fv(second_line_pos.mV); - glEnd(); - - { - LLGLDepthTest gls_depth(GL_FALSE); - // Spheres on ends of connectors - if (mDrawFirst) - { - color = mFirstColor; - color.mV[3] *= 0.25f*alpha_factor; - glColor4fv(color.mV); - glPushMatrix(); - glTranslatef(first_pos_agent.mV[0], first_pos_agent.mV[1], first_pos_agent.mV[2]); - glScalef(0.1f, 0.1f, 0.1f); - gSphere.render(); - glPopMatrix(); - } - if (mDrawSecond) - { - color = mSecondColor; - color.mV[3] *= 0.25f*alpha_factor; - glColor4fv(color.mV); - glPushMatrix(); - glTranslatef(second_pos_agent.mV[0], second_pos_agent.mV[1], second_pos_agent.mV[2]); - glScalef(0.1f, 0.1f, 0.1f); - gSphere.render(); - glPopMatrix(); - } - { - LLGLSNoTexture no_texture; - color = mColor; - color.mV[3] *= 0.25f*alpha_factor; - glColor4fv(color.mV); - glBegin(GL_LINES); - glVertex3fv(first_line_pos.mV); - glVertex3fv(second_line_pos.mV); - glEnd(); - } - } - - LLFontGL *fontp = LLFontGL::sSansSerif; - if (mLabel.size()) - { - hud_render_utf8text(mLabel, center_agent, *fontp, LLFontGL::NORMAL, -0.5f*fontp->getWidthF32(mLabel), 0, LLColor4::white, FALSE); - } -} - -void LLHUDConnector::setZCompare(const BOOL zcompare) -{ - mZCompare = zcompare; -} - -void LLHUDConnector::setColors(const LLColor4 &color, const LLColor4 &first_color, const LLColor4 &second_color) -{ - mColor = color; - mFirstColor = first_color; - mSecondColor = second_color; -} - -void LLHUDConnector::setDoFade(const BOOL do_fade) -{ - mDoFade = do_fade; -} - -void LLHUDConnector::setEndpoints(const BOOL &first, const BOOL &second) -{ - mDrawFirst = first; - mDrawSecond = second; -} diff --git a/linden/indra/newview/llhudconnector.h b/linden/indra/newview/llhudconnector.h deleted file mode 100644 index 3ca4725..0000000 --- a/linden/indra/newview/llhudconnector.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file llhudconnector.h - * @brief LLHUDConnector class definition - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLHUDCONNECTOR_H -#define LL_LLHUDCONNECTOR_H - -#include "llmemory.h" -#include "lldarrayptr.h" - -#include "llhudobject.h" -#include "v4color.h" -#include "v3math.h" -#include "v3dmath.h" -#include "llstring.h" - -class LLViewerObject; - -class LLHUDConnector : public LLHUDObject -{ -public: - void setColors(const LLColor4 &color, const LLColor4 &first_color, const LLColor4 &second_color); - void setZCompare(const BOOL zcompare); - void setDoFade(const BOOL do_fade); - - void setLabel(const LLString &label); - void setTargets(LLViewerObject *first_object, LLViewerObject *second_object); - void setEndpoints(const BOOL &first, const BOOL &second); - - friend class LLHUDObject; -protected: - LLHUDConnector(const U8 type); - - /*virtual*/ void render(); - -private: - ~LLHUDConnector(); - - LLString mLabel; - - BOOL mDoFade; - F32 mFadeRange; - F32 mFadeDistance; - BOOL mZCompare; - - LLColor4 mColor; - LLColor4 mFirstColor; - LLColor4 mSecondColor; - - BOOL mDrawFirst; - BOOL mDrawSecond; -}; - -#endif // LL_LLHUDCONNECTOR_H diff --git a/linden/indra/newview/llhudeffectbeam.cpp b/linden/indra/newview/llhudeffectbeam.cpp index 4918946..2ba9ade 100644 --- a/linden/indra/newview/llhudeffectbeam.cpp +++ b/linden/indra/newview/llhudeffectbeam.cpp @@ -274,51 +274,6 @@ void LLHUDEffectBeam::render() // Init the color of the particles LLColor4U coloru = mColor; - - /* - // This is disabled for now - DJS - - // Fade the alpha - coloru.mV[3] = mFadeInterp.getCurVal()*mColor.mV[3]; - - // Draw a regular "beam" that connects the source and target - - // First, figure out start and end positions relative to the camera - LLVector3 start_pos_agent; - if (mSourceObject->getPCode() == LL_PCODE_LEGACY_AVATAR) - { - LLViewerObject *objp = mSourceObject; - LLVOAvatar *avatarp = (LLVOAvatar *)objp; - LLVector3d hand_pos_global = gAgent.getPosGlobalFromAgent(avatarp->mWristLeftp->getWorldPosition()); - start_pos_agent = gAgent.getPosAgentFromGlobal(hand_pos_global); - } - else - { - start_pos_agent = mSourceObject->getPositionAgent(); - } - LLVector3 start_pos_camera = (start_pos_agent - gAgent.getCameraPositionAgent()); - LLVector3 target_pos_agent = gAgent.getPosAgentFromGlobal(mTargetPos); - LLVector3 target_pos_camera = target_pos_agent - gAgent.getCameraPositionAgent(); - - // Generate the right "up" vector which is perpendicular to the beam, make it 1/10 meter wide, going to a point. - LLVector3 camera_up = gCamera->getUpAxis(); - LLVector3 camera_at = gCamera->getAtAxis(); - LLVector3 up = target_pos_camera % start_pos_camera; - up.normVec(); - up *= 0.1f; - - // Draw the triangle for the beam. - LLVector3 vertex; - glColor4ubv(coloru.mV); - glBegin(GL_TRIANGLE_STRIP); - vertex = start_pos_agent + up; - glVertex3fv(vertex.mV); - vertex = start_pos_agent - up; - glVertex3fv(vertex.mV); - vertex = target_pos_agent; - glVertex3fv(vertex.mV); - glEnd(); - */ // Draw the particles S32 i; diff --git a/linden/indra/newview/llhudeffectlookat.cpp b/linden/indra/newview/llhudeffectlookat.cpp index 207946d..4cd69bb 100644 --- a/linden/indra/newview/llhudeffectlookat.cpp +++ b/linden/indra/newview/llhudeffectlookat.cpp @@ -33,6 +33,8 @@ #include "llhudeffectlookat.h" +#include "llglimmediate.h" + #include "message.h" #include "llagent.h" #include "llvoavatar.h" @@ -498,19 +500,19 @@ void LLHUDEffectLookAt::render() glPushMatrix(); glTranslatef(target.mV[VX], target.mV[VY], target.mV[VZ]); glScalef(0.3f, 0.3f, 0.3f); - glBegin(GL_LINES); + gGL.begin(GL_LINES); { LLColor3 color = (*mAttentions)[mTargetType].mColor; - glColor3f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]); - glVertex3f(-1.f, 0.f, 0.f); - glVertex3f(1.f, 0.f, 0.f); + gGL.color3f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]); + gGL.vertex3f(-1.f, 0.f, 0.f); + gGL.vertex3f(1.f, 0.f, 0.f); - glVertex3f(0.f, -1.f, 0.f); - glVertex3f(0.f, 1.f, 0.f); + gGL.vertex3f(0.f, -1.f, 0.f); + gGL.vertex3f(0.f, 1.f, 0.f); - glVertex3f(0.f, 0.f, -1.f); - glVertex3f(0.f, 0.f, 1.f); - } glEnd(); + gGL.vertex3f(0.f, 0.f, -1.f); + gGL.vertex3f(0.f, 0.f, 1.f); + } gGL.end(); glPopMatrix(); } } diff --git a/linden/indra/newview/llhudeffectlookat.h b/linden/indra/newview/llhudeffectlookat.h index 4e5e77f..cc64c67 100644 --- a/linden/indra/newview/llhudeffectlookat.h +++ b/linden/indra/newview/llhudeffectlookat.h @@ -33,7 +33,6 @@ #define LL_LLHUDEFFECTLOOKAT_H #include "llhudeffect.h" -#include "llskiplist.h" class LLViewerObject; class LLVOAvatar; diff --git a/linden/indra/newview/llhudeffectpointat.cpp b/linden/indra/newview/llhudeffectpointat.cpp index cd3077a..c47705b 100644 --- a/linden/indra/newview/llhudeffectpointat.cpp +++ b/linden/indra/newview/llhudeffectpointat.cpp @@ -34,6 +34,7 @@ #include "llhudeffectpointat.h" #include "llgl.h" +#include "llglimmediate.h" #include "llagent.h" #include "lldrawable.h" @@ -329,18 +330,18 @@ void LLHUDEffectPointAt::render() glPushMatrix(); glTranslatef(target.mV[VX], target.mV[VY], target.mV[VZ]); glScalef(0.3f, 0.3f, 0.3f); - glBegin(GL_LINES); + gGL.begin(GL_LINES); { - glColor3f(1.f, 0.f, 0.f); - glVertex3f(-1.f, 0.f, 0.f); - glVertex3f(1.f, 0.f, 0.f); + gGL.color3f(1.f, 0.f, 0.f); + gGL.vertex3f(-1.f, 0.f, 0.f); + gGL.vertex3f(1.f, 0.f, 0.f); - glVertex3f(0.f, -1.f, 0.f); - glVertex3f(0.f, 1.f, 0.f); + gGL.vertex3f(0.f, -1.f, 0.f); + gGL.vertex3f(0.f, 1.f, 0.f); - glVertex3f(0.f, 0.f, -1.f); - glVertex3f(0.f, 0.f, 1.f); - } glEnd(); + gGL.vertex3f(0.f, 0.f, -1.f); + gGL.vertex3f(0.f, 0.f, 1.f); + } gGL.end(); glPopMatrix(); } } diff --git a/linden/indra/newview/llhudeffecttrail.cpp b/linden/indra/newview/llhudeffecttrail.cpp index 85b103f..ce5905d 100644 --- a/linden/indra/newview/llhudeffecttrail.cpp +++ b/linden/indra/newview/llhudeffecttrail.cpp @@ -84,7 +84,7 @@ void LLHUDEffectSpiral::markDead() mPartSourcep->setDead(); mPartSourcep = NULL; } - LLHUDObject::markDead(); + LLHUDEffect::markDead(); } void LLHUDEffectSpiral::packData(LLMessageSystem *mesgsys) @@ -250,7 +250,7 @@ void LLHUDEffectSpiral::triggerLocal() psb->setColor(color); if (mTargetObject.isNull()) { - psb->mLKGTargetPosGlobal = mPositionGlobal; + psb->mLKGTargetPosGlobal = mPositionGlobal; } } else @@ -277,10 +277,10 @@ void LLHUDEffectSpiral::render() { F32 time = mTimer.getElapsedTimeF32(); - if (!mSourceObject.isNull() && mSourceObject->isDead() || - !mTargetObject.isNull() && mTargetObject->isDead() || - mKillTime < time || - !gSavedSettings.getBOOL("ShowSelectionBeam")) + if ((!mSourceObject.isNull() && mSourceObject->isDead()) || + (!mTargetObject.isNull() && mTargetObject->isDead()) || + mKillTime < time || + (!mPartSourcep.isNull() && !gSavedSettings.getBOOL("ShowSelectionBeam")) ) { markDead(); return; diff --git a/linden/indra/newview/llhudicon.cpp b/linden/indra/newview/llhudicon.cpp index 2124827..393c932 100644 --- a/linden/indra/newview/llhudicon.cpp +++ b/linden/indra/newview/llhudicon.cpp @@ -34,6 +34,7 @@ #include "llhudicon.h" #include "llgl.h" +#include "llglimmediate.h" #include "llviewerobject.h" #include "lldrawable.h" @@ -83,8 +84,11 @@ void LLHUDIcon::renderIcon(BOOL for_select) { LLGLSUIDefault texture_state; LLGLDepthTest gls_depth(GL_TRUE); - LLGLState no_texture(GL_TEXTURE_2D, for_select ? FALSE : TRUE); - + if (for_select) + { + LLViewerImage::unbindTexture(0); + } + if (mHidden) return; @@ -152,28 +156,28 @@ void LLHUDIcon::renderIcon(BOOL for_select) { // set color to unique color id for picking LLColor4U coloru((U8)(mPickID >> 16), (U8)(mPickID >> 8), (U8)mPickID); - glColor4ubv(coloru.mV); + gGL.color4ubv(coloru.mV); } else { LLColor4 icon_color = LLColor4::white; icon_color.mV[VALPHA] = alpha_factor; - glColor4fv(icon_color.mV); + gGL.color4fv(icon_color.mV); LLViewerImage::bindTexture(mImagep); } - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { - glTexCoord2f(0.f, 1.f); - glVertex3fv(upper_left.mV); - glTexCoord2f(0.f, 0.f); - glVertex3fv(lower_left.mV); - glTexCoord2f(1.f, 0.f); - glVertex3fv(lower_right.mV); - glTexCoord2f(1.f, 1.f); - glVertex3fv(upper_right.mV); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3fv(upper_left.mV); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex3fv(lower_left.mV); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3fv(lower_right.mV); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex3fv(upper_right.mV); } - glEnd(); + gGL.end(); } void LLHUDIcon::setImage(LLViewerImage* imagep) diff --git a/linden/indra/newview/llhudmanager.cpp b/linden/indra/newview/llhudmanager.cpp index 5810cd2..2c38943 100644 --- a/linden/indra/newview/llhudmanager.cpp +++ b/linden/indra/newview/llhudmanager.cpp @@ -37,7 +37,6 @@ #include "object_flags.h" #include "llagent.h" -#include "llhudconnector.h" #include "llhudeffect.h" #include "pipeline.h" #include "llviewercontrol.h" @@ -91,7 +90,7 @@ void LLHUDManager::sendEffects() llwarns << "Trying to send dead effect!" << llendl; continue; } - if (hep->mType <= LLHUDObject::LL_HUD_CONNECTOR) + if (hep->mType < LLHUDObject::LL_HUD_EFFECT_BEAM) { llwarns << "Trying to send effect of type " << hep->mType << " which isn't really an effect and shouldn't be in this list!" << llendl; continue; diff --git a/linden/indra/newview/llhudmanager.h b/linden/indra/newview/llhudmanager.h index 881e744..cf63784 100644 --- a/linden/indra/newview/llhudmanager.h +++ b/linden/indra/newview/llhudmanager.h @@ -36,9 +36,6 @@ #include "llhudobject.h" #include "lldarray.h" -#include "llanimalcontrols.h" -#include "lllocalanimationobject.h" -#include "llcape.h" class LLViewerObject; class LLHUDEffect; diff --git a/linden/indra/newview/llhudobject.cpp b/linden/indra/newview/llhudobject.cpp index 4c27211..c2525eb 100644 --- a/linden/indra/newview/llhudobject.cpp +++ b/linden/indra/newview/llhudobject.cpp @@ -39,17 +39,11 @@ #include "llhudtext.h" #include "llhudicon.h" -#include "llhudconnector.h" #include "llhudeffectbeam.h" #include "llhudeffecttrail.h" #include "llhudeffectlookat.h" -//Ventrella #include "llvoicevisualizer.h" -#include "llanimalcontrols.h" -#include "lllocalanimationobject.h" -#include "llcape.h" -// End Ventrella #include "llagent.h" @@ -155,9 +149,6 @@ LLHUDObject *LLHUDObject::addHUDObject(const U8 type) case LL_HUD_ICON: hud_objectp = new LLHUDIcon(type); break; - case LL_HUD_CONNECTOR: - hud_objectp = new LLHUDConnector(type); - break; default: llwarns << "Unknown type of hud object:" << (U32) type << llendl; } diff --git a/linden/indra/newview/llhudobject.h b/linden/indra/newview/llhudobject.h index 277b59a..5b9872a 100644 --- a/linden/indra/newview/llhudobject.h +++ b/linden/indra/newview/llhudobject.h @@ -41,7 +41,6 @@ #include "v4color.h" #include "v3math.h" #include "v3dmath.h" -#include "linked_lists.h" #include "lldrawpool.h" #include diff --git a/linden/indra/newview/llhudrender.cpp b/linden/indra/newview/llhudrender.cpp index a803b0e..df1fa46 100644 --- a/linden/indra/newview/llhudrender.cpp +++ b/linden/indra/newview/llhudrender.cpp @@ -100,16 +100,10 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent, LLVector3 render_pos = pos_agent + (floorf(x_offset) * right_axis) + (floorf(y_offset) * up_axis); //get the render_pos in screen space - F64 modelview[16]; - F64 projection[16]; - GLint viewport[4]; - glGetDoublev(GL_MODELVIEW_MATRIX, modelview); - glGetDoublev(GL_PROJECTION_MATRIX, projection); - glGetIntegerv(GL_VIEWPORT, viewport); - + F64 winX, winY, winZ; gluProject(render_pos.mV[0], render_pos.mV[1], render_pos.mV[2], - modelview, projection, viewport, + gGLModelView, gGLProjection, (GLint*) gGLViewport, &winX, &winY, &winZ); //fonts all render orthographically, set up projection diff --git a/linden/indra/newview/llhudtext.cpp b/linden/indra/newview/llhudtext.cpp index 7515a1b..5dc016e 100644 --- a/linden/indra/newview/llhudtext.cpp +++ b/linden/indra/newview/llhudtext.cpp @@ -33,6 +33,8 @@ #include "llhudtext.h" +#include "llglimmediate.h" + #include "llagent.h" #include "llviewercontrol.h" #include "llchatbar.h" @@ -262,7 +264,7 @@ void LLHUDText::renderText(BOOL for_select) LLGLSNoTexture no_texture_state; S32 name = mSourceObject->mGLName; LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name); - glColor4ubv(coloru.mV); + gGL.color4ubv(coloru.mV); gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec); LLUI::popMatrix(); return; @@ -271,14 +273,14 @@ void LLHUDText::renderText(BOOL for_select) { LLViewerImage::bindTexture(imagep); - glColor4fv(bg_color.mV); + gGL.color4fv(bg_color.mV); gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec); if ( mLabelSegments.size()) { LLUI::pushMatrix(); { - glColor4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); + gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec; LLVector3 label_offset = height_vec - label_height; LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]); @@ -296,7 +298,7 @@ void LLHUDText::renderText(BOOL for_select) { LLUI::pushMatrix(); { - glColor4fv(bg_color.mV); + gGL.color4fv(bg_color.mV); LLVector3 target_pos = -1.f * (mPositionOffset.mV[VX] * x_pixel_vec + mPositionOffset.mV[VY] * y_pixel_vec); target_pos += (width_vec / 2.f); target_pos += mVertAlignment == ALIGN_VERT_CENTER ? (height_vec * 0.5f) : LLVector3::zero; @@ -308,15 +310,15 @@ void LLHUDText::renderText(BOOL for_select) LLUI::popMatrix(); - LLGLDisable gls_texture_2d(GL_TEXTURE_2D); + LLImageGL::unbindTexture(0); LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE); LLVector3 box_center_offset; box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f); LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]); - glColor4fv(bg_color.mV); + gGL.color4fv(bg_color.mV); LLUI::setLineWidth(2.0); - glBegin(GL_LINES); + gGL.begin(GL_LINES); { if (outside_width) { @@ -326,20 +328,20 @@ void LLHUDText::renderText(BOOL for_select) { // start at right edge vert = width_vec * 0.5f; - glVertex3fv(vert.mV); + gGL.vertex3fv(vert.mV); } else { // start at left edge vert = width_vec * -0.5f; - glVertex3fv(vert.mV); + gGL.vertex3fv(vert.mV); } vert = -mPositionOffset.mV[VX] * x_pixel_vec; - glVertex3fv(vert.mV); - glVertex3fv(vert.mV); + gGL.vertex3fv(vert.mV); + gGL.vertex3fv(vert.mV); vert -= mPositionOffset.mV[VY] * y_pixel_vec; vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero); - glVertex3fv(vert.mV); + gGL.vertex3fv(vert.mV); } else { @@ -349,20 +351,20 @@ void LLHUDText::renderText(BOOL for_select) { // start at top edge vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec); - glVertex3fv(vert.mV); + gGL.vertex3fv(vert.mV); } else { // start at bottom edge vert = (height_vec * -0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec); - glVertex3fv(vert.mV); + gGL.vertex3fv(vert.mV); } vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec; vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero); - glVertex3fv(vert.mV); + gGL.vertex3fv(vert.mV); } } - glEnd(); + gGL.end(); LLUI::setLineWidth(1.0); } @@ -441,6 +443,8 @@ void LLHUDText::renderText(BOOL for_select) hud_render_text(segment_iter->getText(), render_position, *fontp, style, x_offset, y_offset, text_color, mOnHUDAttachment); } } + /// Reset the default color to white. The renderer expects this to be the default. + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } void LLHUDText::setStringUTF8(const std::string &wtext) diff --git a/linden/indra/newview/llimpanel.cpp b/linden/indra/newview/llimpanel.cpp index 193beb9..9e6739f 100644 --- a/linden/indra/newview/llimpanel.cpp +++ b/linden/indra/newview/llimpanel.cpp @@ -438,7 +438,7 @@ void LLVoiceChannel::handleStatusChange(EStatusType type) case STATUS_LOGGED_IN: if (!mLoginNotificationHandle.isDead()) { - LLNotifyBox* notifyp = (LLNotifyBox*)LLPanel::getPanelByHandle(mLoginNotificationHandle); + LLNotifyBox* notifyp = (LLNotifyBox*)mLoginNotificationHandle.get(); if (notifyp) { notifyp->close(); @@ -1251,9 +1251,9 @@ BOOL LLFloaterIMPanel::postBuild() childSetEnabled("profile_btn", FALSE); } - sTitleString = getFormattedUIString("title_string"); - sTypingStartString = getFormattedUIString("typing_start_string"); - sSessionStartString = getFormattedUIString("session_start_string"); + sTitleString = getString("title_string"); + sTypingStartString = getString("typing_start_string"); + sSessionStartString = getString("session_start_string"); if (mSpeakerPanel) { @@ -1330,12 +1330,12 @@ void LLFloaterIMPanel::draw() if (self_speaker.notNull() && self_speaker->mModeratorMutedText) { mInputEditor->setEnabled(FALSE); - mInputEditor->setLabel(getFormattedUIString("muted_text_label")); + mInputEditor->setLabel(getString("muted_text_label")); } else { mInputEditor->setEnabled(TRUE); - mInputEditor->setLabel(getFormattedUIString("default_text_label")); + mInputEditor->setLabel(getString("default_text_label")); } if (mAutoConnect && enable_connect) @@ -1543,7 +1543,7 @@ void LLFloaterIMPanel::selectNone() BOOL LLFloaterIMPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent ) { BOOL handled = FALSE; - if( getVisible() && mEnabled && !called_from_parent && gFocusMgr.childHasKeyboardFocus(this)) + if( getVisible() && getEnabled() && !called_from_parent && gFocusMgr.childHasKeyboardFocus(this)) { if( KEY_RETURN == key && mask == MASK_NONE) { @@ -1930,7 +1930,7 @@ void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update) if (voice_moderated) { - setTitle(mSessionLabel + LLString(" ") + getFormattedUIString("moderated_chat_label")); + setTitle(mSessionLabel + LLString(" ") + getString("moderated_chat_label")); } else { diff --git a/linden/indra/newview/llimpanel.h b/linden/indra/newview/llimpanel.h index daa6820..a344ba0 100644 --- a/linden/indra/newview/llimpanel.h +++ b/linden/indra/newview/llimpanel.h @@ -100,7 +100,7 @@ protected: LLString mSessionName; LLString::format_map_t mNotifyArgs; BOOL mIgnoreNextSessionLeave; - LLViewHandle mLoginNotificationHandle; + LLHandle mLoginNotificationHandle; typedef std::map voice_channel_map_t; static voice_channel_map_t sVoiceChannelMap; diff --git a/linden/indra/newview/llimview.cpp b/linden/indra/newview/llimview.cpp index 2f9c1eb..92e46b4 100644 --- a/linden/indra/newview/llimview.cpp +++ b/linden/indra/newview/llimview.cpp @@ -40,7 +40,6 @@ #include "llhttpclient.h" #include "llsdutil.h" #include "llstring.h" -#include "linked_lists.h" #include "llvieweruictrlfactory.h" #include "llagent.h" @@ -158,7 +157,7 @@ LLFloaterIM::LLFloaterIM() BOOL LLFloaterIM::postBuild() { - sOnlyUserMessage = getFormattedUIString("only_user_message"); + sOnlyUserMessage = getString("only_user_message"); sOfflineMessage = getUIString("offline_message"); sInviteMessage = getUIString("invite_message"); @@ -166,75 +165,75 @@ BOOL LLFloaterIM::postBuild() if ( sErrorStringsMap.find("generic") == sErrorStringsMap.end() ) { sErrorStringsMap["generic"] = - getFormattedUIString("generic_request_error"); + getString("generic_request_error"); } if ( sErrorStringsMap.find("unverified") == sErrorStringsMap.end() ) { sErrorStringsMap["unverified"] = - getFormattedUIString("insufficient_perms_error"); + getString("insufficient_perms_error"); } if ( sErrorStringsMap.end() == sErrorStringsMap.find("no_ability") ) { sErrorStringsMap["no_ability"] = - getFormattedUIString("no_ability_error"); + getString("no_ability_error"); } if ( sErrorStringsMap.end() == sErrorStringsMap.find("muted") ) { sErrorStringsMap["muted"] = - getFormattedUIString("muted_error"); + getString("muted_error"); } if ( sErrorStringsMap.end() == sErrorStringsMap.find("not_a_moderator") ) { sErrorStringsMap["not_a_moderator"] = - getFormattedUIString("not_a_mod_error"); + getString("not_a_mod_error"); } if ( sErrorStringsMap.end() == sErrorStringsMap.find("does not exist") ) { sErrorStringsMap["does not exist"] = - getFormattedUIString("session_does_not_exist_error"); + getString("session_does_not_exist_error"); } if ( sEventStringsMap.end() == sEventStringsMap.find("add") ) { sEventStringsMap["add"] = - getFormattedUIString("add_session_event"); + getString("add_session_event"); } if ( sEventStringsMap.end() == sEventStringsMap.find("message") ) { sEventStringsMap["message"] = - getFormattedUIString("message_session_event"); + getString("message_session_event"); } if ( sEventStringsMap.end() == sEventStringsMap.find("mute") ) { - sEventStringsMap["mute"] = getFormattedUIString( - "mute_agent_event"); + sEventStringsMap["mute"] = + getString("mute_agent_event"); } if ( sForceCloseSessionMap.end() == sForceCloseSessionMap.find("removed") ) { sForceCloseSessionMap["removed"] = - getFormattedUIString("removed_from_group"); + getString("removed_from_group"); } if ( sForceCloseSessionMap.end() == sForceCloseSessionMap.find("no ability") ) { sForceCloseSessionMap["no ability"] = - getFormattedUIString("close_on_no_ability"); + getString("close_on_no_ability"); } return TRUE; @@ -1015,12 +1014,12 @@ BOOL LLIMMgr::getFloaterOpen() void LLIMMgr::disconnectAllSessions() { LLFloaterIMPanel* floater = NULL; - std::set::iterator handle_it; + std::set >::iterator handle_it; for(handle_it = mFloaters.begin(); handle_it != mFloaters.end(); ) { - floater = (LLFloaterIMPanel*)LLFloater::getFloaterByHandle(*handle_it); + floater = (LLFloaterIMPanel*)handle_it->get(); // MUST do this BEFORE calling floater->onClose() because that may remove the item from the set, causing the subsequent increment to crash. ++handle_it; @@ -1040,12 +1039,12 @@ void LLIMMgr::disconnectAllSessions() LLFloaterIMPanel* LLIMMgr::findFloaterBySession(const LLUUID& session_id) { LLFloaterIMPanel* rv = NULL; - std::set::iterator handle_it; + std::set >::iterator handle_it; for(handle_it = mFloaters.begin(); handle_it != mFloaters.end(); ++handle_it) { - rv = (LLFloaterIMPanel*)LLFloater::getFloaterByHandle(*handle_it); + rv = (LLFloaterIMPanel*)handle_it->get(); if(rv && session_id == rv->getSessionID()) { break; @@ -1171,7 +1170,7 @@ LLFloaterIMPanel* LLIMMgr::createFloater( session_id, other_participant_id, dialog); - LLTabContainerCommon::eInsertionPoint i_pt = user_initiated ? LLTabContainerCommon::RIGHT_OF_CURRENT : LLTabContainerCommon::END; + LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END; LLFloaterChatterBox::getInstance(LLSD())->addFloater(floater, FALSE, i_pt); mFloaters.insert(floater->getHandle()); return floater; @@ -1197,7 +1196,7 @@ LLFloaterIMPanel* LLIMMgr::createFloater( other_participant_id, ids, dialog); - LLTabContainerCommon::eInsertionPoint i_pt = user_initiated ? LLTabContainerCommon::RIGHT_OF_CURRENT : LLTabContainerCommon::END; + LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END; LLFloaterChatterBox::getInstance(LLSD())->addFloater(floater, FALSE, i_pt); mFloaters.insert(floater->getHandle()); return floater; @@ -1219,8 +1218,7 @@ void LLIMMgr::noteOfflineUsers( for(S32 i = 0; i < count; ++i) { info = at.getBuddyInfo(ids.get(i)); - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + std::string first, last; if(info && !info->isOnline() && gCacheName->getName(ids.get(i), first, last)) { @@ -1628,3 +1626,4 @@ LLHTTPRegistration LLHTTPRegistration gHTTPRegistrationMessageChatterBoxInvitation( "/message/ChatterBoxInvitation"); + diff --git a/linden/indra/newview/llimview.h b/linden/indra/newview/llimview.h index 0774698..44cb992 100644 --- a/linden/indra/newview/llimview.h +++ b/linden/indra/newview/llimview.h @@ -165,7 +165,7 @@ public: void clearPendingAgentListUpdates(const LLUUID& session_id); //HACK: need a better way of enumerating existing session, or listening to session create/destroy events - const std::set& getIMFloaterHandles() { return mFloaters; } + const std::set >& getIMFloaterHandles() { return mFloaters; } private: class LLIMSessionInvite; @@ -199,7 +199,7 @@ private: static void onInviteNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* userdata); private: - std::set mFloaters; + std::set > mFloaters; LLFriendObserver* mFriendObserver; // An IM has been received that you haven't seen yet. diff --git a/linden/indra/newview/llinventoryactions.cpp b/linden/indra/newview/llinventoryactions.cpp index 69202cb..27afb17 100644 --- a/linden/indra/newview/llinventoryactions.cpp +++ b/linden/indra/newview/llinventoryactions.cpp @@ -647,10 +647,11 @@ class LLAttachObject : public inventory_panel_listener_t LLString joint_name = userdata.asString(); LLVOAvatar *avatarp = gAgent.getAvatarObject(); LLViewerJointAttachment* attachmentp = NULL; - for (LLViewerJointAttachment* attachment = avatarp->mAttachmentPoints.getFirstData(); - attachment; - attachment = gAgent.getAvatarObject()->mAttachmentPoints.getNextData()) + for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); + iter != avatarp->mAttachmentPoints.end(); ) { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; if (attachment->getName() == joint_name) { attachmentp = attachment; diff --git a/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp index 58b8af2..6d981cc 100644 --- a/linden/indra/newview/llinventorybridge.cpp +++ b/linden/indra/newview/llinventorybridge.cpp @@ -488,11 +488,11 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } // *TODO: remove this -BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) +BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const { BOOL rv = FALSE; - LLInventoryObject* obj = getInventoryObject(); + const LLInventoryObject* obj = getInventoryObject(); if(obj) { @@ -3273,8 +3273,20 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach { LLAttachmentRezAction* rez_action = new LLAttachmentRezAction; rez_action->mItemID = item->getUUID(); - rez_action->mAttachPt = gAgent.getAvatarObject()->mAttachmentPoints.reverseLookup(attachment); - + S32 attach_pt = 0; + if (gAgent.getAvatarObject() && attachment) + { + for (LLVOAvatar::attachment_map_t::iterator iter = gAgent.getAvatarObject()->mAttachmentPoints.begin(); + iter != gAgent.getAvatarObject()->mAttachmentPoints.end(); ++iter) + { + if (iter->second == attachment) + { + rez_action->mAttachPt = iter->first; + break; + } + } + } + rez_action->mAttachPt = attach_pt; if (attachment && attachment->getObject()) { gViewerWindow->alertXml("ReplaceAttachment", confirm_replace_attachment_rez, (void*)rez_action); @@ -3365,10 +3377,11 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) attach_hud_menu && (attach_hud_menu->getChildCount() == 0) && avatarp) { - for (LLViewerJointAttachment* attachment = avatarp->mAttachmentPoints.getFirstData(); - attachment; - attachment = gAgent.getAvatarObject()->mAttachmentPoints.getNextData()) + for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); + iter != avatarp->mAttachmentPoints.end(); ) { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; LLMenuItemCallGL *new_item; if (attachment->getIsHUDAttachment()) { @@ -3509,8 +3522,13 @@ struct LLFoundData struct LLWearableHoldingPattern { LLWearableHoldingPattern() : mResolved(0) {} - ~LLWearableHoldingPattern() { mFoundList.deleteAllData(); } - LLDoubleLinkedList mFoundList; + ~LLWearableHoldingPattern() + { + for_each(mFoundList.begin(), mFoundList.end(), DeletePointer()); + mFoundList.clear(); + } + typedef std::list found_list_t; + found_list_t mFoundList; S32 mResolved; }; @@ -3900,7 +3918,7 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata ) item_array.get(i)->getAssetUUID(), item_array.get(i)->getName(), item_array.get(i)->getType()); - holder->mFoundList.addData(found); + holder->mFoundList.push_front(found); found_container.put(found); } for(i = 0; i < wearable_count; ++i) @@ -3991,10 +4009,10 @@ void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void* data) if(wearable) { - for(LLFoundData* data = holder->mFoundList.getFirstData(); - data; - data = holder->mFoundList.getNextData() ) + for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); + iter != holder->mFoundList.end(); ++iter) { + LLFoundData* data = *iter; if(wearable->getID() == data->mAssetID) { data->mWearable = wearable; @@ -4003,7 +4021,7 @@ void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void* data) } } holder->mResolved += 1; - if(holder->mResolved >= holder->mFoundList.getLength()) + if(holder->mResolved >= (S32)holder->mFoundList.size()) { wear_inventory_category_on_avatar_step3(holder, append); } @@ -4019,10 +4037,10 @@ void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, B // that we recursed through. for( S32 i = 0; i < WT_COUNT; i++ ) { - for(LLFoundData* data = holder->mFoundList.getFirstData(); - data; - data = holder->mFoundList.getNextData()) + for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->mFoundList.begin(); + iter != holder->mFoundList.end(); ++iter) { + LLFoundData* data = *iter; LLWearable* wearable = data->mWearable; if( wearable && ((S32)wearable->getType() == i) ) { diff --git a/linden/indra/newview/llinventorybridge.h b/linden/indra/newview/llinventorybridge.h index a008779..cca56c2 100644 --- a/linden/indra/newview/llinventorybridge.h +++ b/linden/indra/newview/llinventorybridge.h @@ -188,7 +188,7 @@ public: void getClipboardEntries(bool show_asset_id, std::vector &items, std::vector &disabled_items, U32 flags); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); - virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id); + virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const; virtual BOOL dragOrDrop(MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data) { return FALSE; } diff --git a/linden/indra/newview/llinventorymodel.cpp b/linden/indra/newview/llinventorymodel.cpp index 9fb5ae9..feab282 100644 --- a/linden/indra/newview/llinventorymodel.cpp +++ b/linden/indra/newview/llinventorymodel.cpp @@ -47,6 +47,7 @@ #include "llviewerinventory.h" #include "llviewermessage.h" #include "llviewerwindow.h" +#include "llviewerregion.h" #include "llappviewer.h" #include "lldbstrings.h" #include "llviewerstats.h" @@ -54,6 +55,8 @@ #include "llnotify.h" #include "llcallbacklist.h" #include "llpreview.h" +#include "llviewercontrol.h" +#include "llsdutil.h" #include //#define DIFF_INVENTORY_FILES @@ -69,6 +72,8 @@ F32 LLInventoryModel::sMinTimeBetweenFetches = 0.3f; F32 LLInventoryModel::sMaxTimeBetweenFetches = 10.f; BOOL LLInventoryModel::sTimelyFetchPending = FALSE; LLFrameTimer LLInventoryModel::sFetchTimer; +LLInventoryModel::cat_map_t LLInventoryModel::sBulkFetchMap; +S16 LLInventoryModel::sBulkFetchCount = 0; // RN: for some reason, using std::queue in the header file confuses the compiler which things it's an xmlrpc_queue static std::deque sFetchQueue; @@ -1002,6 +1007,286 @@ void LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id) } } +//Initialize statics. +LLAlertDialog* LLInventoryModel::fetchDescendentsResponder::sRetryDialog=NULL; +LLSD LLInventoryModel::fetchDescendentsResponder::sRetrySD; + +bool LLInventoryModel::isBulkFetchProcessingComplete() +{ + return ( (sFetchQueue.empty() + && sBulkFetchMap.empty() + && sBulkFetchCount==0) ? TRUE : FALSE ) ; +} + +//If we get back a normal response, handle it here +void LLInventoryModel::fetchDescendentsResponder::result(const LLSD& content) +{ + if (content.has("folders")) + { + for(LLSD::array_const_iterator folder_it = content["folders"].beginArray(); + folder_it != content["folders"].endArray(); + ++folder_it) + { + LLSD folder_sd = *folder_it; + + + LLUUID agent_id = folder_sd["agent-id"]; + + if(agent_id != gAgent.getID()) //This should never happen. + { + llwarns << "Got a UpdateInventoryItem for the wrong agent." + << llendl; + break; + } + LLUUID parent_id = folder_sd["folder-id"]; + LLUUID owner_id = folder_sd["owner-id"]; + S32 version = (S32)folder_sd["version"].asInteger(); + S32 descendents = (S32)folder_sd["descendents"].asInteger(); + LLPointer tcategory = new LLViewerInventoryCategory(owner_id); + for(LLSD::array_const_iterator category_it = folder_sd["categories"].beginArray(); + category_it != folder_sd["categories"].endArray(); + ++category_it) + { + LLSD category = *category_it; + tcategory->fromLLSD(category); + + if (sFullFetchStarted) + { + sFetchQueue.push_back(tcategory->getUUID()); + } + else if ( !gInventory.isCategoryComplete(tcategory->getUUID()) ) + { + gInventory.updateCategory(tcategory); + } + + } + LLPointer titem = new LLViewerInventoryItem; + for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray(); + item_it != folder_sd["items"].endArray(); + ++item_it) + { + LLSD item = *item_it; + titem->unpackMessage(item); + + gInventory.updateItem(titem); + } + + // set version and descendentcount according to message. + LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id); + if(cat) + { + cat->setVersion(version); + cat->setDescendentCount(descendents); + } + + } + } + + if (content.has("bad-folders")) + { + for(LLSD::array_const_iterator folder_it = content["bad-folders"].beginArray(); + folder_it != content["bad-folders"].endArray(); + ++folder_it) + { + LLSD folder_sd = *folder_it; + + //These folders failed on the dataserver. We probably don't want to retry them. + llinfos << "Folder " << folder_sd["folder-id"].asString() + << "Error: " << folder_sd["error"].asString() << llendl; + } + } + + LLInventoryModel::incrBulkFetch(-1); + + if (isBulkFetchProcessingComplete()) + { + llinfos << "Inventory fetch completed" << llendl; + if (sFullFetchStarted) + { + sAllFoldersFetched = TRUE; + } + stopBackgroundFetch(); + } + + gInventory.notifyObservers(); +} + +//If we get back an error (not found, etc...), handle it here +void LLInventoryModel::fetchDescendentsResponder::error(U32 status, const std::string& reason) +{ + llinfos << "fetchDescendentsResponder::error " + << status << ": " << reason << llendl; + + LLInventoryModel::incrBulkFetch(-1); + + if (status==499) //timed out. Let's be awesome! + { + for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray(); + folder_it != mRequestSD["folders"].endArray(); + ++folder_it) + { + LLSD folder_sd = *folder_it; + sRetrySD["folders"].append(folder_sd); + } + sMinTimeBetweenFetches = 10.0f; //Add 10 seconds for every time out in this sequence. + + if (!sRetryDialog) //The dialog isn't up. Prompt the resident. + { + sRetryDialog = gViewerWindow->alertXml("RetryFetchInventoryDescendents", onClickRetry, this); + } + } + else + { + if (isBulkFetchProcessingComplete()) + { + if (sFullFetchStarted) + { + sAllFoldersFetched = TRUE; + } + stopBackgroundFetch(); + } + } + gInventory.notifyObservers(); +} + +void LLInventoryModel::fetchDescendentsResponder::onClickRetry(S32 option, void* userdata) +{ + if (option == 0) + { + std::string url = gAgent.getRegion()->getCapability("FetchInventoryDescendents"); + + if (!url.empty()) //Capability found. Build up LLSD and use it. + { + LLSD body = sRetrySD; + LLInventoryModel::incrBulkFetch(1); + LLHTTPClient::post(url, body, new LLInventoryModel::fetchDescendentsResponder(body),300); + } + } + else + { + if (isBulkFetchProcessingComplete()) + { + if (sFullFetchStarted) + { + sAllFoldersFetched = TRUE; + } + stopBackgroundFetch(); + } + } + sRetryDialog=NULL; + sRetrySD.clear(); +} + +//static Bundle up a bunch of requests to send all at once. +void LLInventoryModel::bulkFetch(std::string url) +{ + //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. + //If there are items in sFetchQueue, we want to check the time since the last bulkFetch was + //sent. If it exceeds our retry time, go ahead and fire off another batch. + //Stopbackgroundfetch will be run from the Responder instead of here. + + S16 max_concurrent_fetches=8; + F32 new_min_time = 0.5f; //HACK! Clean this up when old code goes away entirely. + if (sMinTimeBetweenFetches <= new_min_time) sMinTimeBetweenFetches=new_min_time; //HACK! See above. + + if(gDisconnected + || sBulkFetchCount > max_concurrent_fetches + || sFetchTimer.getElapsedTimeF32() < sMinTimeBetweenFetches) + { + return; // just bail if we are disconnected. + } + + //HACK. This is inelegant. We're shuffling a dequeue to a map to get rid of + //redundant requests. When we get rid of the old code entirely, we can change + //the dequeue to a map. In the new model, there is no benefit to queue order. + U32 folder_count=0; + U32 max_batch_size=10; + while( !(sFetchQueue.empty() ) ) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(sFetchQueue.front()); + + if (cat) + { + if ( !gInventory.isCategoryComplete(cat->getUUID()) ) //grab this folder. + { + sBulkFetchMap[(cat->getUUID())] = cat; + } + else if (sFullFetchStarted) + { //Already have this folder but append child folders to list. + // add all children to queue + parent_cat_map_t::iterator cat_it = gInventory.mParentChildCategoryTree.find(cat->getUUID()); + if (cat_it != gInventory.mParentChildCategoryTree.end()) + { + cat_array_t* child_categories = cat_it->second; + + for (S32 child_num = 0; child_num < child_categories->count(); child_num++) + { + sFetchQueue.push_back(child_categories->get(child_num)->getUUID()); + } + } + + } + } + sFetchQueue.pop_front(); + } + + + if (!sBulkFetchMap.empty()) //There's stuff to fetch. + { + U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1; + + LLSD body; + + cat_map_t::iterator iter=sBulkFetchMap.begin(); + while( iter!=sBulkFetchMap.end() && (folder_count < max_batch_size) ) + { + LLViewerInventoryCategory* cat = iter->second; + + if (cat && !gInventory.isCategoryComplete(cat->getUUID()) ) //Category exists + { + BOOL fetchItems=TRUE; + if ( sFullFetchStarted + && gInventory.isCategoryComplete(cat->getUUID()) ) + { + fetchItems=FALSE; + } + + LLSD folder_sd; + folder_sd["folder-id"] = cat->getUUID(); + folder_sd["owner-id"] = cat->getOwnerID(); + folder_sd["sort-order"] = (LLSD::Integer)sort_order; + folder_sd["fetch-folders"] = (LLSD::Boolean)sFullFetchStarted; + folder_sd["fetch-items"] = (LLSD::Boolean)fetchItems; + body["folders"].append(folder_sd); + + folder_count++; + } + sBulkFetchMap.erase(iter); + iter=sBulkFetchMap.begin(); + } + + if (iter == sBulkFetchMap.end()) sBulkFetchMap.clear(); + + if (folder_count > 0) + { + sBulkFetchCount++; + + LLHTTPClient::post(url, body, new LLInventoryModel::fetchDescendentsResponder(body)); + sFetchTimer.reset(); + } + + } + + if (isBulkFetchProcessingComplete()) + { + if (sFullFetchStarted) + { + sAllFoldersFetched = TRUE; + } + stopBackgroundFetch(); + } +} + // static bool LLInventoryModel::isEverythingFetched() { @@ -1049,6 +1334,9 @@ void LLInventoryModel::stopBackgroundFetch() { sBackgroundFetchActive = FALSE; gIdleCallbacks.deleteFunction(&LLInventoryModel::backgroundFetch, NULL); + sBulkFetchCount=0; + sMinTimeBetweenFetches=0.0f; +// sFullFetchStarted=FALSE; } } @@ -1057,6 +1345,15 @@ void LLInventoryModel::backgroundFetch(void*) { if (sBackgroundFetchActive) { + //If we'll be using the capability, we'll be sending batches and the background thing isn't as important. + std::string url = gAgent.getRegion()->getCapability("FetchInventoryDescendents"); + if (!url.empty()) + { + bulkFetch(url); + return; + } + + //DEPRECATED OLD CODE FOLLOWS. // no more categories to fetch, stop fetch process if (sFetchQueue.empty()) { @@ -3063,8 +3360,8 @@ void LLInventoryFetchDescendentsObserver::fetchDescendents( if(!cat) continue; if(!isComplete(cat)) { - cat->fetchDescendents(); - mIncompleteFolders.push_back(*it); + cat->fetchDescendents(); //blindly fetch it without seeing if anything else is fetching it. + mIncompleteFolders.push_back(*it); //Add to list of things being downloaded for this observer. } else { diff --git a/linden/indra/newview/llinventorymodel.h b/linden/indra/newview/llinventorymodel.h index 7b57787..8205bf4 100644 --- a/linden/indra/newview/llinventorymodel.h +++ b/linden/indra/newview/llinventorymodel.h @@ -91,6 +91,7 @@ class LLViewerInventoryItem; class LLViewerInventoryCategory; class LLMessageSystem; class LLInventoryCollectFunctor; +class LLAlertDialog; class LLInventoryModel { @@ -105,11 +106,26 @@ public: // These are used a lot... typedef LLDynamicArray > cat_array_t; typedef LLDynamicArray > item_array_t; - // construction & destruction LLInventoryModel(); ~LLInventoryModel(); + class fetchDescendentsResponder: public LLHTTPClient::Responder + { + public: + fetchDescendentsResponder(const LLSD& request_sd) : mRequestSD(request_sd) {}; + void result(const LLSD& content); + void error(U32 status, const std::string& reason); + static void onClickRetry(S32 option, void* userdata); + static void appendRetryList(LLSD retry_sd); + public: + typedef std::vector folder_ref_t; + protected: + LLSD mRequestSD; + static LLSD sRetrySD; + static LLAlertDialog *sRetryDialog; + }; + // // Accessors // @@ -263,6 +279,9 @@ public: // make sure we have the descendents in the structure. void fetchDescendentsOf(const LLUUID& folder_id); + + // Add categories to a list to be fetched in bulk. + static void bulkFetch(std::string url); // call this method to request the inventory. //void requestFromServer(const LLUUID& agent_id); @@ -348,7 +367,7 @@ public: static BOOL backgroundFetchActive(); static bool isEverythingFetched(); static void backgroundFetch(void*); // background fetch idle function - + static void incrBulkFetch(S16 fetching) { sBulkFetchCount+=fetching; if (sBulkFetchCount<0) sBulkFetchCount=0; } protected: // Internal methods which add inventory and make sure that all of @@ -395,7 +414,8 @@ protected: static void processInventoryDescendents(LLMessageSystem* msg, void**); static void processMoveInventoryItem(LLMessageSystem* msg, void**); static void processFetchInventoryReply(LLMessageSystem* msg, void**); - + static bool isBulkFetchProcessingComplete(); + bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting); protected: @@ -419,8 +439,6 @@ protected: mutable LLPointer mLastItem; // This last set of indices is used to map parents to children. - //LLPtrSkipMap mParentChildCategoryTree; - //LLPtrSkipMap mParentChildItemTree; typedef std::map parent_cat_map_t; typedef std::map parent_item_map_t; parent_cat_map_t mParentChildCategoryTree; @@ -430,6 +448,7 @@ protected: observer_list_t mObservers; // completing the fetch once per session should be sufficient + static cat_map_t sBulkFetchMap; static BOOL sBackgroundFetchActive; static BOOL sTimelyFetchPending; static BOOL sAllFoldersFetched; @@ -438,6 +457,7 @@ protected: static LLFrameTimer sFetchTimer; static F32 sMinTimeBetweenFetches; static F32 sMaxTimeBetweenFetches; + static S16 sBulkFetchCount; // This flag is used to handle an invalid inventory state. bool mIsAgentInvUsable; diff --git a/linden/indra/newview/llinventoryview.cpp b/linden/indra/newview/llinventoryview.cpp index c6c8548..340608b 100644 --- a/linden/indra/newview/llinventoryview.cpp +++ b/linden/indra/newview/llinventoryview.cpp @@ -453,7 +453,7 @@ LLInventoryView::LLInventoryView(const LLString& name, LLFloater(name, rect, "Inventory", RESIZE_YES, INV_MIN_WIDTH, INV_MIN_HEIGHT, DRAG_ON_TOP, MINIMIZE_NO, CLOSE_YES) - //LLViewHandle mFinderHandle takes care of its own initialization + //LLHandle mFinderHandle takes care of its own initialization { init(inventory); } @@ -464,7 +464,7 @@ LLInventoryView::LLInventoryView(const LLString& name, LLFloater(name, rect, "Inventory", RESIZE_YES, INV_MIN_WIDTH, INV_MIN_HEIGHT, DRAG_ON_TOP, MINIMIZE_NO, CLOSE_YES) - //LLViewHandle mFinderHandle takes care of its own initialization + //LLHandle mFinderHandle takes care of its own initialization { init(inventory); setRect(rect); // override XML @@ -767,6 +767,7 @@ void LLInventoryView::changed(U32 mask) } title << mFilterText; setTitle(title.str()); + } // static @@ -884,7 +885,7 @@ void LLInventoryView::toggleFindOptions() if (!floater) { LLInventoryViewFinder * finder = new LLInventoryViewFinder("Inventory Finder", - LLRect(mRect.mLeft - INV_FINDER_WIDTH, mRect.mTop, mRect.mLeft, mRect.mTop - INV_FINDER_HEIGHT), + LLRect(getRect().mLeft - INV_FINDER_WIDTH, getRect().mTop, getRect().mLeft, getRect().mTop - INV_FINDER_HEIGHT), this); mFinderHandle = finder->getHandle(); finder->open(); /*Flawfinder: ignore*/ @@ -1067,7 +1068,7 @@ BOOL LLInventoryView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, { if(needsToScroll) { - mFilterTabs->setDragAndDropDelayTimer(); + mFilterTabs->startDragAndDropDelayTimer(); } } @@ -1235,13 +1236,13 @@ BOOL LLInventoryPanel::postBuild() LLRect folder_rect(0, 0, - mRect.getWidth(), + getRect().getWidth(), 0); - mFolders = new LLFolderView(mName, NULL, folder_rect, LLUUID::null, this); + mFolders = new LLFolderView(getName(), NULL, folder_rect, LLUUID::null, this); mFolders->setAllowMultiSelect(mAllowMultiSelect); // scroller - LLRect scroller_view_rect = mRect; + LLRect scroller_view_rect = getRect(); scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); mScroller = new LLScrollableContainerView("Inventory Scroller", scroller_view_rect, diff --git a/linden/indra/newview/llinventoryview.h b/linden/indra/newview/llinventoryview.h index e8f3076..c8c3947 100644 --- a/linden/indra/newview/llinventoryview.h +++ b/linden/indra/newview/llinventoryview.h @@ -258,7 +258,7 @@ public: void toggleFindOptions(); - LLInventoryViewFinder* getFinder() { return (LLInventoryViewFinder*)LLFloater::getFloaterByHandle(mFinderHandle); } + LLInventoryViewFinder* getFinder() { return (LLInventoryViewFinder*)mFinderHandle.get(); } protected: // internal initialization code @@ -267,7 +267,7 @@ protected: protected: LLSearchEditor* mSearchEditor; LLTabContainer* mFilterTabs; - LLViewHandle mFinderHandle; + LLHandle mFinderHandle; LLInventoryPanel* mActivePanel; LLSaveFolderState* mSavedFolderState; @@ -372,3 +372,4 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach #endif // LL_LLINVENTORYVIEW_H + diff --git a/linden/indra/newview/lljoystickbutton.cpp b/linden/indra/newview/lljoystickbutton.cpp index dddbea8..b429ed2 100644 --- a/linden/indra/newview/lljoystickbutton.cpp +++ b/linden/indra/newview/lljoystickbutton.cpp @@ -36,6 +36,7 @@ // Library includes #include "llcoord.h" #include "indra_constants.h" +#include "llglimmediate.h" // Project includes #include "llui.h" @@ -72,18 +73,18 @@ LLJoystick::LLJoystick( mHeldDown(FALSE), mHeldDownTimer() { - mHeldDownCallback = &LLJoystick::onHeldDown; - mCallbackUserData = this; + setHeldDownCallback(&LLJoystick::onHeldDown); + setCallbackUserData(this); } void LLJoystick::updateSlop() { - mVertSlopNear = mRect.getHeight(); - mVertSlopFar = mRect.getHeight() * 2; + mVertSlopNear = getRect().getHeight(); + mVertSlopFar = getRect().getHeight() * 2; - mHorizSlopNear = mRect.getWidth(); - mHorizSlopFar = mRect.getWidth() * 2; + mHorizSlopNear = getRect().getWidth(); + mHorizSlopFar = getRect().getWidth() * 2; // Compute initial mouse offset based on initial quadrant. // Place the mouse evenly between the near and far zones. @@ -163,7 +164,7 @@ F32 LLJoystick::getElapsedHeldDownTime() { if( mHeldDown ) { - return mMouseDownTimer.getElapsedTimeF32(); + return getHeldDownTime(); } else { @@ -244,13 +245,13 @@ LLXMLNodePtr LLJoystick::getXML(bool save_children) const { LLXMLNodePtr node = LLUICtrl::getXML(); - node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(mHAlign)); + node->createChild("halign", TRUE)->setStringValue(LLFontGL::nameFromHAlign(getHAlign())); node->createChild("quadrant", TRUE)->setStringValue(nameFromQuadrant(mInitialQuadrant)); - addImageAttributeToXML(node,mImageUnselectedName,mImageUnselectedID,"image_unselected"); - addImageAttributeToXML(node,mImageSelectedName,mImageSelectedID,"image_selected"); + addImageAttributeToXML(node,getImageUnselectedName(),getImageUnselectedID(),"image_unselected"); + addImageAttributeToXML(node,getImageSelectedName(),getImageSelectedID(),"image_selected"); - node->createChild("scale_image", TRUE)->setBoolValue(mScaleImage); + node->createChild("scale_image", TRUE)->setBoolValue(getScaleImage()); return node; } @@ -504,8 +505,8 @@ BOOL LLJoystickCameraRotate::handleMouseDown(S32 x, S32 y, MASK mask) updateSlop(); // Set initial offset based on initial click location - S32 horiz_center = mRect.getWidth() / 2; - S32 vert_center = mRect.getHeight() / 2; + S32 horiz_center = getRect().getWidth() / 2; + S32 vert_center = getRect().getHeight() / 2; S32 dx = x - horiz_center; S32 dy = y - vert_center; @@ -607,26 +608,26 @@ void LLJoystickCameraRotate::draw() { LLGLSUIDefault gls_ui; - mImageUnselected->draw( 0, 0 ); + getImageUnselected()->draw( 0, 0 ); if( mInTop ) { - drawRotatedImage( mImageSelected->getImage(), 0 ); + drawRotatedImage( getImageSelected()->getImage(), 0 ); } if( mInRight ) { - drawRotatedImage( mImageSelected->getImage(), 1 ); + drawRotatedImage( getImageSelected()->getImage(), 1 ); } if( mInBottom ) { - drawRotatedImage( mImageSelected->getImage(), 2 ); + drawRotatedImage( getImageSelected()->getImage(), 2 ); } if( mInLeft ) { - drawRotatedImage( mImageSelected->getImage(), 3 ); + drawRotatedImage( getImageSelected()->getImage(), 3 ); } if (sDebugRects) @@ -637,7 +638,7 @@ void LLJoystickCameraRotate::draw() } // Draws image rotated by multiples of 90 degrees -void LLJoystickCameraRotate::drawRotatedImage( LLImageGL* image, S32 rotations ) +void LLJoystickCameraRotate::drawRotatedImage( const LLImageGL* image, S32 rotations ) { S32 width = image->getWidth(); S32 height = image->getHeight(); @@ -652,23 +653,23 @@ void LLJoystickCameraRotate::drawRotatedImage( LLImageGL* image, S32 rotations ) image->bind(); - glColor4fv(UI_VERTEX_COLOR.mV); + gGL.color4fv(UI_VERTEX_COLOR.mV); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { - glTexCoord2fv( uv[ (rotations + 0) % 4]); - glVertex2i(width, height ); + gGL.texCoord2fv( uv[ (rotations + 0) % 4]); + gGL.vertex2i(width, height ); - glTexCoord2fv( uv[ (rotations + 1) % 4]); - glVertex2i(0, height ); + gGL.texCoord2fv( uv[ (rotations + 1) % 4]); + gGL.vertex2i(0, height ); - glTexCoord2fv( uv[ (rotations + 2) % 4]); - glVertex2i(0, 0); + gGL.texCoord2fv( uv[ (rotations + 2) % 4]); + gGL.vertex2i(0, 0); - glTexCoord2fv( uv[ (rotations + 3) % 4]); - glVertex2i(width, 0); + gGL.texCoord2fv( uv[ (rotations + 3) % 4]); + gGL.vertex2i(width, 0); } - glEnd(); + gGL.end(); } @@ -732,7 +733,7 @@ BOOL LLJoystickCameraZoom::handleMouseDown(S32 x, S32 y, MASK mask) if( handled ) { - if (mFirstMouse.mY > mRect.getHeight() / 2) + if (mFirstMouse.mY > getRect().getHeight() / 2) { mInitialQuadrant = JQ_UP; } @@ -801,7 +802,7 @@ void LLJoystickCameraZoom::draw() } else { - mImageUnselected->draw( 0, 0 ); + getImageUnselected()->draw( 0, 0 ); } if (sDebugRects) @@ -813,11 +814,11 @@ void LLJoystickCameraZoom::draw() void LLJoystickCameraZoom::updateSlop() { - mVertSlopNear = mRect.getHeight() / 4; - mVertSlopFar = mRect.getHeight() / 2; + mVertSlopNear = getRect().getHeight() / 4; + mVertSlopFar = getRect().getHeight() / 2; - mHorizSlopNear = mRect.getWidth() / 4; - mHorizSlopFar = mRect.getWidth() / 2; + mHorizSlopNear = getRect().getWidth() / 4; + mHorizSlopFar = getRect().getWidth() / 2; // Compute initial mouse offset based on initial quadrant. // Place the mouse evenly between the near and far zones. diff --git a/linden/indra/newview/lljoystickbutton.h b/linden/indra/newview/lljoystickbutton.h index adba271..ed0d1dd 100644 --- a/linden/indra/newview/lljoystickbutton.h +++ b/linden/indra/newview/lljoystickbutton.h @@ -140,7 +140,7 @@ public: protected: F32 getOrbitRate(); virtual void updateSlop(); - void drawRotatedImage( LLImageGL* image, S32 rotations ); + void drawRotatedImage( const LLImageGL* image, S32 rotations ); protected: BOOL mInLeft; diff --git a/linden/indra/newview/lllcd.cpp b/linden/indra/newview/lllcd.cpp index 3d26824..f9660b5 100644 --- a/linden/indra/newview/lllcd.cpp +++ b/linden/indra/newview/lllcd.cpp @@ -200,12 +200,12 @@ LLDebugConsolePageGroup::LLDebugConsolePageGroup(CEzLcd *LCD, int type, HICON SL void LLDebugPageGroup::UpdateDetails() { mLCD->ModifyControlsOnPage(mPageArray[0].mPageIndex); - LLString ping = llformat("1000"); - LLString packetsIn = llformat("0"); - LLString packetsOut = llformat("0"); - LLString packetLoss = llformat("0"); - LLString fps = llformat("0"); - LLString simfps = llformat("0"); + LLString ping = "1000"; + LLString packetsIn = "0"; + LLString packetsOut = "0"; + LLString packetLoss = "0"; + LLString fps = "0"; + LLString simfps = "0"; // region name if (gStatusBar) { @@ -257,11 +257,11 @@ LLDebugPageGroup::LLDebugPageGroup(CEzLcd *LCD, int type, HICON SLIcon) // add Title HANDLE title = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_CENTER, 128); mLCD->SetOrigin(title, 32, 0); - mLCD->SetText(title, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("DebugInfo")).c_str())); + mLCD->SetText(title, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("DebugInfo")).c_str())); HANDLE fpsStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 18); mLCD->SetOrigin(fpsStatic, ICON_WIDTH, 11); - mLCD->SetText(fpsStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("FPS")).c_str())); + mLCD->SetText(fpsStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("FPS")).c_str())); HANDLE fps = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 25); mLCD->SetOrigin(fps, ICON_WIDTH+25, 11); @@ -270,7 +270,7 @@ LLDebugPageGroup::LLDebugPageGroup(CEzLcd *LCD, int type, HICON SLIcon) HANDLE simfpsStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 35); mLCD->SetOrigin(simfpsStatic, ICON_WIDTH+37+25, 11); - mLCD->SetText(simfpsStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("SimFPS")).c_str())); + mLCD->SetText(simfpsStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("SimFPS")).c_str())); HANDLE simfps = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 25); mLCD->SetOrigin(simfps, ICON_WIDTH+37+27+37, 11); @@ -279,7 +279,7 @@ LLDebugPageGroup::LLDebugPageGroup(CEzLcd *LCD, int type, HICON SLIcon) HANDLE packetsinStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 25); mLCD->SetOrigin(packetsinStatic, ICON_WIDTH, 22); - mLCD->SetText(packetsinStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Pin")).c_str())); + mLCD->SetText(packetsinStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Pin")).c_str())); HANDLE packetsin = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 25); mLCD->SetOrigin(packetsin, ICON_WIDTH+32, 22); @@ -288,7 +288,7 @@ LLDebugPageGroup::LLDebugPageGroup(CEzLcd *LCD, int type, HICON SLIcon) HANDLE packetsoutStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 30); mLCD->SetOrigin(packetsoutStatic, ICON_WIDTH+37+25, 22); - mLCD->SetText(packetsoutStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Pout")).c_str())); + mLCD->SetText(packetsoutStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Pout")).c_str())); HANDLE packetsout = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 25); mLCD->SetOrigin(packetsout, ICON_WIDTH+37+27+37, 22); @@ -297,7 +297,7 @@ LLDebugPageGroup::LLDebugPageGroup(CEzLcd *LCD, int type, HICON SLIcon) HANDLE packetlossStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 30); mLCD->SetOrigin(packetlossStatic, ICON_WIDTH, 33); - mLCD->SetText(packetlossStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("PLoss")).c_str())); + mLCD->SetText(packetlossStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("PLoss")).c_str())); HANDLE packetloss = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 35); mLCD->SetOrigin(packetloss, ICON_WIDTH+33, 33); @@ -306,7 +306,7 @@ LLDebugPageGroup::LLDebugPageGroup(CEzLcd *LCD, int type, HICON SLIcon) HANDLE pingStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 20); mLCD->SetOrigin(pingStatic, ICON_WIDTH+32+38, 33); - mLCD->SetText(pingStatic,(LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Ping")).c_str())); + mLCD->SetText(pingStatic,(LPCTSTR)(utf8str_to_utf16str(bogus->getString("Ping")).c_str())); HANDLE ping = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 30); mLCD->SetOrigin(ping, ICON_WIDTH+37+27+37, 33); @@ -326,8 +326,8 @@ LLDebugPageGroup::LLDebugPageGroup(CEzLcd *LCD, int type, HICON SLIcon) void LLLindenPageGroup::UpdateDetails() { mLCD->ModifyControlsOnPage(mPageArray[0].mPageIndex); - LLString time = llformat("Unknown"); - LLString balance = llformat("Unknown"); + LLString time = "Unknown"; + LLString balance = "Unknown"; // region name if (gStatusBar) { @@ -363,11 +363,11 @@ LLLindenPageGroup::LLLindenPageGroup(CEzLcd *LCD, int type, HICON SLIcon) // add Title HANDLE title = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_CENTER, 128); mLCD->SetOrigin(title, 32, 0); - mLCD->SetText(title, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("AccountDetails")).c_str())); + mLCD->SetText(title, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("AccountDetails")).c_str())); HANDLE timeStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 30); mLCD->SetOrigin(timeStatic, ICON_WIDTH, 11); - mLCD->SetText(timeStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Time")).c_str())); + mLCD->SetText(timeStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Time")).c_str())); HANDLE time = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 160 - ICON_WIDTH - 32); mLCD->SetOrigin(time, ICON_WIDTH+32, 11); @@ -376,7 +376,7 @@ LLLindenPageGroup::LLLindenPageGroup(CEzLcd *LCD, int type, HICON SLIcon) HANDLE balanceStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 30); mLCD->SetOrigin(balanceStatic, ICON_WIDTH, 22); - mLCD->SetText(balanceStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("LBal")).c_str())); + mLCD->SetText(balanceStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("LBal")).c_str())); HANDLE balance = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 160 - ICON_WIDTH - 35); mLCD->SetOrigin(balance, ICON_WIDTH+35, 22); @@ -395,28 +395,28 @@ LLLindenPageGroup::LLLindenPageGroup(CEzLcd *LCD, int type, HICON SLIcon) void LLRegionPageGroup::UpdateDetails() { - LLString pos = llformat("Unknown"); - LLString parcel = llformat("Unknown"); - LLString region = llformat("Unknown"); - LLString owner = llformat("Unknown"); - LLString forsale = bogus->childGetText("No"); - LLString rtype = llformat("Unknown"); - LLString sqm = llformat("0"); - LLString traffic = llformat("0"); + LLString pos = "Unknown"; + LLString parcel = "Unknown"; + LLString region = "Unknown"; + LLString owner = "Unknown"; + LLString forsale = bogus->getString("No"); + LLString rtype = "Unknown"; + LLString sqm = "0"; + LLString traffic = "0"; // region name if (gStatusBar) { pos = llformat(" %d, %d, %d", gStatusBar->mRegionDetails.mX, gStatusBar->mRegionDetails.mY, gStatusBar->mRegionDetails.mZ); - parcel = llformat("%s", gStatusBar->mRegionDetails.mParcelName); + parcel = gStatusBar->mRegionDetails.mParcelName; region = gStatusBar->mRegionDetails.mRegionName; - rtype = llformat("%s", gStatusBar->mRegionDetails.mAccesString); + rtype = gStatusBar->mRegionDetails.mAccesString; sqm = llformat("%d", gStatusBar->mRegionDetails.mArea); if (gStatusBar->mRegionDetails.mForSale) { - forsale = bogus->childGetText("Yes"); + forsale = bogus->getString("Yes"); } - owner = llformat("%s", gStatusBar->mRegionDetails.mOwner); + owner = gStatusBar->mRegionDetails.mOwner; traffic = llformat("%d", (int)gStatusBar->mRegionDetails.mTraffic); } @@ -466,11 +466,11 @@ LLRegionPageGroup::LLRegionPageGroup(CEzLcd *LCD, int type, HICON SLIcon) // add Title HANDLE title = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_CENTER, 128); mLCD->SetOrigin(title, 32, 0); - mLCD->SetText(title, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("LocationDetails1")).c_str())); + mLCD->SetText(title, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("LocationDetails1")).c_str())); HANDLE regionNameStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 30); mLCD->SetOrigin(regionNameStatic, ICON_WIDTH, 11); - mLCD->SetText(regionNameStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Region")).c_str())); + mLCD->SetText(regionNameStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Region")).c_str())); HANDLE regionName = mLCD->AddText(LG_SCROLLING_TEXT, LG_SMALL, DT_LEFT, 160 - ICON_WIDTH - 30 - 2); mLCD->SetOrigin(regionName, ICON_WIDTH+32, 11); @@ -479,7 +479,7 @@ LLRegionPageGroup::LLRegionPageGroup(CEzLcd *LCD, int type, HICON SLIcon) HANDLE parcelStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 30); mLCD->SetOrigin(parcelStatic, ICON_WIDTH, 22); - mLCD->SetText(parcelStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Parcel")).c_str())); + mLCD->SetText(parcelStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Parcel")).c_str())); HANDLE parcel = mLCD->AddText(LG_SCROLLING_TEXT, LG_SMALL, DT_CENTER, 160 - ICON_WIDTH - 30 - 2); mLCD->SetOrigin(parcel, ICON_WIDTH+32, 22); @@ -488,7 +488,7 @@ LLRegionPageGroup::LLRegionPageGroup(CEzLcd *LCD, int type, HICON SLIcon) HANDLE positionStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 18); mLCD->SetOrigin(positionStatic, 0, 33); - mLCD->SetText(positionStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Parcel")).c_str())); + mLCD->SetText(positionStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Parcel")).c_str())); HANDLE position = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 60); mLCD->SetOrigin(position, 20, 33); @@ -497,7 +497,7 @@ LLRegionPageGroup::LLRegionPageGroup(CEzLcd *LCD, int type, HICON SLIcon) HANDLE sqmStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 18); mLCD->SetOrigin(sqmStatic, 90, 33); - mLCD->SetText(sqmStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Sqm")).c_str())); + mLCD->SetText(sqmStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Sqm")).c_str())); HANDLE sqm = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 40); mLCD->SetOrigin(sqm, 90 + 20, 33); @@ -521,11 +521,11 @@ LLRegionPageGroup::LLRegionPageGroup(CEzLcd *LCD, int type, HICON SLIcon) // add Title title = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_CENTER, 128); mLCD->SetOrigin(title, 32, 0); - mLCD->SetText(title, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("LocationDetails2")).c_str())); + mLCD->SetText(title, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("LocationDetails2")).c_str())); HANDLE ownerStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 30); mLCD->SetOrigin(ownerStatic, ICON_WIDTH, 11); - mLCD->SetText(ownerStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Owner")).c_str())); + mLCD->SetText(ownerStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Owner")).c_str())); HANDLE owner = mLCD->AddText(LG_SCROLLING_TEXT, LG_SMALL, DT_LEFT, 160 - 30 - ICON_WIDTH - 2); mLCD->SetOrigin(owner, ICON_WIDTH+32, 11); @@ -534,7 +534,7 @@ LLRegionPageGroup::LLRegionPageGroup(CEzLcd *LCD, int type, HICON SLIcon) HANDLE typeStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 30); mLCD->SetOrigin(typeStatic, ICON_WIDTH, 22); - mLCD->SetText(typeStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Type")).c_str())); + mLCD->SetText(typeStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Type")).c_str())); HANDLE rtype = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 160 - 30 - ICON_WIDTH - 2); mLCD->SetOrigin(rtype, ICON_WIDTH+32, 22); @@ -543,16 +543,16 @@ LLRegionPageGroup::LLRegionPageGroup(CEzLcd *LCD, int type, HICON SLIcon) HANDLE forsaleStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 40); mLCD->SetOrigin(forsaleStatic, 0, 33); - mLCD->SetText(forsaleStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Forsale")).c_str())); + mLCD->SetText(forsaleStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Forsale")).c_str())); HANDLE forsale = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 30); mLCD->SetOrigin(forsale, 42, 33); - mLCD->SetText(forsale, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("No")).c_str())); + mLCD->SetText(forsale, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("No")).c_str())); newPage2.mDisplayItemArray.push_back(forsale); HANDLE trafficStatic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 50); mLCD->SetOrigin(trafficStatic, 70, 33); - mLCD->SetText(trafficStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Traffic")).c_str())); + mLCD->SetText(trafficStatic, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Traffic")).c_str())); HANDLE traffic = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_LEFT, 30); mLCD->SetOrigin(traffic, 122, 33); @@ -592,9 +592,9 @@ void LLChatPageGroup::InsertText(const LLString &newLine) LLChatPageGroup::LLChatPageGroup(CEzLcd *LCD, int type, HICON SLIcon) :LLLCDPageGroup(LCD, type, SLIcon) { - mLine1 = llformat(""); - mLine2 = llformat(""); - mLine3 = llformat(""); + mLine1 = ""; + mLine2 = ""; + mLine3 = ""; // create a new specific page LLLCDSpecificPage newPage; newPage.mPageIndex = mLCD->AddNewPage() - 1; @@ -609,7 +609,7 @@ LLChatPageGroup::LLChatPageGroup(CEzLcd *LCD, int type, HICON SLIcon) // add Title HANDLE title = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_CENTER, 128); mLCD->SetOrigin(title, 32, 0); - mLCD->SetText(title, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Last3ChatLines")).c_str())); + mLCD->SetText(title, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Last3ChatLines")).c_str())); // add line HANDLE chatLine = mLCD->AddText(LG_SCROLLING_TEXT, LG_SMALL, DT_LEFT, 160 - ICON_WIDTH); @@ -661,9 +661,9 @@ void LLIMPageGroup::InsertText(const LLString &newLine) LLIMPageGroup::LLIMPageGroup(CEzLcd *LCD, int type, HICON SLIcon) :LLLCDPageGroup(LCD, type, SLIcon){ - mLine1 = llformat(""); - mLine2 = llformat(""); - mLine3 = llformat(""); + mLine1 = ""; + mLine2 = ""; + mLine3 = ""; // create a new specific page LLLCDSpecificPage newPage; newPage.mPageIndex = mLCD->AddNewPage() - 1; @@ -678,7 +678,7 @@ LLIMPageGroup::LLIMPageGroup(CEzLcd *LCD, int type, HICON SLIcon) // add Title HANDLE title = mLCD->AddText(LG_STATIC_TEXT, LG_SMALL, DT_CENTER, 128); mLCD->SetOrigin(title, 32, 0); - mLCD->SetText(title, (LPCTSTR)(utf8str_to_utf16str(bogus->childGetText("Last3IMLines")).c_str())); + mLCD->SetText(title, (LPCTSTR)(utf8str_to_utf16str(bogus->getString("Last3IMLines")).c_str())); // add line HANDLE chatLine = mLCD->AddText(LG_SCROLLING_TEXT, LG_SMALL, DT_LEFT, 160 - ICON_WIDTH); @@ -703,4 +703,4 @@ LLIMPageGroup::LLIMPageGroup(CEzLcd *LCD, int type, HICON SLIcon) } #endif //LL_WINDOWS -#endif //LL_LCD_COMPILE \ No newline at end of file +#endif //LL_LCD_COMPILE diff --git a/linden/indra/newview/lllocalanimationobject.cpp b/linden/indra/newview/lllocalanimationobject.cpp deleted file mode 100644 index 117736b..0000000 --- a/linden/indra/newview/lllocalanimationobject.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/** - * @file lllocalanimationobject.cpp - * @brief LLHUDLocalAnimationObject class implementation - * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "lllocalanimationobject.h" -#include "llglheaders.h" -#include "llsphere.h" -#include "llrand.h" -#include "llviewerobject.h" - -const F32 OPACITY = 1.0f; -const int _X_ = 0; -const int _Y_ = 1; -const int _Z_ = 2; -const F32 BODY_RADIUS = 0.2f; -const F32 HEAD_RADIUS = 0.1f; -const F32 ONE_HALF = 0.5f; - -/* -//----------------------------------------------- -// constructor -//----------------------------------------------- -LLHUDLocalAnimationObject::LLHUDLocalAnimationObject() -: LLHUDObject( LL_HUD_LOCAL_ANIMATION_OBJECT )// cal the base class and pass this in, K? -{ - mParentObject = NULL; - - F32 windSensitivity = 0.04f; - - //---------------------------------------------- - // trunk - //---------------------------------------------- - LLFlexibleObjectAttributes trunkAttributes; - trunkAttributes.mAnchorPositionOffset.setVec( 0.0f, 0.0f, -0.2f ); - trunkAttributes.mAnchorDirection.setVec( 0.0f, 0.0f, 1.0f ); - trunkAttributes.mColor = LLColor4( 0.4f, 0.3f, 0.2f, 1.0f ); - trunkAttributes.mAnchorDirection.normVec(); - trunkAttributes.mAnchorRadius = 0.3f; - trunkAttributes.mNumSections = 3; - trunkAttributes.mGravity = 1.2f; - trunkAttributes.mLength = 9.0f; - trunkAttributes.mTension = 10.0f; - trunkAttributes.mEndRadius = 0.2f; - trunkAttributes.mTextureFileName = "JVTestTreeTrunk.tga"; - trunkAttributes.mRenderStyle = "tube"; - - mTrunk.setAttributes( trunkAttributes ); - - - - //--------------------------------------------- - // frond 1 - //--------------------------------------------- - LLFlexibleObjectAttributes frond1Attributes; - - frond1Attributes.mAnchorPositionOffset.setVec( 0.0f, 0.0f, 0.0f ); - frond1Attributes.mAnchorDirection.setVec( 1.0f, 0.0f, 1.0f ); - frond1Attributes.mAnchorDirection.normVec(); - frond1Attributes.mColor = LLColor4( 0.15f, 0.25f, 0.0f, 1.0f ); - frond1Attributes.mAnchorRadius = 0.5f; - frond1Attributes.mTension = 2.0f; - frond1Attributes.mNumSections = 2; - frond1Attributes.mGravity = 2.0f; - frond1Attributes.mLength = 5.0f; - frond1Attributes.mEndRadius = 0.0f; - frond1Attributes.mTextureFileName = "JVTestPalmFrond.tga"; - frond1Attributes.mRenderStyle = "billboard_tube"; - frond1Attributes.mWindSensitivity = windSensitivity; - - mFrond1.setAttributes( frond1Attributes ); - - //--------------------------------------------- - // frond 2 - //--------------------------------------------- - LLFlexibleObjectAttributes frond2Attributes; - - frond2Attributes.mAnchorPositionOffset.setVec( 0.0f, 0.0f, 0.0f ); - frond2Attributes.mAnchorDirection.setVec( 1.0f, 0.7f, 0.7f ); - frond2Attributes.mAnchorDirection.normVec(); - frond2Attributes.mColor = LLColor4( 0.15f, 0.25f, 0.0f, 1.0f ); - frond2Attributes.mAnchorRadius = 0.5f; - frond2Attributes.mTension = 2.0f; - frond2Attributes.mNumSections = 2; - frond2Attributes.mGravity = 2.0f; - frond2Attributes.mLength = 6.0f; - frond2Attributes.mEndRadius = 0.0f; - frond2Attributes.mTextureFileName = "JVTestPalmFrond.tga"; - frond2Attributes.mRenderStyle = "billboard_tube"; - frond2Attributes.mWindSensitivity = windSensitivity; - - mFrond2.setAttributes( frond2Attributes ); - - //--------------------------------------------- - // frond 3 - //--------------------------------------------- - LLFlexibleObjectAttributes frond3Attributes; - - frond3Attributes.mAnchorPositionOffset.setVec( 0.0f, 0.0f, 0.0f ); - frond3Attributes.mAnchorDirection.setVec( 1.0f, 0.7f, -0.7f ); - frond3Attributes.mAnchorDirection.normVec(); - frond3Attributes.mColor = LLColor4( 0.15f, 0.25f, 0.0f, 1.0f ); - frond3Attributes.mAnchorRadius = 0.3f; - frond3Attributes.mTension = 2.0f; - frond3Attributes.mNumSections = 2; - frond3Attributes.mGravity = 2.0f; - frond3Attributes.mLength = 6.0f; - frond3Attributes.mEndRadius = 0.0f; - frond3Attributes.mTextureFileName = "JVTestPalmFrond.tga"; - frond3Attributes.mRenderStyle = "billboard_tube"; - frond3Attributes.mWindSensitivity = windSensitivity; - - mFrond3.setAttributes( frond3Attributes ); - - - //--------------------------------------------- - // frond 4 - //--------------------------------------------- - LLFlexibleObjectAttributes frond4Attributes; - - frond4Attributes.mAnchorPositionOffset.setVec( 0.0f, 0.0f, 0.0f ); - frond4Attributes.mAnchorDirection.setVec( 1.0f, -0.8f, 0.3f ); - frond4Attributes.mAnchorDirection.normVec(); - frond4Attributes.mColor = LLColor4( 0.15f, 0.25f, 0.0f, 1.0f ); - frond4Attributes.mAnchorRadius = 0.5f; - frond4Attributes.mTension = 2.0f; - frond4Attributes.mNumSections = 2; - frond4Attributes.mGravity = 2.0f; - frond4Attributes.mLength = 6.0f; - frond4Attributes.mEndRadius = 0.0f; - frond4Attributes.mTextureFileName = "JVTestPalmFrond.tga"; - frond4Attributes.mRenderStyle = "billboard_tube"; - frond4Attributes.mWindSensitivity = windSensitivity; - - - mFrond4.setAttributes( frond4Attributes ); - - - //--------------------------------------------- - // frond 5 - //--------------------------------------------- - LLFlexibleObjectAttributes frond5Attributes; - - frond5Attributes.mAnchorPositionOffset.setVec( 0.0f, 0.0f, 0.0f ); - frond5Attributes.mAnchorDirection.setVec( 1.0f, -0.8f, -0.3f ); - frond5Attributes.mAnchorDirection.normVec(); - frond5Attributes.mColor = LLColor4( 0.15f, 0.25f, 0.0f, 1.0f ); - frond5Attributes.mAnchorRadius = 0.5f; - frond5Attributes.mTension = 2.0f; - frond5Attributes.mNumSections = 2; - frond5Attributes.mGravity = 2.0f; - frond5Attributes.mLength = 5.0f; - frond5Attributes.mEndRadius = 0.0f; - frond5Attributes.mTextureFileName = "JVTestPalmFrond.tga"; - frond5Attributes.mRenderStyle = "billboard_tube"; - frond5Attributes.mWindSensitivity = windSensitivity; - - mFrond5.setAttributes( frond5Attributes ); - -}//------------------------------------------------------------------------------ - - - -//--------------------------------------------------------------------------------- -void LLHUDLocalAnimationObject::update() -{ - if ( ! mParentObject ) - { - return; - } - - //-------------------------------------------------------------------------------------------------- - // now, setting the trunk position and orientation, and updating it... - //-------------------------------------------------------------------------------------------------- - mTrunk.setParentPositionAndRotationDirectly( mParentObject->getRenderPosition(), mParentObject->getRenderRotation() ); - mTrunk.update(); - - - //-------------------------------------------------------------------------------------------------- - // now, setting the frond positions and orientations, and updating them... - //-------------------------------------------------------------------------------------------------- - mFrond1.setParentPositionAndRotationDirectly( mTrunk.getEndPosition(), mTrunk.getEndRotation() ); - mFrond2.setParentPositionAndRotationDirectly( mTrunk.getEndPosition(), mTrunk.getEndRotation() ); - mFrond3.setParentPositionAndRotationDirectly( mTrunk.getEndPosition(), mTrunk.getEndRotation() ); - mFrond4.setParentPositionAndRotationDirectly( mTrunk.getEndPosition(), mTrunk.getEndRotation() ); - mFrond5.setParentPositionAndRotationDirectly( mTrunk.getEndPosition(), mTrunk.getEndRotation() ); - - mFrond1.update(); - mFrond2.update(); - mFrond3.update(); - mFrond4.update(); - mFrond5.update(); - -}//------------------------------------------------------------------ - - - - - - - -//------------------------------------------------------------------ -void LLHUDLocalAnimationObject::render() -{ - mTrunk.render(); - - mFrond1.render(); - mFrond2.render(); - mFrond3.render(); - mFrond4.render(); - mFrond5.render(); - -}//------------------------------------------------------------------ - - - - - -//------------------------------------------------------------------ -void LLHUDLocalAnimationObject::setAttributes( LLLocalAnimationObjectAttributes a ) -{ - //mAttributes = a; // ???? // how do I do this? - - //mAttributes.mAnchorPositionOffset = a.mAnchorPositionOffset; - //mAttributes.mAnchorDirection = a.mAnchorDirection; - //mAttributes.mAnchorRadius = a.mAnchorRadius; - //mAttributes.mNumSections = a.mNumSections; - //mAttributes.mLength = a.mLength; - //mAttributes.mGravity = a.mGravity; - //mAttributes.mAirFriction = a.mAirFriction; - //mAttributes.mTension = a.mTension; - //mAttributes.mRadiusChange = a.mRadiusChange; - -}//------------------------------------------------------------------ - - - -//------------------------------------------------------------------ -void LLHUDLocalAnimationObject::setParentObject( LLViewerObject * p ) -{ - printf( "Setting parent of localAnimationObject controls %x to object %x \n", this, p ); - mParentObject = p; - -}//------------------------------------------------------------------ - - -//------------------------------------------------------------------ -LLViewerObject * LLHUDLocalAnimationObject::getParentObject() -{ - return mParentObject; - -}//------------------------------------------------------------------ - - - -//------------------------------------------------------------------ -void LLHUDLocalAnimationObject::markAsDead() -{ - mDead = TRUE; - mParentObject = NULL; - -}//------------------------------------------------------------------ - -*/ - - - - - - diff --git a/linden/indra/newview/lllocalanimationobject.h b/linden/indra/newview/lllocalanimationobject.h deleted file mode 100644 index 6bea2bb..0000000 --- a/linden/indra/newview/lllocalanimationobject.h +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file lllocalanimationobject.h - * @brief LLHUDLocalAnimationObject class definition - * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LOCALANIMATIONOBJECT_H -#define LL_LOCALANIMATIONOBJECT_H - -#include "llhudobject.h" -#include "llflexibleobject.h" - -//----------------------------------------------------------------------------------- -// Default setting for the attributes of a localAnimationObjectControls object... -//----------------------------------------------------------------------------------- -//const LLVector3 LOCAL_ANIMATION_OBJECT_DEFAULT_ANCHOR_DIRECTION = LLVector3::z_axis; -//const LLVector3 LOCAL_ANIMATION_OBJECT_DEFAULT_ANCHOR_POSITION_OFFSET = LLVector3::zero; -//const LLColor4 LOCAL_ANIMATION_OBJECT_DEFAULT_COLOR = LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ); -//const F32 LOCAL_ANIMATION_OBJECT_DEFAULT_GRAVITY = 0.3f; -//const F32 LOCAL_ANIMATION_OBJECT_DEFAULT_TENSION = 10.0f; -//const F32 LOCAL_ANIMATION_OBJECT_DEFAULT_AIR_FRICTION = 10.0f; -//const F32 LOCAL_ANIMATION_OBJECT_DEFAULT_LENGTH = 1.0f; -//const int LOCAL_ANIMATION_OBJECT_DEFAULT_NUM_SECTIONS = 4; -//const F32 LOCAL_ANIMATION_OBJECT_DEFAULT_ANCHOR_RADIUS = 0.05f; -//const F32 LOCAL_ANIMATION_OBJECT_DEFAULT_RADIUS_CHANGE = -0.01f; - -class LLViewerObject; -/* - -//------------------------------------------------- -// This structure is also used in the part of the -// code that creates new localAnimationObjectControls objects. -//------------------------------------------------- -struct LLLocalAnimationObjectAttributes -{ - //LLVector3 mAnchorPositionOffset; - //LLVector3 mAnchorDirection; - //LLColor4 mColor; - //F32 mAnchorRadius; - //S32 mNumSections; - //F32 mLength; - //F32 mGravity; - //F32 mAirFriction; - //F32 mTension; - //F32 mRadiusChange; - bool mUsingBodyControls; - bool mUsingHeadControls; - bool mUsingTailControls; - bool mUsingLegControls; - - //------ the constructor for the structure ------------ - LLLocalAnimationObjectAttributes() - { - //mAnchorPositionOffset = LOCAL_ANIMATION_OBJECT_DEFAULT_ANCHOR_DIRECTION; - //mAnchorDirection = LOCAL_ANIMATION_OBJECT_DEFAULT_ANCHOR_POSITION_OFFSET; - //mAnchorRadius = LOCAL_ANIMATION_OBJECT_DEFAULT_ANCHOR_RADIUS; - //mColor = LOCAL_ANIMATION_OBJECT_DEFAULT_COLOR; - //mNumSections = LOCAL_ANIMATION_OBJECT_DEFAULT_NUM_SECTIONS; - //mLength = LOCAL_ANIMATION_OBJECT_DEFAULT_LENGTH; - //mGravity = LOCAL_ANIMATION_OBJECT_DEFAULT_GRAVITY; - //mAirFriction = LOCAL_ANIMATION_OBJECT_DEFAULT_AIR_FRICTION; - //mTension = LOCAL_ANIMATION_OBJECT_DEFAULT_TENSION; - //mRadiusChange = LOCAL_ANIMATION_OBJECT_DEFAULT_RADIUS_CHANGE; - } -};// end of attributes structure - - - -//--------------------------------------------------------- -// The LLHUDLocalAnimationObject class -//--------------------------------------------------------- -class LLHUDLocalAnimationObject : public LLHUDObject -{ - public: - LLHUDLocalAnimationObject(); - void setParentObject( LLViewerObject * ); - void setAttributes( LLLocalAnimationObjectAttributes ); - void markAsDead(); - void update(); - LLViewerObject * getParentObject(); - void render(); - - private: - //-------------------------------------- - // private members - //-------------------------------------- - LLViewerObject* mParentObject; - LLLocalAnimationObjectAttributes mAttributes; - LLHUDFlexibleObject mTrunk; - LLHUDFlexibleObject mFrond1; - LLHUDFlexibleObject mFrond2; - LLHUDFlexibleObject mFrond3; - LLHUDFlexibleObject mFrond4; - LLHUDFlexibleObject mFrond5; - - //-------------------------------------- - // private methods - //-------------------------------------- - void updateVirtualServer(); - - friend class LLHUDObject; - -};// end of class definition -*/ - -#endif // LL_LOCALANIMATIONOBJECT_H diff --git a/linden/indra/newview/llmanip.cpp b/linden/indra/newview/llmanip.cpp index 2cf450d..9d9103f 100644 --- a/linden/indra/newview/llmanip.cpp +++ b/linden/indra/newview/llmanip.cpp @@ -35,8 +35,8 @@ #include "llmath.h" #include "v3math.h" -//#include "llquaternion.h" #include "llgl.h" +#include "llglimmediate.h" #include "llprimitive.h" #include "llview.h" #include "llviewerimagelist.h" @@ -78,11 +78,13 @@ void LLManip::rebuild(LLViewerObject* vobj) { gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME, TRUE); - //gPipeline.markMoved(drawablep, FALSE); - //gPipeline.updateMoveNormalAsync(vobj->mDrawable); - drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED drawablep->updateMove(); + LLSpatialGroup* group = drawablep->getSpatialGroup(); + if (group) + { + group->dirtyGeom(); + } } } @@ -388,29 +390,29 @@ void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z) if (draw_x) { - glColor4f(1.f, 0.f, 0.f, LINE_ALPHA); - glBegin(GL_LINES); - glVertex3f( -region_size, 0.f, 0.f ); - glVertex3f( region_size, 0.f, 0.f ); - glEnd(); + gGL.color4f(1.f, 0.f, 0.f, LINE_ALPHA); + gGL.begin(GL_LINES); + gGL.vertex3f( -region_size, 0.f, 0.f ); + gGL.vertex3f( region_size, 0.f, 0.f ); + gGL.end(); } if (draw_y) { - glColor4f(0.f, 1.f, 0.f, LINE_ALPHA); - glBegin(GL_LINES); - glVertex3f( 0.f, -region_size, 0.f ); - glVertex3f( 0.f, region_size, 0.f ); - glEnd(); + gGL.color4f(0.f, 1.f, 0.f, LINE_ALPHA); + gGL.begin(GL_LINES); + gGL.vertex3f( 0.f, -region_size, 0.f ); + gGL.vertex3f( 0.f, region_size, 0.f ); + gGL.end(); } if (draw_z) { - glColor4f(0.f, 0.f, 1.f, LINE_ALPHA); - glBegin(GL_LINES); - glVertex3f( 0.f, 0.f, -region_size ); - glVertex3f( 0.f, 0.f, region_size ); - glEnd(); + gGL.color4f(0.f, 0.f, 1.f, LINE_ALPHA); + gGL.begin(GL_LINES); + gGL.vertex3f( 0.f, 0.f, -region_size ); + gGL.vertex3f( 0.f, 0.f, region_size ); + gGL.end(); } LLUI::setLineWidth(1.0f); } @@ -435,7 +437,7 @@ void LLManip::renderXYZ(const LLVector3 &vec) gViewerWindow->setup2DRender(); const LLVector2& display_scale = gViewerWindow->getDisplayScale(); glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f); - glColor4f(0.f, 0.f, 0.f, 0.7f); + gGL.color4f(0.f, 0.f, 0.f, 0.7f); gl_draw_scaled_image_with_border(window_center_x - 115, window_center_y + vertical_offset - PAD, @@ -453,7 +455,6 @@ void LLManip::renderXYZ(const LLVector3 &vec) { LLLocale locale(LLLocale::USER_LOCALE); LLGLDepthTest gls_depth(GL_FALSE); - LLGLEnable tex(GL_TEXTURE_2D); // render drop shadowed text snprintf(feedback_string, sizeof(feedback_string), "X: %.3f", vec.mV[VX]); /* Flawfinder: ignore */ hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *gResMgr->getRes( LLFONT_SANSSERIF ), LLFontGL::NORMAL, -102.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE); @@ -497,7 +498,6 @@ void LLManip::renderTickText(const LLVector3& pos, const char* text, const LLCol // render shadow first LLColor4 shadow_color = LLColor4::black; - LLGLEnable tex(GL_TEXTURE_2D); shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f; gViewerWindow->setupViewport(1, -1); hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, -0.5f * big_fontp->getWidthF32(text), 3.f, shadow_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD); @@ -557,7 +557,6 @@ void LLManip::renderTickValue(const LLVector3& pos, F32 value, const char* suffi LLColor4 shadow_color = LLColor4::black; shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f; - LLGLEnable tex(GL_TEXTURE_2D); if (fractional_portion != 0) { snprintf(fraction_string, sizeof(fraction_string), "%c%02d%s", gResMgr->getDecimalPoint(), fractional_portion, suffix); /* Flawfinder: ignore */ diff --git a/linden/indra/newview/llmanip.h b/linden/indra/newview/llmanip.h index 2053bc7..ef6630b 100644 --- a/linden/indra/newview/llmanip.h +++ b/linden/indra/newview/llmanip.h @@ -135,7 +135,7 @@ public: EManipPart getHighlightedPart() { return mHighlightedPart; } - LLHandle getSelection(); + LLSafeHandle getSelection(); protected: LLVector3 getSavedPivotPoint() const; @@ -153,7 +153,7 @@ protected: protected: LLFrameTimer mHelpTextTimer; BOOL mInSnapRegime; - LLHandle mObjectSelection; + LLSafeHandle mObjectSelection; EManipPart mHighlightedPart; static F32 sHelpTextVisibleTime; diff --git a/linden/indra/newview/llmaniprotate.cpp b/linden/indra/newview/llmaniprotate.cpp index 66f21d7..bd951a6 100644 --- a/linden/indra/newview/llmaniprotate.cpp +++ b/linden/indra/newview/llmaniprotate.cpp @@ -36,6 +36,7 @@ // library includes #include "llmath.h" #include "llgl.h" +#include "llglimmediate.h" #include "v4color.h" #include "llprimitive.h" #include "llview.h" @@ -205,7 +206,7 @@ void LLManipRotate::render() if (mManipPart == LL_NO_PART) { - glColor4f( 0.7f, 0.7f, 0.7f, 0.3f ); + gGL.color4f( 0.7f, 0.7f, 0.7f, 0.3f ); gl_circle_2d( 0, 0, mRadiusMeters, CIRCLE_STEPS, TRUE ); } @@ -839,7 +840,7 @@ void LLManipRotate::renderSnapGuides() LLColor4 line_color = setupSnapGuideRenderPass(pass); - glColor4fv(line_color.mV); + gGL.color4fv(line_color.mV); if (mCamEdgeOn) { @@ -868,7 +869,7 @@ void LLManipRotate::renderSnapGuides() LLVector3 outer_point; LLVector3 text_point; LLQuaternion rot(deg * DEG_TO_RAD, constraint_axis); - glBegin(GL_LINES); + gGL.begin(GL_LINES); { inner_point = (projected_snap_axis * mRadiusMeters * SNAP_GUIDE_INNER_RADIUS * rot) + center; F32 tick_length = 0.f; @@ -921,10 +922,10 @@ void LLManipRotate::renderSnapGuides() text_point = outer_point + (projected_snap_axis * mRadiusMeters * 0.1f) * rot; - glVertex3fv(inner_point.mV); - glVertex3fv(outer_point.mV); + gGL.vertex3fv(inner_point.mV); + gGL.vertex3fv(outer_point.mV); } - glEnd(); + gGL.end(); //RN: text rendering does own shadow pass, so only render once if (pass == 1 && render_text && i % 16 == 0) @@ -1029,7 +1030,7 @@ void LLManipRotate::renderSnapGuides() } } } - glColor4fv(line_color.mV); + gGL.color4fv(line_color.mV); } // now render projected object axis @@ -1046,15 +1047,15 @@ void LLManipRotate::renderSnapGuides() object_axis = object_axis * SNAP_GUIDE_INNER_RADIUS * mRadiusMeters + center; LLVector3 line_start = center; - glBegin(GL_LINES); + gGL.begin(GL_LINES); { - glVertex3fv(line_start.mV); - glVertex3fv(object_axis.mV); + gGL.vertex3fv(line_start.mV); + gGL.vertex3fv(object_axis.mV); } - glEnd(); + gGL.end(); // draw snap guide arrow - glBegin(GL_TRIANGLES); + gGL.begin(GL_TRIANGLES); { LLVector3 arrow_dir; LLVector3 arrow_span = (object_axis - line_start) % getConstraintAxis(); @@ -1066,23 +1067,23 @@ void LLManipRotate::renderSnapGuides() { arrow_dir *= -1.f; } - glVertex3fv((object_axis + arrow_dir * mRadiusMeters * 0.1f).mV); - glVertex3fv((object_axis + arrow_span * mRadiusMeters * 0.1f).mV); - glVertex3fv((object_axis - arrow_span * mRadiusMeters * 0.1f).mV); + gGL.vertex3fv((object_axis + arrow_dir * mRadiusMeters * 0.1f).mV); + gGL.vertex3fv((object_axis + arrow_span * mRadiusMeters * 0.1f).mV); + gGL.vertex3fv((object_axis - arrow_span * mRadiusMeters * 0.1f).mV); } - glEnd(); + gGL.end(); { LLGLDepthTest gls_depth(GL_TRUE); - glBegin(GL_LINES); + gGL.begin(GL_LINES); { - glVertex3fv(line_start.mV); - glVertex3fv(object_axis.mV); + gGL.vertex3fv(line_start.mV); + gGL.vertex3fv(object_axis.mV); } - glEnd(); + gGL.end(); // draw snap guide arrow - glBegin(GL_TRIANGLES); + gGL.begin(GL_TRIANGLES); { LLVector3 arrow_dir; LLVector3 arrow_span = (object_axis - line_start) % getConstraintAxis(); @@ -1095,11 +1096,11 @@ void LLManipRotate::renderSnapGuides() arrow_dir *= -1.f; } - glVertex3fv((object_axis + arrow_dir * mRadiusMeters * 0.1f).mV); - glVertex3fv((object_axis + arrow_span * mRadiusMeters * 0.1f).mV); - glVertex3fv((object_axis - arrow_span * mRadiusMeters * 0.1f).mV); + gGL.vertex3fv((object_axis + arrow_dir * mRadiusMeters * 0.1f).mV); + gGL.vertex3fv((object_axis + arrow_span * mRadiusMeters * 0.1f).mV); + gGL.vertex3fv((object_axis - arrow_span * mRadiusMeters * 0.1f).mV); } - glEnd(); + gGL.end(); } } } diff --git a/linden/indra/newview/llmanipscale.cpp b/linden/indra/newview/llmanipscale.cpp index 74137f8..883c3d7 100644 --- a/linden/indra/newview/llmanipscale.cpp +++ b/linden/indra/newview/llmanipscale.cpp @@ -38,6 +38,7 @@ #include "v3math.h" #include "llquaternion.h" #include "llgl.h" +#include "llglimmediate.h" #include "v4color.h" #include "llprimitive.h" @@ -47,7 +48,6 @@ #include "llbox.h" #include "llviewercontrol.h" #include "llcriticaldamp.h" -#include "llcylinder.h" #include "lldrawable.h" #include "llfloatertools.h" #include "llglheaders.h" @@ -145,15 +145,15 @@ inline void LLManipScale::conditionalHighlight( U32 part, const LLColor4* highli mScaledBoxHandleSize = mBoxHandleSize * manipulator_scale; if (mManipPart != (S32)LL_NO_PART && mManipPart != (S32)part) { - glColor4fv( invisible.mV ); + gGL.color4fv( invisible.mV ); } else if( mHighlightedPart == (S32)part ) { - glColor4fv( highlight ? highlight->mV : default_highlight.mV ); + gGL.color4fv( highlight ? highlight->mV : default_highlight.mV ); } else { - glColor4fv( normal ? normal->mV : default_normal.mV ); + gGL.color4fv( normal ? normal->mV : default_normal.mV ); } } @@ -173,11 +173,6 @@ void LLManipScale::handleDeselect() LLManip::handleDeselect(); } -BOOL sort_manip_by_z(LLManipScale::ManipulatorHandle *new_manip, LLManipScale::ManipulatorHandle *test_manip) -{ - return ((new_manip->mType < test_manip->mType) || (new_manip->mPosition.mV[VZ] < test_manip->mPosition.mV[VZ])); -} - LLManipScale::LLManipScale( LLToolComposite* composite ) : LLManip( "Scale", composite ), @@ -194,7 +189,6 @@ LLManipScale::LLManipScale( LLToolComposite* composite ) mSnapGuideLength(0.f), mScaleSnapValue(0.f) { - mProjectedManipulators.setInsertBefore(sort_manip_by_z); mManipulatorScales = new F32[NUM_MANIPULATORS]; for (S32 i = 0; i < NUM_MANIPULATORS; i++) { @@ -204,7 +198,8 @@ LLManipScale::LLManipScale( LLToolComposite* composite ) LLManipScale::~LLManipScale() { - delete []mManipulatorScales; + for_each(mProjectedManipulators.begin(), mProjectedManipulators.end(), DeletePointer()); + delete[] mManipulatorScales; } void LLManipScale::render() @@ -471,8 +466,6 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) LLVector3 max = bbox.getMaxLocal(); LLVector3 ctr = bbox.getCenterLocal(); - mProjectedManipulators.deleteAllData(); - S32 numManips = 0; // corners mManipulatorVertices[numManips++] = LLVector4(min.mV[VX], min.mV[VY], min.mV[VZ], 1.f); @@ -496,6 +489,9 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) mManipulatorVertices[numManips++] = LLVector4(ctr.mV[VX], ctr.mV[VY], min.mV[VZ], 1.f); } + for_each(mProjectedManipulators.begin(), mProjectedManipulators.end(), DeletePointer()); + mProjectedManipulators.clear(); + for (S32 i = 0; i < numManips; i++) { LLVector4 projectedVertex = mManipulatorVertices[i] * transform; @@ -503,7 +499,7 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) ManipulatorHandle* projManipulator = new ManipulatorHandle(LLVector3(projectedVertex.mV[VX], projectedVertex.mV[VY], projectedVertex.mV[VZ]), MANIPULATOR_IDS[i], (i < 7) ? SCALE_MANIP_CORNER : SCALE_MANIP_FACE); - mProjectedManipulators.addDataSorted(projManipulator); + mProjectedManipulators.insert(projManipulator); } F32 half_width = (F32)gViewerWindow->getWindowWidth() / 2.f; @@ -514,9 +510,10 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) mHighlightedPart = LL_NO_PART; - for (ManipulatorHandle* manipulator = mProjectedManipulators.getFirstData(); - manipulator; - manipulator = mProjectedManipulators.getNextData()) + for (minpulator_list_t::iterator iter = mProjectedManipulators.begin(); + iter != mProjectedManipulators.end(); ++iter) + { + ManipulatorHandle* manipulator = *iter; { manip2d.setVec(manipulator->mPosition.mV[VX] * half_width, manipulator->mPosition.mV[VY] * half_height); @@ -529,6 +526,7 @@ void LLManipScale::highlightManipulators(S32 x, S32 y) break; } } + } } for (S32 i = 0; i < NUM_MANIPULATORS; i++) @@ -600,47 +598,47 @@ void LLManipScale::renderFaces( const LLBBox& bbox ) if (mManipPart == LL_NO_PART) { - glColor4fv( default_normal_color.mV ); + gGL.color4fv( default_normal_color.mV ); LLGLDepthTest gls_depth(GL_FALSE); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { // Face 0 - glVertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]); - glVertex3f(min.mV[VX], min.mV[VY], max.mV[VZ]); - glVertex3f(max.mV[VX], min.mV[VY], max.mV[VZ]); - glVertex3f(max.mV[VX], max.mV[VY], max.mV[VZ]); + gGL.vertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]); + gGL.vertex3f(min.mV[VX], min.mV[VY], max.mV[VZ]); + gGL.vertex3f(max.mV[VX], min.mV[VY], max.mV[VZ]); + gGL.vertex3f(max.mV[VX], max.mV[VY], max.mV[VZ]); // Face 1 - glVertex3f(max.mV[VX], min.mV[VY], max.mV[VZ]); - glVertex3f(max.mV[VX], min.mV[VY], min.mV[VZ]); - glVertex3f(max.mV[VX], max.mV[VY], min.mV[VZ]); - glVertex3f(max.mV[VX], max.mV[VY], max.mV[VZ]); + gGL.vertex3f(max.mV[VX], min.mV[VY], max.mV[VZ]); + gGL.vertex3f(max.mV[VX], min.mV[VY], min.mV[VZ]); + gGL.vertex3f(max.mV[VX], max.mV[VY], min.mV[VZ]); + gGL.vertex3f(max.mV[VX], max.mV[VY], max.mV[VZ]); // Face 2 - glVertex3f(min.mV[VX], max.mV[VY], min.mV[VZ]); - glVertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]); - glVertex3f(max.mV[VX], max.mV[VY], max.mV[VZ]); - glVertex3f(max.mV[VX], max.mV[VY], min.mV[VZ]); + gGL.vertex3f(min.mV[VX], max.mV[VY], min.mV[VZ]); + gGL.vertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]); + gGL.vertex3f(max.mV[VX], max.mV[VY], max.mV[VZ]); + gGL.vertex3f(max.mV[VX], max.mV[VY], min.mV[VZ]); // Face 3 - glVertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]); - glVertex3f(min.mV[VX], max.mV[VY], min.mV[VZ]); - glVertex3f(min.mV[VX], min.mV[VY], min.mV[VZ]); - glVertex3f(min.mV[VX], min.mV[VY], max.mV[VZ]); + gGL.vertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]); + gGL.vertex3f(min.mV[VX], max.mV[VY], min.mV[VZ]); + gGL.vertex3f(min.mV[VX], min.mV[VY], min.mV[VZ]); + gGL.vertex3f(min.mV[VX], min.mV[VY], max.mV[VZ]); // Face 4 - glVertex3f(min.mV[VX], min.mV[VY], max.mV[VZ]); - glVertex3f(min.mV[VX], min.mV[VY], min.mV[VZ]); - glVertex3f(max.mV[VX], min.mV[VY], min.mV[VZ]); - glVertex3f(max.mV[VX], min.mV[VY], max.mV[VZ]); + gGL.vertex3f(min.mV[VX], min.mV[VY], max.mV[VZ]); + gGL.vertex3f(min.mV[VX], min.mV[VY], min.mV[VZ]); + gGL.vertex3f(max.mV[VX], min.mV[VY], min.mV[VZ]); + gGL.vertex3f(max.mV[VX], min.mV[VY], max.mV[VZ]); // Face 5 - glVertex3f(min.mV[VX], min.mV[VY], min.mV[VZ]); - glVertex3f(min.mV[VX], max.mV[VY], min.mV[VZ]); - glVertex3f(max.mV[VX], max.mV[VY], min.mV[VZ]); - glVertex3f(max.mV[VX], min.mV[VY], min.mV[VZ]); + gGL.vertex3f(min.mV[VX], min.mV[VY], min.mV[VZ]); + gGL.vertex3f(min.mV[VX], max.mV[VY], min.mV[VZ]); + gGL.vertex3f(max.mV[VX], max.mV[VY], min.mV[VZ]); + gGL.vertex3f(max.mV[VX], min.mV[VY], min.mV[VZ]); } - glEnd(); + gGL.end(); } // Find nearest vertex @@ -763,7 +761,7 @@ void LLManipScale::renderCorners( const LLBBox& bbox ) void LLManipScale::renderBoxHandle( F32 x, F32 y, F32 z ) { - LLGLDisable gls_tex(GL_TEXTURE_2D); + LLImageGL::unbindTexture(0); LLGLDepthTest gls_depth(GL_FALSE); glPushMatrix(); @@ -1536,29 +1534,29 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) { LLColor4 tick_color = setupSnapGuideRenderPass(pass); - glBegin(GL_LINES); + gGL.begin(GL_LINES); LLVector3 line_mid = mScaleCenter + (mScaleSnapValue * mScaleDir) + (mSnapGuideDir1 * mSnapRegimeOffset); LLVector3 line_start = line_mid - (mScaleDir * (llmin(mScaleSnapValue, mSnapGuideLength * 0.5f))); LLVector3 line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnapValue, mSnapGuideLength * 0.5f)); - glColor4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * 0.1f); - glVertex3fv(line_start.mV); - glColor4fv(tick_color.mV); - glVertex3fv(line_mid.mV); - glVertex3fv(line_mid.mV); - glColor4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * 0.1f); - glVertex3fv(line_end.mV); + gGL.color4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * 0.1f); + gGL.vertex3fv(line_start.mV); + gGL.color4fv(tick_color.mV); + gGL.vertex3fv(line_mid.mV); + gGL.vertex3fv(line_mid.mV); + gGL.color4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * 0.1f); + gGL.vertex3fv(line_end.mV); line_mid = mScaleCenter + (mScaleSnapValue * mScaleDir) + (mSnapGuideDir2 * mSnapRegimeOffset); line_start = line_mid - (mScaleDir * (llmin(mScaleSnapValue, mSnapGuideLength * 0.5f))); line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnapValue, mSnapGuideLength * 0.5f)); - glVertex3fv(line_start.mV); - glColor4fv(tick_color.mV); - glVertex3fv(line_mid.mV); - glVertex3fv(line_mid.mV); - glColor4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * 0.1f); - glVertex3fv(line_end.mV); - glEnd(); + gGL.vertex3fv(line_start.mV); + gGL.color4fv(tick_color.mV); + gGL.vertex3fv(line_mid.mV); + gGL.vertex3fv(line_mid.mV); + gGL.color4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * 0.1f); + gGL.vertex3fv(line_end.mV); + gGL.end(); } { @@ -1587,41 +1585,41 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) if (mInSnapRegime) { // draw snap guide line - glBegin(GL_LINES); + gGL.begin(GL_LINES); LLVector3 snap_line_center = mScaleCenter + (mScaleSnapValue * mScaleDir); LLVector3 snap_line_start = snap_line_center + (mSnapGuideDir1 * mSnapRegimeOffset); LLVector3 snap_line_end = snap_line_center + (mSnapGuideDir2 * mSnapRegimeOffset); - glColor4f(1.f, 1.f, 1.f, grid_alpha); - glVertex3fv(snap_line_start.mV); - glVertex3fv(snap_line_center.mV); - glVertex3fv(snap_line_center.mV); - glVertex3fv(snap_line_end.mV); - glEnd(); + gGL.color4f(1.f, 1.f, 1.f, grid_alpha); + gGL.vertex3fv(snap_line_start.mV); + gGL.vertex3fv(snap_line_center.mV); + gGL.vertex3fv(snap_line_center.mV); + gGL.vertex3fv(snap_line_end.mV); + gGL.end(); // draw snap guide arrow - glBegin(GL_TRIANGLES); + gGL.begin(GL_TRIANGLES); { //gGLSNoCullFaces.set(); - glColor4f(1.f, 1.f, 1.f, grid_alpha); + gGL.color4f(1.f, 1.f, 1.f, grid_alpha); LLVector3 arrow_dir; LLVector3 arrow_span = mScaleDir; arrow_dir = snap_line_start - snap_line_center; arrow_dir.normVec(); - glVertex3fv((snap_line_start + arrow_dir * mBoxHandleSize).mV); - glVertex3fv((snap_line_start + arrow_span * mBoxHandleSize).mV); - glVertex3fv((snap_line_start - arrow_span * mBoxHandleSize).mV); + gGL.vertex3fv((snap_line_start + arrow_dir * mBoxHandleSize).mV); + gGL.vertex3fv((snap_line_start + arrow_span * mBoxHandleSize).mV); + gGL.vertex3fv((snap_line_start - arrow_span * mBoxHandleSize).mV); arrow_dir = snap_line_end - snap_line_center; arrow_dir.normVec(); - glVertex3fv((snap_line_end + arrow_dir * mBoxHandleSize).mV); - glVertex3fv((snap_line_end + arrow_span * mBoxHandleSize).mV); - glVertex3fv((snap_line_end - arrow_span * mBoxHandleSize).mV); + gGL.vertex3fv((snap_line_end + arrow_dir * mBoxHandleSize).mV); + gGL.vertex3fv((snap_line_end + arrow_span * mBoxHandleSize).mV); + gGL.vertex3fv((snap_line_end - arrow_span * mBoxHandleSize).mV); } - glEnd(); + gGL.end(); } LLVector2 screen_translate_axis(llabs(mScaleDir * gCamera->getLeftAxis()), llabs(mScaleDir * gCamera->getUpAxis())); @@ -1636,7 +1634,7 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) start_tick = -(llmin(ticks_from_scale_center_1, num_ticks_per_side1)); stop_tick = llmin(max_ticks1, num_ticks_per_side1); - glBegin(GL_LINES); + gGL.begin(GL_LINES); // draw first row of ticks for (S32 i = start_tick; i <= stop_tick; i++) { @@ -1660,16 +1658,17 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) tick_scale *= 0.7f; } - glColor4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * alpha); + gGL.color4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * alpha); LLVector3 tick_start = tick_pos + (mSnapGuideDir1 * mSnapRegimeOffset); LLVector3 tick_end = tick_start + (mSnapGuideDir1 * mSnapRegimeOffset * tick_scale); - glVertex3fv(tick_start.mV); - glVertex3fv(tick_end.mV); + gGL.vertex3fv(tick_start.mV); + gGL.vertex3fv(tick_end.mV); } // draw opposite row of ticks start_tick = -(llmin(ticks_from_scale_center_2, num_ticks_per_side2)); stop_tick = llmin(max_ticks2, num_ticks_per_side2); + for (S32 i = start_tick; i <= stop_tick; i++) { F32 alpha = (1.f - (1.f * ((F32)llabs(i) / (F32)num_ticks_per_side2))); @@ -1692,13 +1691,13 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox) tick_scale *= 0.7f; } - glColor4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * alpha); + gGL.color4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * alpha); LLVector3 tick_start = tick_pos + (mSnapGuideDir2 * mSnapRegimeOffset); LLVector3 tick_end = tick_start + (mSnapGuideDir2 * mSnapRegimeOffset * tick_scale); - glVertex3fv(tick_start.mV); - glVertex3fv(tick_end.mV); + gGL.vertex3fv(tick_start.mV); + gGL.vertex3fv(tick_end.mV); } - glEnd(); + gGL.end(); } // render tick labels diff --git a/linden/indra/newview/llmanipscale.h b/linden/indra/newview/llmanipscale.h index ebc8eda..f3d0996 100644 --- a/linden/indra/newview/llmanipscale.h +++ b/linden/indra/newview/llmanipscale.h @@ -124,6 +124,20 @@ private: void updateSnapGuides(const LLBBox& bbox); private: + struct compare_manipulators + { + bool operator() (const ManipulatorHandle* const a, const ManipulatorHandle* const b) const + { + if (a->mType != b->mType) + return a->mType < b->mType; + else if (a->mPosition.mV[VZ] != b->mPosition.mV[VZ]) + return a->mPosition.mV[VZ] < b->mPosition.mV[VZ]; + else + return a->mManipID < b->mManipID; + } + }; + + F32 mBoxHandleSize; // The size of the handles at the corners of the bounding box F32 mScaledBoxHandleSize; // handle size after scaling for selection feedback EManipPart mManipPart; @@ -135,7 +149,8 @@ private: S32 mLastMouseY; BOOL mSendUpdateOnMouseUp; U32 mLastUpdateFlags; - LLLinkedList mProjectedManipulators; + typedef std::set minpulator_list_t; + minpulator_list_t mProjectedManipulators; LLVector4 mManipulatorVertices[14]; F32 mScaleSnapUnit1; // size of snap multiples for axis 1 F32 mScaleSnapUnit2; // size of snap multiples for axis 2 diff --git a/linden/indra/newview/llmaniptranslate.cpp b/linden/indra/newview/llmaniptranslate.cpp index 2642f95..c1457b3 100644 --- a/linden/indra/newview/llmaniptranslate.cpp +++ b/linden/indra/newview/llmaniptranslate.cpp @@ -38,6 +38,7 @@ #include "llmaniptranslate.h" #include "llgl.h" +#include "llglimmediate.h" #include "llagent.h" #include "llbbox.h" @@ -99,11 +100,6 @@ const U32 ARROW_TO_AXIS[4] = VZ }; -BOOL sort_manip_by_end_z(LLManipTranslate::ManipulatorHandle *new_manip, LLManipTranslate::ManipulatorHandle *test_manip) -{ - return (new_manip->mEndPosition.mV[VZ] < test_manip->mEndPosition.mV[VZ]); -} - LLManipTranslate::LLManipTranslate( LLToolComposite* composite ) : LLManip( "Move", composite ), mLastHoverMouseX(-1), @@ -124,8 +120,6 @@ LLManipTranslate::LLManipTranslate( LLToolComposite* composite ) mPlaneScales(1.f, 1.f, 1.f), mPlaneManipPositions(1.f, 1.f, 1.f, 1.f) { - mProjectedManipulators.setInsertBefore(sort_manip_by_end_z); - if (sGridTex == 0) { restoreGL(); @@ -140,7 +134,6 @@ void LLManipTranslate::restoreGL() U32 mip = 0; GLuint* d = new GLuint[rez*rez]; - LLGLEnable tex2d(GL_TEXTURE_2D); glGenTextures(1, &sGridTex); glBindTexture(GL_TEXTURE_2D, sGridTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); @@ -253,7 +246,7 @@ void LLManipTranslate::restoreGL() LLManipTranslate::~LLManipTranslate() { - mProjectedManipulators.deleteAllData(); + for_each(mProjectedManipulators.begin(), mProjectedManipulators.end(), DeletePointer()); } @@ -841,8 +834,6 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) transform *= projMatrix; } - mProjectedManipulators.deleteAllData(); - S32 numManips = 0; // edges @@ -898,6 +889,9 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) planar_manip_xy_visible = TRUE; } + for_each(mProjectedManipulators.begin(), mProjectedManipulators.end(), DeletePointer()); + mProjectedManipulators.clear(); + for (S32 i = 0; i < num_arrow_manips; i+= 2) { LLVector4 projected_start = mManipulatorVertices[i] * transform; @@ -911,7 +905,7 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]), MANIPULATOR_IDS[i / 2], 10.f); // 10 pixel hotspot for arrows - mProjectedManipulators.addDataSorted(projManipulator); + mProjectedManipulators.insert(projManipulator); } if (planar_manip_yz_visible) @@ -928,7 +922,7 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]), MANIPULATOR_IDS[i / 2], 20.f); // 20 pixels for planar manipulators - mProjectedManipulators.addDataSorted(projManipulator); + mProjectedManipulators.insert(projManipulator); } if (planar_manip_xz_visible) @@ -945,7 +939,7 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]), MANIPULATOR_IDS[i / 2], 20.f); // 20 pixels for planar manipulators - mProjectedManipulators.addDataSorted(projManipulator); + mProjectedManipulators.insert(projManipulator); } if (planar_manip_xy_visible) @@ -962,7 +956,7 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) LLVector3(projected_end.mV[VX], projected_end.mV[VY], projected_end.mV[VZ]), MANIPULATOR_IDS[i / 2], 20.f); // 20 pixels for planar manipulators - mProjectedManipulators.addDataSorted(projManipulator); + mProjectedManipulators.insert(projManipulator); } LLVector2 manip_start_2d; @@ -973,9 +967,10 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) LLVector2 mousePos((F32)x - half_width, (F32)y - half_height); LLVector2 mouse_delta; - for (ManipulatorHandle* manipulator = mProjectedManipulators.getFirstData(); - manipulator; - manipulator = mProjectedManipulators.getNextData()) + for (minpulator_list_t::iterator iter = mProjectedManipulators.begin(); + iter != mProjectedManipulators.end(); ++iter) + { + ManipulatorHandle* manipulator = *iter; { manip_start_2d.setVec(manipulator->mStartPosition.mV[VX] * half_width, manipulator->mStartPosition.mV[VY] * half_height); manip_end_2d.setVec(manipulator->mEndPosition.mV[VX] * half_width, manipulator->mEndPosition.mV[VY] * half_height); @@ -996,6 +991,7 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y) break; } } + } } F32 LLManipTranslate::getMinGridScale() @@ -1057,7 +1053,7 @@ BOOL LLManipTranslate::handleMouseUp(S32 x, S32 y, MASK mask) void LLManipTranslate::render() { glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gGL.pushMatrix(); if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { F32 zoom = gAgent.getAvatarObject()->mHUDCurZoom; @@ -1071,7 +1067,7 @@ void LLManipTranslate::render() renderTranslationHandles(); renderSnapGuides(); } - glPopMatrix(); + gGL.popMatrix(); renderText(); } @@ -1257,31 +1253,31 @@ void LLManipTranslate::renderSnapGuides() { LLColor4 line_color = setupSnapGuideRenderPass(pass); - glBegin(GL_LINES); + gGL.begin(GL_LINES); { LLVector3 line_start = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) + (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit)); LLVector3 line_end = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) - (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit)); LLVector3 line_mid = (line_start + line_end) * 0.5f; - glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); - glVertex3fv(line_start.mV); - glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); - glVertex3fv(line_mid.mV); - glVertex3fv(line_mid.mV); - glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); - glVertex3fv(line_end.mV); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); + gGL.vertex3fv(line_start.mV); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); + gGL.vertex3fv(line_mid.mV); + gGL.vertex3fv(line_mid.mV); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); + gGL.vertex3fv(line_end.mV); line_start.setVec(selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) + (translate_axis * guide_size_meters * 0.5f)); line_end.setVec(selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) - (translate_axis * guide_size_meters * 0.5f)); line_mid = (line_start + line_end) * 0.5f; - glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); - glVertex3fv(line_start.mV); - glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); - glVertex3fv(line_mid.mV); - glVertex3fv(line_mid.mV); - glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); - glVertex3fv(line_end.mV); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); + gGL.vertex3fv(line_start.mV); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); + gGL.vertex3fv(line_mid.mV); + gGL.vertex3fv(line_mid.mV); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW] * 0.2f); + gGL.vertex3fv(line_end.mV); for (S32 i = -num_ticks_per_side; i <= num_ticks_per_side; i++) { @@ -1314,53 +1310,53 @@ void LLManipTranslate::renderSnapGuides() tick_end = tick_start + (mSnapOffsetAxis * mSnapOffsetMeters * tick_scale); - glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); - glVertex3fv(tick_start.mV); - glVertex3fv(tick_end.mV); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); + gGL.vertex3fv(tick_start.mV); + gGL.vertex3fv(tick_end.mV); tick_start = selection_center + (mSnapOffsetAxis * -mSnapOffsetMeters) + (translate_axis * (getMinGridScale() / (F32)(max_subdivisions) * (F32)i - offset_nearest_grid_unit)); tick_end = tick_start - (mSnapOffsetAxis * mSnapOffsetMeters * tick_scale); - glVertex3fv(tick_start.mV); - glVertex3fv(tick_end.mV); + gGL.vertex3fv(tick_start.mV); + gGL.vertex3fv(tick_end.mV); } } - glEnd(); + gGL.end(); if (mInSnapRegime) { LLVector3 line_start = selection_center - mSnapOffsetAxis * mSnapOffsetMeters; LLVector3 line_end = selection_center + mSnapOffsetAxis * mSnapOffsetMeters; - glBegin(GL_LINES); + gGL.begin(GL_LINES); { - glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); - glVertex3fv(line_start.mV); - glVertex3fv(line_end.mV); + gGL.vertex3fv(line_start.mV); + gGL.vertex3fv(line_end.mV); } - glEnd(); + gGL.end(); // draw snap guide arrow - glBegin(GL_TRIANGLES); + gGL.begin(GL_TRIANGLES); { - glColor4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); + gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]); LLVector3 arrow_dir; LLVector3 arrow_span = translate_axis; arrow_dir = -mSnapOffsetAxis; - glVertex3fv((line_start + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV); - glVertex3fv((line_start + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); - glVertex3fv((line_start - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); + gGL.vertex3fv((line_start + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV); + gGL.vertex3fv((line_start + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); + gGL.vertex3fv((line_start - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); arrow_dir = mSnapOffsetAxis; - glVertex3fv((line_end + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV); - glVertex3fv((line_end + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); - glVertex3fv((line_end - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); + gGL.vertex3fv((line_end + arrow_dir * mConeSize * SNAP_ARROW_SCALE).mV); + gGL.vertex3fv((line_end + arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); + gGL.vertex3fv((line_end - arrow_span * mConeSize * SNAP_ARROW_SCALE).mV); } - glEnd(); + gGL.end(); } } @@ -1444,7 +1440,6 @@ void LLManipTranslate::renderSnapGuides() LLVector3 help_text_pos = selection_center_start + (snap_offset_meters_up * 3.f * mSnapOffsetAxis); const LLFontGL* big_fontp = LLFontGL::sSansSerif; - LLGLSTexture gls_texture; std::string help_text = "Move mouse cursor over ruler to snap"; LLColor4 help_text_color = LLColor4::white; help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f); @@ -1498,19 +1493,20 @@ void LLManipTranslate::renderSnapGuides() break; } + LLImageGL::unbindTexture(0); highlightIntersection(normal, selection_center, grid_rotation, inner_color); - glPushMatrix(); + gGL.pushMatrix(); F32 x,y,z,angle_radians; grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z); - glTranslatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]); + gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]); glRotatef(angle_radians * RAD_TO_DEG, x, y, z); F32 sz = mGridSizeMeters; F32 tiles = sz; glMatrixMode(GL_TEXTURE); - glPushMatrix(); + gGL.pushMatrix(); usc = 1.0f/usc; vsc = 1.0f/vsc; @@ -1524,37 +1520,41 @@ void LLManipTranslate::renderSnapGuides() } glScalef(usc, vsc, 1.0f); - glTranslatef(u, v, 0); + gGL.translatef(u, v, 0); float a = line_alpha; LLColor4 col = gColors.getColor("SilhouetteChildColor"); { //draw grid behind objects - LLGLSTexture tex2d; LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); { - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER); - glBindTexture(GL_TEXTURE_2D, sGridTex); - glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); - renderGrid(u,v,tiles,0.9f, 0.9f, 0.9f,a*0.15f); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - - { - LLGLDisable alpha_test(GL_ALPHA_TEST); - //draw black overlay - glBindTexture(GL_TEXTURE_2D, 0); - renderGrid(u,v,tiles,0.0f, 0.0f, 0.0f,a*0.16f); - - //draw grid top - glBindTexture(GL_TEXTURE_2D, sGridTex); - renderGrid(u,v,tiles,1,1,1,a); - - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + LLGLDisable stencil(GL_STENCIL_TEST); + { + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER); + glBindTexture(GL_TEXTURE_2D, sGridTex); + gGL.flush(); + gGL.blendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); + renderGrid(u,v,tiles,0.9f, 0.9f, 0.9f,a*0.15f); + gGL.flush(); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + { + LLGLDisable alpha_test(GL_ALPHA_TEST); + //draw black overlay + LLImageGL::unbindTexture(0); + renderGrid(u,v,tiles,0.0f, 0.0f, 0.0f,a*0.16f); + + //draw grid top + glBindTexture(GL_TEXTURE_2D, sGridTex); + renderGrid(u,v,tiles,1,1,1,a); + + gGL.popMatrix(); + glMatrixMode(GL_MODELVIEW); + gGL.popMatrix(); + } { LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); @@ -1564,6 +1564,7 @@ void LLManipTranslate::renderSnapGuides() { LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER); LLGLEnable stipple(GL_LINE_STIPPLE); + gGL.flush(); glLineStipple(1, 0x3333); switch (mManipPart) @@ -1580,6 +1581,7 @@ void LLManipTranslate::renderSnapGuides() default: break; } + gGL.flush(); } } } @@ -1592,32 +1594,32 @@ void LLManipTranslate::renderGrid(F32 x, F32 y, F32 size, F32 r, F32 g, F32 b, F for (F32 xx = -size-d; xx < size+d; xx += d) { - glBegin(GL_TRIANGLE_STRIP); + gGL.begin(GL_TRIANGLE_STRIP); for (F32 yy = -size-d; yy < size+d; yy += d) { float dx, dy, da; dx = xx; dy = yy; da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a; - glTexCoord2f(dx, dy); + gGL.texCoord2f(dx, dy); renderGridVert(dx,dy,r,g,b,da); dx = xx+d; dy = yy; da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a; - glTexCoord2f(dx, dy); + gGL.texCoord2f(dx, dy); renderGridVert(dx,dy,r,g,b,da); dx = xx; dy = yy+d; da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a; - glTexCoord2f(dx, dy); + gGL.texCoord2f(dx, dy); renderGridVert(dx,dy,r,g,b,da); dx = xx+d; dy = yy+d; da = sqrtf(llmax(0.0f, 1.0f-sqrtf(dx*dx+dy*dy)/size))*a; - glTexCoord2f(dx, dy); + gGL.texCoord2f(dx, dy); renderGridVert(dx,dy,r,g,b,da); } - glEnd(); + gGL.end(); } @@ -1633,10 +1635,12 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, return; } - U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT }; + U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY }; + U32 num_types = sizeof(types)/sizeof(U32); GLuint stencil_mask = 0xFFFFFFFF; //stencil in volumes + gGL.stop(); { glStencilMask(stencil_mask); glClearStencil(1); @@ -1646,7 +1650,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS); glStencilFunc(GL_ALWAYS, 0, stencil_mask); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - LLGLDisable tex(GL_TEXTURE_2D); + LLImageGL::unbindTexture(0); glColor4f(1,1,1,1); //setup clip plane @@ -1675,14 +1679,14 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, //stencil in volumes glStencilOp(GL_INCR, GL_INCR, GL_INCR); glCullFace(GL_FRONT); - for (U32 i = 0; i < 3; i++) + for (U32 i = 0; i < num_types; i++) { gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); } glStencilOp(GL_DECR, GL_DECR, GL_DECR); glCullFace(GL_BACK); - for (U32 i = 0; i < 3; i++) + for (U32 i = 0; i < num_types; i++) { gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); } @@ -1698,12 +1702,13 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); } + gGL.start(); - glPushMatrix(); + gGL.pushMatrix(); F32 x,y,z,angle_radians; grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z); - glTranslatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]); + gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]); glRotatef(angle_radians * RAD_TO_DEG, x, y, z); F32 sz = mGridSizeMeters; @@ -1711,7 +1716,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, //draw volume/plane intersections { - LLGLDisable tex(GL_TEXTURE_2D); + LLImageGL::unbindTexture(0); LLGLDepthTest depth(GL_FALSE); LLGLEnable stencil(GL_STENCIL_TEST); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); @@ -1719,7 +1724,11 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal, renderGrid(0,0,tiles,inner_color.mV[0], inner_color.mV[1], inner_color.mV[2], 0.25f); } - glPopMatrix(); + glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF); + glStencilMask(0xFFFFFFFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + gGL.popMatrix(); } void LLManipTranslate::renderText() @@ -1830,9 +1839,9 @@ void LLManipTranslate::renderTranslationHandles() mConeSize = mArrowLengthMeters / 4.f; glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gGL.pushMatrix(); { - glTranslatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]); + gGL.translatef(selection_center.mV[VX], selection_center.mV[VY], selection_center.mV[VZ]); F32 angle_radians, x, y, z; grid_rotation.getAngleAxis(&angle_radians, &x, &y, &z); @@ -1884,9 +1893,9 @@ void LLManipTranslate::renderTranslationHandles() if ((mManipPart == LL_NO_PART || mManipPart == LL_YZ_PLANE) && llabs(relative_camera_dir.mV[VX]) > MIN_PLANE_MANIP_DOT_PRODUCT) { // render YZ plane manipulator - glPushMatrix(); + gGL.pushMatrix(); glScalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]); - glTranslatef(0.f, mPlaneManipOffsetMeters, mPlaneManipOffsetMeters); + gGL.translatef(0.f, mPlaneManipOffsetMeters, mPlaneManipOffsetMeters); glScalef(mPlaneScales.mV[VX], mPlaneScales.mV[VX], mPlaneScales.mV[VX]); if (mHighlightedPart == LL_YZ_PLANE) { @@ -1898,49 +1907,49 @@ void LLManipTranslate::renderTranslationHandles() color1.setVec(0.f, 1.f, 0.f, 0.6f); color2.setVec(0.f, 0.f, 1.f, 0.6f); } - glBegin(GL_TRIANGLES); + gGL.begin(GL_TRIANGLES); { - glColor4fv(color1.mV); - glVertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); - glVertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f)); - glVertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); - - glColor4fv(color2.mV); - glVertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); - glVertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); - glVertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); + gGL.color4fv(color1.mV); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f)); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); + + gGL.color4fv(color2.mV); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); } - glEnd(); + gGL.end(); LLUI::setLineWidth(3.0f); - glBegin(GL_LINES); + gGL.begin(GL_LINES); { - glColor4f(0.f, 0.f, 0.f, 0.3f); - glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - glVertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - glVertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - glVertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f); - glVertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - glVertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f); - - glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); - glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); - glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); - glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); - glVertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); + gGL.color4f(0.f, 0.f, 0.f, 0.3f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f); + + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); } - glEnd(); + gGL.end(); LLUI::setLineWidth(1.0f); - glPopMatrix(); + gGL.popMatrix(); } if ((mManipPart == LL_NO_PART || mManipPart == LL_XZ_PLANE) && llabs(relative_camera_dir.mV[VY]) > MIN_PLANE_MANIP_DOT_PRODUCT) { // render XZ plane manipulator - glPushMatrix(); + gGL.pushMatrix(); glScalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]); - glTranslatef(mPlaneManipOffsetMeters, 0.f, mPlaneManipOffsetMeters); + gGL.translatef(mPlaneManipOffsetMeters, 0.f, mPlaneManipOffsetMeters); glScalef(mPlaneScales.mV[VY], mPlaneScales.mV[VY], mPlaneScales.mV[VY]); if (mHighlightedPart == LL_XZ_PLANE) { @@ -1953,48 +1962,48 @@ void LLManipTranslate::renderTranslationHandles() color2.setVec(1.f, 0.f, 0.f, 0.6f); } - glBegin(GL_TRIANGLES); + gGL.begin(GL_TRIANGLES); { - glColor4fv(color1.mV); - glVertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); - glVertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); - glVertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); - - glColor4fv(color2.mV); - glVertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); - glVertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f)); - glVertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); + gGL.color4fv(color1.mV); + gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); + gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); + gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); + + gGL.color4fv(color2.mV); + gGL.vertex3f(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f)); + gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f)); + gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f)); } - glEnd(); + gGL.end(); LLUI::setLineWidth(3.0f); - glBegin(GL_LINES); + gGL.begin(GL_LINES); { - glColor4f(0.f, 0.f, 0.f, 0.3f); - glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - glVertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - glVertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - glVertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f); - glVertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - glVertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f); + gGL.color4f(0.f, 0.f, 0.f, 0.3f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f); + gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f); - glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); - glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); - glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); - glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); - glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); - glVertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.1f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.25f); + gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.4f, 0.f, mPlaneManipOffsetMeters * PLANE_TICK_SIZE * 0.1f); } - glEnd(); + gGL.end(); LLUI::setLineWidth(1.0f); - glPopMatrix(); + gGL.popMatrix(); } if ((mManipPart == LL_NO_PART || mManipPart == LL_XY_PLANE) && llabs(relative_camera_dir.mV[VZ]) > MIN_PLANE_MANIP_DOT_PRODUCT) { // render XY plane manipulator - glPushMatrix(); + gGL.pushMatrix(); glScalef(mPlaneManipPositions.mV[VX], mPlaneManipPositions.mV[VY], mPlaneManipPositions.mV[VZ]); /* Y @@ -2008,13 +2017,13 @@ void LLManipTranslate::renderTranslationHandles() LLVector3 v0,v1,v2,v3; #if 0 // This should theoretically work but looks off; could be tuned later -SJB - glTranslatef(-mPlaneManipOffsetMeters, -mPlaneManipOffsetMeters, 0.f); + gGL.translatef(-mPlaneManipOffsetMeters, -mPlaneManipOffsetMeters, 0.f); v0 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f); v1 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.75f), 0.f); v2 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f); v3 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.75f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f); #else - glTranslatef(mPlaneManipOffsetMeters, mPlaneManipOffsetMeters, 0.f); + gGL.translatef(mPlaneManipOffsetMeters, mPlaneManipOffsetMeters, 0.f); v0 = LLVector3(mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), 0.f); v1 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.75f), 0.f); v2 = LLVector3(mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * ( PLANE_TICK_SIZE * 0.25f), 0.f); @@ -2032,44 +2041,44 @@ void LLManipTranslate::renderTranslationHandles() color2.setVec(0.f, 0.8f, 0.f, 0.6f); } - glBegin(GL_TRIANGLES); + gGL.begin(GL_TRIANGLES); { - glColor4fv(color1.mV); - glVertex3fv(v0.mV); - glVertex3fv(v1.mV); - glVertex3fv(v2.mV); - - glColor4fv(color2.mV); - glVertex3fv(v2.mV); - glVertex3fv(v3.mV); - glVertex3fv(v0.mV); + gGL.color4fv(color1.mV); + gGL.vertex3fv(v0.mV); + gGL.vertex3fv(v1.mV); + gGL.vertex3fv(v2.mV); + + gGL.color4fv(color2.mV); + gGL.vertex3fv(v2.mV); + gGL.vertex3fv(v3.mV); + gGL.vertex3fv(v0.mV); } - glEnd(); + gGL.end(); LLUI::setLineWidth(3.0f); - glBegin(GL_LINES); + gGL.begin(GL_LINES); { - glColor4f(0.f, 0.f, 0.f, 0.3f); + gGL.color4f(0.f, 0.f, 0.f, 0.3f); LLVector3 v12 = (v1 + v2) * .5f; - glVertex3fv(v0.mV); - glVertex3fv(v12.mV); - glVertex3fv(v12.mV); - glVertex3fv((v12 + (v0-v12)*.3f + (v2-v12)*.3f).mV); - glVertex3fv(v12.mV); - glVertex3fv((v12 + (v0-v12)*.3f + (v1-v12)*.3f).mV); + gGL.vertex3fv(v0.mV); + gGL.vertex3fv(v12.mV); + gGL.vertex3fv(v12.mV); + gGL.vertex3fv((v12 + (v0-v12)*.3f + (v2-v12)*.3f).mV); + gGL.vertex3fv(v12.mV); + gGL.vertex3fv((v12 + (v0-v12)*.3f + (v1-v12)*.3f).mV); LLVector3 v23 = (v2 + v3) * .5f; - glVertex3fv(v0.mV); - glVertex3fv(v23.mV); - glVertex3fv(v23.mV); - glVertex3fv((v23 + (v0-v23)*.3f + (v3-v23)*.3f).mV); - glVertex3fv(v23.mV); - glVertex3fv((v23 + (v0-v23)*.3f + (v2-v23)*.3f).mV); + gGL.vertex3fv(v0.mV); + gGL.vertex3fv(v23.mV); + gGL.vertex3fv(v23.mV); + gGL.vertex3fv((v23 + (v0-v23)*.3f + (v3-v23)*.3f).mV); + gGL.vertex3fv(v23.mV); + gGL.vertex3fv((v23 + (v0-v23)*.3f + (v2-v23)*.3f).mV); } - glEnd(); + gGL.end(); LLUI::setLineWidth(1.0f); - glPopMatrix(); + gGL.popMatrix(); } } { @@ -2141,7 +2150,7 @@ void LLManipTranslate::renderTranslationHandles() } } } - glPopMatrix(); + gGL.popMatrix(); } @@ -2150,11 +2159,11 @@ void LLManipTranslate::renderArrow(S32 which_arrow, S32 selected_arrow, F32 box_ LLGLSNoTexture gls_ui_no_texture; LLGLEnable gls_blend(GL_BLEND); LLGLEnable gls_color_material(GL_COLOR_MATERIAL); - + for (S32 pass = 1; pass <= 2; pass++) { LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, pass == 1 ? GL_LEQUAL : GL_GREATER); - glPushMatrix(); + gGL.pushMatrix(); S32 index = 0; @@ -2175,27 +2184,23 @@ void LLManipTranslate::renderArrow(S32 which_arrow, S32 selected_arrow, F32 box_ color.mV[index] = pass == 1 ? .8f : .35f ; // red, green, or blue color.mV[VALPHA] = 0.6f; } - glColor4fv( color.mV ); + gGL.color4fv( color.mV ); LLVector3 vec; { -// Stipple looks OK, but not great - SJB -// LLGLEnable stipple(GL_LINE_STIPPLE); -// glLineStipple(1, 0x3333); - LLUI::setLineWidth(2.0f); - glBegin(GL_LINES); + gGL.begin(GL_LINES); vec.mV[index] = box_size; - glVertex3f(vec.mV[0], vec.mV[1], vec.mV[2]); + gGL.vertex3f(vec.mV[0], vec.mV[1], vec.mV[2]); vec.mV[index] = arrow_size; - glVertex3f(vec.mV[0], vec.mV[1], vec.mV[2]); - glEnd(); + gGL.vertex3f(vec.mV[0], vec.mV[1], vec.mV[2]); + gGL.end(); LLUI::setLineWidth(1.0f); } - glTranslatef(vec.mV[0], vec.mV[1], vec.mV[2]); + gGL.translatef(vec.mV[0], vec.mV[1], vec.mV[2]); glScalef(handle_size, handle_size, handle_size); F32 rot = 0.0f; @@ -2220,31 +2225,32 @@ void LLManipTranslate::renderArrow(S32 which_arrow, S32 selected_arrow, F32 box_ break; } + glColor4fv(color.mV); glRotatef(rot, axis.mV[0], axis.mV[1], axis.mV[2]); glScalef(mArrowScales.mV[index], mArrowScales.mV[index], mArrowScales.mV[index] * 1.5f); gCone.render(CONE_LOD_HIGHEST); - glPopMatrix(); + gGL.popMatrix(); } } void LLManipTranslate::renderGridVert(F32 x_trans, F32 y_trans, F32 r, F32 g, F32 b, F32 alpha) { - glColor4f(r, g, b, alpha); + gGL.color4f(r, g, b, alpha); switch (mManipPart) { case LL_YZ_PLANE: - glVertex3f(0, x_trans, y_trans); + gGL.vertex3f(0, x_trans, y_trans); break; case LL_XZ_PLANE: - glVertex3f(x_trans, 0, y_trans); + gGL.vertex3f(x_trans, 0, y_trans); break; case LL_XY_PLANE: - glVertex3f(x_trans, y_trans, 0); + gGL.vertex3f(x_trans, y_trans, 0); break; default: - glVertex3f(0,0,0); + gGL.vertex3f(0,0,0); break; } diff --git a/linden/indra/newview/llmaniptranslate.h b/linden/indra/newview/llmaniptranslate.h index 7f206eb..05decfb 100644 --- a/linden/indra/newview/llmaniptranslate.h +++ b/linden/indra/newview/llmaniptranslate.h @@ -35,7 +35,6 @@ #include "llmanip.h" #include "lltimer.h" #include "v4math.h" -#include "linked_lists.h" #include "llquaternion.h" class LLManipTranslate : public LLManip @@ -88,6 +87,17 @@ protected: F32 getMinGridScale(); private: + struct compare_manipulators + { + bool operator() (const ManipulatorHandle* const a, const ManipulatorHandle* const b) const + { + if (a->mEndPosition.mV[VZ] != b->mEndPosition.mV[VZ]) + return (a->mEndPosition.mV[VZ] < b->mEndPosition.mV[VZ]); + else + return a->mManipID < b->mManipID; + } + }; + S32 mLastHoverMouseX; S32 mLastHoverMouseY; BOOL mSendUpdateOnMouseUp; @@ -105,7 +115,8 @@ private: LLVector3d mDragCursorStartGlobal; LLVector3d mDragSelectionStartGlobal; LLTimer mUpdateTimer; - LLLinkedList mProjectedManipulators; + typedef std::set minpulator_list_t; + minpulator_list_t mProjectedManipulators; LLVector4 mManipulatorVertices[18]; F32 mSnapOffsetMeters; LLVector3 mSnapOffsetAxis; diff --git a/linden/indra/newview/llmediaremotectrl.cpp b/linden/indra/newview/llmediaremotectrl.cpp index 8bf9103..401fc7e 100644 --- a/linden/indra/newview/llmediaremotectrl.cpp +++ b/linden/indra/newview/llmediaremotectrl.cpp @@ -33,9 +33,16 @@ #include "llmediaremotectrl.h" +#include "audioengine.h" +#include "lliconctrl.h" +#include "llmimetypes.h" #include "lloverlaybar.h" +#include "llviewermedia.h" +#include "llviewerparcelmedia.h" +#include "llviewerparcelmgr.h" #include "llvieweruictrlfactory.h" #include "llpanelaudiovolume.h" +#include "llparcel.h" #include "llviewercontrol.h" #include "llbutton.h" @@ -45,7 +52,7 @@ LLMediaRemoteCtrl::LLMediaRemoteCtrl() { setIsChrome(TRUE); - mIsFocusRoot = TRUE; + setFocusRoot(TRUE); mFactoryMap["Volume Panel"] = LLCallbackMap(createVolumePanel, NULL); build(); @@ -69,6 +76,10 @@ BOOL LLMediaRemoteCtrl::postBuild() { childSetAction("media_play",LLOverlayBar::toggleMediaPlay,this); childSetAction("music_play",LLOverlayBar::toggleMusicPlay,this); + childSetAction("media_stop",LLOverlayBar::mediaStop,this); + childSetAction("music_stop",LLOverlayBar::toggleMusicPlay,this); + childSetAction("media_pause",LLOverlayBar::toggleMediaPlay,this); + childSetAction("music_pause",LLOverlayBar::toggleMusicPlay,this); childSetAction("expand", onClickExpandBtn, this); return TRUE; @@ -76,36 +87,8 @@ BOOL LLMediaRemoteCtrl::postBuild() void LLMediaRemoteCtrl::draw() { - LLButton* music_play_btn = LLUICtrlFactory::getButtonByName(this, "music_play"); - if (music_play_btn) - { - if (gOverlayBar->musicPlaying()) - { - music_play_btn->setValue(TRUE); - music_play_btn->setImageOverlay("icn_music-pause.tga"); - } - else - { - music_play_btn->setValue(FALSE); - music_play_btn->setImageOverlay("icn_music-play.tga"); - } - } - - LLButton* media_play_btn = LLUICtrlFactory::getButtonByName(this, "media_play"); - if (media_play_btn) - { - if (gOverlayBar->mediaPlaying()) - { - media_play_btn->setValue(TRUE); - media_play_btn->setImageOverlay("icn_media-pause.tga"); - } - else - { - media_play_btn->setValue(FALSE); - media_play_btn->setImageOverlay("icn_media-play.tga"); - } - } - + enableMediaButtons(); + LLButton* expand_button = LLUICtrlFactory::getButtonByName(this, "expand"); if (expand_button) { @@ -142,3 +125,128 @@ void* LLMediaRemoteCtrl::createVolumePanel(void* data) LLPanelAudioVolume* panel = new LLPanelAudioVolume(); return panel; } + +// Virtual +void LLMediaRemoteCtrl::setToolTip(const LLString& msg) +{ + LLString mime_type = LLMIMETypes::translate(LLViewerMedia::getMimeType()); + LLString tool_tip = LLMIMETypes::findToolTip(LLViewerMedia::getMimeType()); + LLString play_tip = LLMIMETypes::findPlayTip(LLViewerMedia::getMimeType()); + // childSetToolTip("media_stop", getString("stop_label") + "\n" + tool_tip); + childSetToolTip("media_icon", tool_tip); + childSetToolTip("media_play", play_tip); +} + +void LLMediaRemoteCtrl::enableMediaButtons() +{ + // Media + bool play_media_enabled = false; + bool stop_media_enabled = false; + bool play_music_enabled = false; + bool stop_music_enabled = false; + bool music_show_pause = false; + bool media_show_pause = false; + LLColor4 music_icon_color = LLUI::sColorsGroup->getColor( "IconDisabledColor" ); + LLColor4 media_icon_color = LLUI::sColorsGroup->getColor( "IconDisabledColor" ); + LLString media_type = "none/none"; + + // Put this in xui file + LLString media_url = getString("default_tooltip_label"); + LLParcel* parcel = gParcelMgr->getAgentParcel(); + + if (gSavedSettings.getBOOL("AudioStreamingVideo")) + { + if ( parcel && parcel->getMediaURL()[0]) + { + // Set the tooltip + // Put this text into xui file + media_url = parcel->getObscureMedia() ? getString("media_hidden_label") : parcel->getMediaURL(); + media_type = parcel->getMediaType(); + + play_media_enabled = true; + media_icon_color = LLUI::sColorsGroup->getColor( "IconEnabledColor" ); + + LLMediaBase::EStatus status = LLViewerParcelMedia::getStatus(); + switch(status) + { + case LLMediaBase::STATUS_STOPPED: + case LLMediaBase::STATUS_UNKNOWN: + media_show_pause = false; + stop_media_enabled = false; + break; + case LLMediaBase::STATUS_STARTED: + case LLMediaBase::STATUS_NAVIGATING: + case LLMediaBase::STATUS_RESETTING: + // HACK: only show the pause button for movie types + media_show_pause = LLMIMETypes::widgetType(parcel->getMediaType()) == "movie" ? true : false; + stop_media_enabled = true; + play_media_enabled = false; + break; + case LLMediaBase::STATUS_PAUSED: + media_show_pause = false; + stop_media_enabled = true; + break; + default: + // inherit defaults above + break; + } + } + } + if (gSavedSettings.getBOOL("AudioStreamingMusic") && gAudiop) + { + + if ( parcel && parcel->getMusicURL()[0]) + { + play_music_enabled = true; + music_icon_color = LLUI::sColorsGroup->getColor( "IconEnabledColor" ); + + if (gOverlayBar->musicPlaying()) + { + music_show_pause = true; + stop_music_enabled = true; + } + else + { + music_show_pause = false; + stop_music_enabled = false; + } + } + // if no mime type has been set disable play + if( LLViewerMedia::getMimeType().empty() + || LLViewerMedia::getMimeType() == "none/none") + { + play_media_enabled = false; + stop_media_enabled = false; + } + } + const LLUUID media_icon_id = LLUUID(gViewerArt.findString(LLMIMETypes::findIcon(media_type))); + LLButton* music_play_btn = LLUICtrlFactory::getButtonByName(this, "music_play"); + LLButton* music_stop_btn = LLUICtrlFactory::getButtonByName(this, "music_stop"); + LLButton* music_pause_btn = LLUICtrlFactory::getButtonByName(this, "music_pause"); + LLButton* media_play_btn = LLUICtrlFactory::getButtonByName(this, "media_play"); + LLButton* media_stop_btn = LLUICtrlFactory::getButtonByName(this, "media_stop"); + LLButton* media_pause_btn = LLUICtrlFactory::getButtonByName(this, "media_pause"); + LLIconCtrl* media_icon = LLUICtrlFactory::getIconByName(this, "media_icon"); + + music_play_btn->setEnabled(play_music_enabled); + music_stop_btn->setEnabled(stop_music_enabled); + music_pause_btn->setEnabled(music_show_pause); + music_pause_btn->setVisible(music_show_pause); + music_play_btn->setVisible(! music_show_pause); + childSetColor("music_icon", music_icon_color); + if(! media_icon_id.isNull()) + { + media_icon->setImage(media_icon_id); + } + + media_play_btn->setEnabled(play_media_enabled); + media_stop_btn->setEnabled(stop_media_enabled); + media_pause_btn->setEnabled(media_show_pause); + media_pause_btn->setVisible(media_show_pause); + media_play_btn->setVisible(! media_show_pause); + childSetColor("media_icon", media_icon_color); + + setToolTip(media_url); +} + + diff --git a/linden/indra/newview/llmediaremotectrl.h b/linden/indra/newview/llmediaremotectrl.h index 2681681..cacb2b3 100644 --- a/linden/indra/newview/llmediaremotectrl.h +++ b/linden/indra/newview/llmediaremotectrl.h @@ -45,8 +45,11 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void draw(); + void enableMediaButtons(); + static void onClickExpandBtn(void* user_data); static void* createVolumePanel(void* data); + virtual void setToolTip(const LLString& msg); protected: void build(); diff --git a/linden/indra/newview/llmemoryview.cpp b/linden/indra/newview/llmemoryview.cpp index 40b5387..c6db748 100644 --- a/linden/indra/newview/llmemoryview.cpp +++ b/linden/indra/newview/llmemoryview.cpp @@ -107,12 +107,12 @@ BOOL LLMemoryView::handleHover(S32 x, S32 y, MASK mask) struct mtv_display_info { S32 memtype; const char *desc; - LLColor4 *color; + const LLColor4 *color; }; -static LLColor4 red0(0.5f, 0.0f, 0.0f, 1.0f); +static const LLColor4 red0(0.5f, 0.0f, 0.0f, 1.0f); -static struct mtv_display_info mtv_display_table[] = +static const struct mtv_display_info mtv_display_table[] = { { LLMemType::MTYPE_INIT, "Init", &LLColor4::white }, { LLMemType::MTYPE_STARTUP, "Startup", &LLColor4::cyan1 }, @@ -147,8 +147,8 @@ static const int MTV_DISPLAY_NUM = (sizeof(mtv_display_table)/sizeof(mtv_displa void LLMemoryView::draw() { std::string tdesc; - S32 width = mRect.getWidth(); - S32 height = mRect.getHeight(); + S32 width = getRect().getWidth(); + S32 height = getRect().getHeight(); LLGLSUIDefault gls_ui; LLGLSNoTexture gls_no_tex; @@ -194,7 +194,6 @@ void LLMemoryView::draw() // Labels { - LLGLSTexture gls_texture; y = ytop; S32 peak = 0; for (S32 i=0; ihasName( "mimetypes" ) ) + { + llwarns << "Unable to read MIME type file: " + << xml_filename << llendl; + return false; + } + + for (LLXMLNode* node = root->getFirstChild(); + node != NULL; + node = node->getNextSibling()) + { + if (node->hasName("defaultlabel")) + { + sDefaultLabel = node->getTextContents(); + } + else if (node->hasName("defaultwidget")) + { + sDefaultWidgetType = node->getTextContents(); + } + else if (node->hasName("defaultimpl")) + { + sDefaultImpl = node->getTextContents(); + } + else if (node->hasName("mimetype") || node->hasName("scheme")) + { + LLString mime_type; + node->getAttributeString("name", mime_type); + LLMIMEInfo info; + for (LLXMLNode* child = node->getFirstChild(); + child != NULL; + child = child->getNextSibling()) + { + if (child->hasName("label")) + { + info.mLabel = child->getTextContents(); + } + else if (child->hasName("widgettype")) + { + info.mWidgetType = child->getTextContents(); + } + else if (child->hasName("impl")) + { + info.mImpl = child->getTextContents(); + } + } + sMap[mime_type] = info; + } + else if (node->hasName("widgetset")) + { + LLString set_name; + node->getAttributeString("name", set_name); + LLMIMEWidgetSet info; + for (LLXMLNode* child = node->getFirstChild(); + child != NULL; + child = child->getNextSibling()) + { + if (child->hasName("label")) + { + info.mLabel = child->getTextContents(); + } + if (child->hasName("icon")) + { + info.mIcon = child->getTextContents(); + } + if (child->hasName("default_type")) + { + info.mDefaultMimeType = child->getTextContents(); + } + if (child->hasName("tooltip")) + { + info.mToolTip = child->getTextContents(); + } + if (child->hasName("playtip")) + { + info.mPlayTip = child->getTextContents(); + } + if (child->hasName("allow_resize")) + { + child->getBoolValue( 1, (BOOL*)&( info.mAllowResize ) ); + } + if (child->hasName("allow_looping")) + { + child->getBoolValue( 1, (BOOL*)&( info.mAllowLooping ) ); + } + } + sWidgetMap[set_name] = info; + } + } + return true; +} + +// static +LLString LLMIMETypes::translate(const LLString& mime_type) +{ + mime_info_map_t::const_iterator it = sMap.find(mime_type); + if (it != sMap.end()) + { + return it->second.mLabel; + } + else + { + return sDefaultLabel; + } +} + +// static +LLString LLMIMETypes::widgetType(const LLString& mime_type) +{ + mime_info_map_t::const_iterator it = sMap.find(mime_type); + if (it != sMap.end()) + { + return it->second.mWidgetType; + } + else + { + return sDefaultWidgetType; + } +} + +// static +LLString LLMIMETypes::implType(const LLString& mime_type) +{ + mime_info_map_t::const_iterator it = sMap.find(mime_type); + if (it != sMap.end()) + { + return it->second.mImpl; + } + else + { + return sDefaultImpl; + } +} + +// static +LLString LLMIMETypes::findIcon(const LLString& mime_type) +{ + LLString icon = ""; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + icon = it->second.mIcon; + } + return icon; +} + +// static +LLString LLMIMETypes::findDefaultMimeType(const LLString& widget_type) +{ + LLString mime_type = "none/none"; + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + mime_type = it->second.mDefaultMimeType; + } + return mime_type; +} + +// static +LLString LLMIMETypes::findToolTip(const LLString& mime_type) +{ + LLString tool_tip = ""; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + tool_tip = it->second.mToolTip; + } + return tool_tip; +} + +// static +LLString LLMIMETypes::findPlayTip(const LLString& mime_type) +{ + LLString play_tip = ""; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + play_tip = it->second.mPlayTip; + } + return play_tip; +} + +// static +bool LLMIMETypes::findAllowResize(const LLString& mime_type) +{ + bool allow_resize = false; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + allow_resize = it->second.mAllowResize; + } + return allow_resize; +} + +// static +bool LLMIMETypes::findAllowLooping(const LLString& mime_type) +{ + bool allow_looping = false; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + allow_looping = it->second.mAllowLooping; + } + return allow_looping; +} diff --git a/linden/indra/newview/llmimetypes.h b/linden/indra/newview/llmimetypes.h new file mode 100644 index 0000000..6267e7f --- /dev/null +++ b/linden/indra/newview/llmimetypes.h @@ -0,0 +1,118 @@ +/** + * @file llmimetypes.h + * @brief Translates a MIME type like "video/quicktime" into a + * localizable user-friendly string like "QuickTime Movie" + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLMIMETYPES_H +#define LLMIMETYPES_H + +#include "llstring.h" // because XML parsing lib uses LLString, ugh +#include + +class LLMIMETypes +{ +public: + static bool parseMIMETypes(const LLString& xml_file_path); + // Loads the MIME string definition XML file, usually + // from the application skins directory + + static LLString translate(const LLString& mime_type); + // Returns "QuickTime Movie" from "video/quicktime" + + static LLString widgetType(const LLString& mime_type); + // Type of control widgets for this MIME type + // Returns "movie" from "video/quicktime" + + static LLString implType(const LLString& mime_type); + // Type of Impl to use for decoding media. + + static LLString findIcon(const LLString& mime_type); + // Icon from control widget type for this MIME type + + static LLString findToolTip(const LLString& mime_type); + // Tool tip from control widget type for this MIME type + + static LLString findPlayTip(const LLString& mime_type); + // Play button tool tip from control widget type for this MIME type + + static LLString findDefaultMimeType(const LLString& widget_type); + // Canonical mime type associated with this widget set + + static bool findAllowResize(const LLString& mime_type); + // accessor for flag to enable/disable media size edit fields + + static bool LLMIMETypes::findAllowLooping(const LLString& mime_type); + // accessor for flag to enable/disable media looping checkbox + +public: + struct LLMIMEInfo + { + LLString mLabel; + // friendly label like "QuickTime Movie" + + LLString mWidgetType; + // "web" means use web media UI widgets + + LLString mImpl; + // which impl to use with this mime type + }; + struct LLMIMEWidgetSet + { + LLString mLabel; + // friendly label like "QuickTime Movie" + + LLString mIcon; + // Name of icon asset to display in toolbar + + LLString mDefaultMimeType; + // Mime type string to use in absence of a specific one + + LLString mToolTip; + // custom tool tip for this mime type + + LLString mPlayTip; + // custom tool tip to display for Play button + + bool mAllowResize; + // enable/disable media size edit fields + + bool mAllowLooping; + // enable/disable media looping checkbox + }; + typedef std::map< LLString, LLMIMEInfo > mime_info_map_t; + typedef std::map< LLString, LLMIMEWidgetSet > mime_widget_set_map_t; + + // Public so users can iterate over it + static mime_info_map_t sMap; + static mime_widget_set_map_t sWidgetMap; +private: +}; + +#endif diff --git a/linden/indra/newview/llmoveview.cpp b/linden/indra/newview/llmoveview.cpp index 422ac0c..5444a6e 100644 --- a/linden/indra/newview/llmoveview.cpp +++ b/linden/indra/newview/llmoveview.cpp @@ -38,7 +38,6 @@ // Viewer includes #include "llagent.h" -#include "llcallbacklist.h" #include "llviewercontrol.h" #include "llfontgl.h" #include "llbutton.h" diff --git a/linden/indra/newview/llnamebox.cpp b/linden/indra/newview/llnamebox.cpp index 9f141b8..5a164b4 100644 --- a/linden/indra/newview/llnamebox.cpp +++ b/linden/indra/newview/llnamebox.cpp @@ -70,24 +70,15 @@ void LLNameBox::setNameID(const LLUUID& name_id, BOOL is_group) { mNameID = name_id; - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char group_name[DB_GROUP_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - LLString name; + std::string name; if (!is_group) { - gCacheName->getName(name_id, first, last); - - name.assign(first); - name.append(1, ' '); - name.append(last); + gCacheName->getFullName(name_id, name); } else { - gCacheName->getGroupName(name_id, group_name); - - name.assign(group_name); + gCacheName->getGroupName(name_id, name); } setText(name); diff --git a/linden/indra/newview/llnamebox.h b/linden/indra/newview/llnamebox.h index f0926fe..8afac5c 100644 --- a/linden/indra/newview/llnamebox.h +++ b/linden/indra/newview/llnamebox.h @@ -37,7 +37,6 @@ #include "llview.h" #include "llstring.h" #include "llfontgl.h" -#include "linked_lists.h" #include "lltextbox.h" class LLNameBox diff --git a/linden/indra/newview/llnameeditor.cpp b/linden/indra/newview/llnameeditor.cpp index aeb4a36..2ba25c3 100644 --- a/linden/indra/newview/llnameeditor.cpp +++ b/linden/indra/newview/llnameeditor.cpp @@ -90,23 +90,15 @@ void LLNameEditor::setNameID(const LLUUID& name_id, BOOL is_group) { mNameID = name_id; - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char group_name[DB_GROUP_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - LLString name; + std::string name; if (!is_group) { - gCacheName->getName(name_id, first, last); - - name.assign(first); - name.append(1, ' '); - name.append(last); + gCacheName->getFullName(name_id, name); } else { - gCacheName->getGroupName(name_id, group_name); - name.assign(group_name); + gCacheName->getGroupName(name_id, name); } setText(name); diff --git a/linden/indra/newview/llnameeditor.h b/linden/indra/newview/llnameeditor.h index 1b02aa4..02e67aa 100644 --- a/linden/indra/newview/llnameeditor.h +++ b/linden/indra/newview/llnameeditor.h @@ -38,7 +38,6 @@ #include "v4color.h" #include "llstring.h" #include "llfontgl.h" -#include "linked_lists.h" #include "lllineeditor.h" diff --git a/linden/indra/newview/llnamelistctrl.cpp b/linden/indra/newview/llnamelistctrl.cpp index 4b63b08..bdfdf06 100644 --- a/linden/indra/newview/llnamelistctrl.cpp +++ b/linden/indra/newview/llnamelistctrl.cpp @@ -73,15 +73,9 @@ BOOL LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, { //llinfos << "LLNameListCtrl::addNameItem " << agent_id << llendl; - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + std::string fullname; + BOOL result = gCacheName->getFullName(agent_id, fullname); - BOOL result = gCacheName->getName(agent_id, first, last); - - LLString fullname; - fullname.assign(first); - fullname.append(1, ' '); - fullname.append(last); fullname.append(suffix); addStringUUIDItem(fullname, agent_id, pos, enabled); @@ -142,7 +136,7 @@ void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos, BOOL enabled) { //llinfos << "LLNameListCtrl::addGroupNameItem " << group_id << llendl; - char group_name[DB_GROUP_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + std::string group_name; gCacheName->getGroupName(group_id, group_name); addStringUUIDItem(group_name, group_id, pos, enabled); } @@ -153,7 +147,7 @@ void LLNameListCtrl::addGroupNameItem(LLScrollListItem* item, EAddPosition pos) { //llinfos << "LLNameListCtrl::addGroupNameItem " << item->getUUID() << llendl; - char group_name[DB_GROUP_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ + std::string group_name; gCacheName->getGroupName(item->getUUID(), group_name); LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex); @@ -166,15 +160,8 @@ BOOL LLNameListCtrl::addNameItem(LLScrollListItem* item, EAddPosition pos) { //llinfos << "LLNameListCtrl::addNameItem " << item->getUUID() << llendl; - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - - BOOL result = gCacheName->getName(item->getUUID(), first, last); - - LLString fullname; - fullname.assign(first); - fullname.append(1, ' '); - fullname.append(last); + std::string fullname; + BOOL result = gCacheName->getFullName(item->getUUID(), fullname); LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex); ((LLScrollListText*)cell)->setText( fullname ); @@ -195,17 +182,12 @@ LLScrollListItem* LLNameListCtrl::addElement(const LLSD& value, EAddPosition pos { LLScrollListItem* item = LLScrollListCtrl::addElement(value, pos, userdata); - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - // use supplied name by default - LLString fullname = value["name"].asString(); + std::string fullname = value["name"].asString(); if (value["target"].asString() == "GROUP") { - char group_name[DB_GROUP_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - gCacheName->getGroupName(item->getUUID(), group_name); + gCacheName->getGroupName(item->getUUID(), fullname); // fullname will be "nobody" if group not found - fullname = group_name; } else if (value["target"].asString() == "SPECIAL") { @@ -213,11 +195,10 @@ LLScrollListItem* LLNameListCtrl::addElement(const LLSD& value, EAddPosition pos } else // normal resident { - if (gCacheName->getName(item->getUUID(), first, last)) + std::string name; + if (gCacheName->getFullName(item->getUUID(), name)) { - fullname.assign(first); - fullname.append(1, ' '); - fullname.append(last); + fullname = name; } } @@ -268,7 +249,7 @@ void LLNameListCtrl::refresh(const LLUUID& id, const char* first, // TODO: scan items for that ID, fix if necessary item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (iter = getItemList().begin(); iter != getItemList().end(); iter++) { LLScrollListItem* item = *iter; if (item->getUUID() == id) diff --git a/linden/indra/newview/llnetmap.cpp b/linden/indra/newview/llnetmap.cpp index ca6161b..01400b1 100644 --- a/linden/indra/newview/llnetmap.cpp +++ b/linden/indra/newview/llnetmap.cpp @@ -36,9 +36,9 @@ #include "indra_constants.h" #include "llui.h" -#include "linked_lists.h" #include "llmath.h" // clampf() #include "llfocusmgr.h" +#include "llglimmediate.h" #include "llagent.h" #include "llcallingcard.h" @@ -117,9 +117,11 @@ LLNetMap::LLNetMap( mTextBoxEast->setColor( minor_color ); addChild( mTextBoxEast ); + major_dir_rect.mRight += 1 ; mTextBoxWest = new LLTextBox( "W", major_dir_rect ); mTextBoxWest->setColor( minor_color ); addChild( mTextBoxWest ); + major_dir_rect.mRight -= 1 ; mTextBoxSouth = new LLTextBox( "S", major_dir_rect ); mTextBoxSouth->setColor( minor_color ); @@ -158,7 +160,7 @@ LLNetMap::LLNetMap( &LLTracker::isTracking, NULL) ); menu->setVisible(FALSE); addChild(menu); - mPopupMenuHandle = menu->mViewHandle; + mPopupMenuHandle = menu->getHandle(); sInstance = this; @@ -191,8 +193,8 @@ void LLNetMap::setScale( F32 scale ) if (mObjectImagep.notNull()) { - F32 half_width = (F32)(mRect.getWidth() / 2); - F32 half_height = (F32)(mRect.getHeight() / 2); + F32 half_width = (F32)(getRect().getWidth() / 2); + F32 half_height = (F32)(getRect().getHeight() / 2); F32 radius = sqrt( half_width * half_width + half_height * half_height ); F32 region_widths = (2.f*radius)/gMiniMapScale; @@ -256,17 +258,17 @@ void LLNetMap::draw() glMatrixMode(GL_MODELVIEW); // Draw background rectangle - glColor4fv( mBackgroundColor.mV ); - gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0); + gGL.color4fv( mBackgroundColor.mV ); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0); } // region 0,0 is in the middle - S32 center_sw_left = mRect.getWidth() / 2 + llfloor(mCurPanX); - S32 center_sw_bottom = mRect.getHeight() / 2 + llfloor(mCurPanY); + S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPanX); + S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPanY); - glPushMatrix(); + gGL.pushMatrix(); - glTranslatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f); + gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f); if( LLNetMap::sRotateMap ) { @@ -296,31 +298,31 @@ void LLNetMap::draw() if (regionp == gAgent.getRegion()) { - glColor4f(1.f, 1.f, 1.f, 1.f); + gGL.color4f(1.f, 1.f, 1.f, 1.f); } else { - glColor4f(0.8f, 0.8f, 0.8f, 1.f); + gGL.color4f(0.8f, 0.8f, 0.8f, 1.f); } if (!regionp->mAlive) { - glColor4f(1.f, 0.5f, 0.5f, 1.f); + gGL.color4f(1.f, 0.5f, 0.5f, 1.f); } // Draw using texture. LLViewerImage::bindTexture(regionp->getLand().getSTexture()); - glBegin(GL_QUADS); - glTexCoord2f(0.f, 1.f); - glVertex2f(left, top); - glTexCoord2f(0.f, 0.f); - glVertex2f(left, bottom); - glTexCoord2f(1.f, 0.f); - glVertex2f(right, bottom); - glTexCoord2f(1.f, 1.f); - glVertex2f(right, top); - glEnd(); + gGL.begin(GL_QUADS); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2f(left, top); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2f(left, bottom); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2f(right, bottom); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2f(right, top); + gGL.end(); // Draw water glAlphaFunc(GL_GREATER, ABOVE_WATERLINE_ALPHA / 255.f ); @@ -328,16 +330,16 @@ void LLNetMap::draw() if (regionp->getLand().getWaterTexture()) { LLViewerImage::bindTexture(regionp->getLand().getWaterTexture()); - glBegin(GL_QUADS); - glTexCoord2f(0.f, 1.f); - glVertex2f(left, top); - glTexCoord2f(0.f, 0.f); - glVertex2f(left, bottom); - glTexCoord2f(1.f, 0.f); - glVertex2f(right, bottom); - glTexCoord2f(1.f, 1.f); - glVertex2f(right, top); - glEnd(); + gGL.begin(GL_QUADS); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2f(left, top); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2f(left, bottom); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2f(right, bottom); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2f(right, top); + gGL.end(); } } glAlphaFunc(GL_GREATER,0.01f); @@ -378,18 +380,18 @@ void LLNetMap::draw() F32 image_half_width = 0.5f*mObjectMapPixels; F32 image_half_height = 0.5f*mObjectMapPixels; - glBegin(GL_QUADS); - glTexCoord2f(0.f, 1.f); - glVertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); - glTexCoord2f(0.f, 0.f); - glVertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height); - glTexCoord2f(1.f, 0.f); - glVertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); - glTexCoord2f(1.f, 1.f); - glVertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); - glEnd(); + gGL.begin(GL_QUADS); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); + gGL.end(); - glPopMatrix(); + gGL.popMatrix(); LLVector3d pos_global; LLVector3 pos_map; @@ -486,28 +488,28 @@ void LLNetMap::draw() if( LLNetMap::sRotateMap ) { - glColor4fv(gFrustumMapColor.mV); + gGL.color4fv(gFrustumMapColor.mV); - glBegin( GL_TRIANGLES ); - glVertex2f( ctr_x, ctr_y ); - glVertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); - glVertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); - glEnd(); + gGL.begin( GL_TRIANGLES ); + gGL.vertex2f( ctr_x, ctr_y ); + gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); + gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); + gGL.end(); } else { - glColor4fv(gRotatingFrustumMapColor.mV); + gGL.color4fv(gRotatingFrustumMapColor.mV); // If we don't rotate the map, we have to rotate the frustum. - glPushMatrix(); - glTranslatef( ctr_x, ctr_y, 0 ); + gGL.pushMatrix(); + gGL.translatef( ctr_x, ctr_y, 0 ); glRotatef( atan2( gCamera->getAtAxis().mV[VX], gCamera->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); - glBegin( GL_TRIANGLES ); - glVertex2f( 0, 0 ); - glVertex2f( -half_width_pixels, far_clip_pixels ); - glVertex2f( half_width_pixels, far_clip_pixels ); - glEnd(); - glPopMatrix(); + gGL.begin( GL_TRIANGLES ); + gGL.vertex2f( 0, 0 ); + gGL.vertex2f( -half_width_pixels, far_clip_pixels ); + gGL.vertex2f( half_width_pixels, far_clip_pixels ); + gGL.end(); + gGL.popMatrix(); } } @@ -542,8 +544,8 @@ LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos ) pos_local.rotVec( rot ); } - pos_local.mV[VX] += mRect.getWidth() / 2 + mCurPanX; - pos_local.mV[VY] += mRect.getHeight() / 2 + mCurPanY; + pos_local.mV[VX] += getRect().getWidth() / 2 + mCurPanX; + pos_local.mV[VY] += getRect().getHeight() / 2 + mCurPanY; return pos_local; } @@ -554,15 +556,15 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color, LLVector3 pos_local = globalPosToView( pos_global ); if( (pos_local.mV[VX] < 0) || (pos_local.mV[VY] < 0) || - (pos_local.mV[VX] >= mRect.getWidth()) || - (pos_local.mV[VY] >= mRect.getHeight()) ) + (pos_local.mV[VX] >= getRect().getWidth()) || + (pos_local.mV[VY] >= getRect().getHeight()) ) { if (draw_arrow) { S32 x = llround( pos_local.mV[VX] ); S32 y = llround( pos_local.mV[VY] ); - LLWorldMapView::drawTrackingCircle( mRect, x, y, color, 1, 10 ); - LLWorldMapView::drawTrackingArrow( mRect, x, y, color ); + LLWorldMapView::drawTrackingCircle( getRect(), x, y, color, 1, 10 ); + LLWorldMapView::drawTrackingArrow( getRect(), x, y, color ); } } else @@ -576,8 +578,8 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color, LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y ) { - x -= llround(mRect.getWidth() / 2 + mCurPanX); - y -= llround(mRect.getHeight() / 2 + mCurPanY); + x -= llround(getRect().getWidth() / 2 + mCurPanX); + y -= llround(getRect().getHeight() / 2 + mCurPanY); LLVector3 pos_local( (F32)x, (F32)y, 0 ); @@ -612,35 +614,32 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, LLString& msg, LLRect* sticky_rect_s { return FALSE; } - if( getVisible() && pointInView( x, y ) ) + LLViewerRegion* region = gWorldPointer->getRegionFromPosGlobal( viewPosToGlobal( x, y ) ); + if( region ) { - LLViewerRegion* region = gWorldPointer->getRegionFromPosGlobal( viewPosToGlobal( x, y ) ); - if( region ) - { - msg.assign( region->getName() ); + msg.assign( region->getName() ); #ifndef LL_RELEASE_FOR_DOWNLOAD - char buffer[MAX_STRING]; /*Flawfinder: ignore*/ - msg.append("\n"); - region->getHost().getHostName(buffer, MAX_STRING); - msg.append(buffer); - msg.append("\n"); - region->getHost().getString(buffer, MAX_STRING); - msg.append(buffer); + char buffer[MAX_STRING]; /*Flawfinder: ignore*/ + msg.append("\n"); + region->getHost().getHostName(buffer, MAX_STRING); + msg.append(buffer); + msg.append("\n"); + region->getHost().getString(buffer, MAX_STRING); + msg.append(buffer); #endif - // *TODO: put this under the control of XUI so it can be - // translated. - msg.append("\n(Double-click to open Map)"); - - S32 SLOP = 4; - localPointToScreen( - x - SLOP, y - SLOP, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP; - sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP; - } - handled = TRUE; + // *TODO: put this under the control of XUI so it can be + // translated. + msg.append("\n(Double-click to open Map)"); + + S32 SLOP = 4; + localPointToScreen( + x - SLOP, y - SLOP, + &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); + sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP; + sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP; } + handled = TRUE; return handled; } @@ -651,8 +650,8 @@ void LLNetMap::setDirectionPos( LLTextBox* text_box, F32 rotation ) // Rotation of 0 means x = 1, y = 0 on the unit circle. - F32 map_half_height = (F32)(mRect.getHeight() / 2); - F32 map_half_width = (F32)(mRect.getWidth() / 2); + F32 map_half_height = (F32)(getRect().getHeight() / 2); + F32 map_half_width = (F32)(getRect().getWidth() / 2); F32 text_half_height = (F32)(text_box->getRect().getHeight() / 2); F32 text_half_width = (F32)(text_box->getRect().getWidth() / 2); F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width ); @@ -762,9 +761,9 @@ void LLNetMap::renderPoint(const LLVector3 &pos_local, const LLColor4U &color, void LLNetMap::createObjectImage() { - // Find the size of the side of a square that surrounds the circle that surrounds mRect. - F32 half_width = (F32)(mRect.getWidth() / 2); - F32 half_height = (F32)(mRect.getHeight() / 2); + // Find the size of the side of a square that surrounds the circle that surrounds getRect(). + F32 half_width = (F32)(getRect().getWidth() / 2); + F32 half_height = (F32)(getRect().getHeight() / 2); F32 radius = sqrt( half_width * half_width + half_height * half_height ); S32 square_size = S32( 2 * radius ); @@ -798,7 +797,7 @@ BOOL LLNetMap::handleDoubleClick( S32 x, S32 y, MASK mask ) BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) { - LLMenuGL* menu = (LLMenuGL*)LLView::getViewByHandle(mPopupMenuHandle); + LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if (menu) { menu->buildDrawLabels(); diff --git a/linden/indra/newview/llnetmap.h b/linden/indra/newview/llnetmap.h index 17963a0..88ec051 100644 --- a/linden/indra/newview/llnetmap.h +++ b/linden/indra/newview/llnetmap.h @@ -92,7 +92,7 @@ protected: static void fly( const LLVector3d& destination ); public: - LLViewHandle mPopupMenuHandle; + LLHandle mPopupMenuHandle; LLColor4 mBackgroundColor; F32 mScale; // Size of a region in pixels diff --git a/linden/indra/newview/llnotify.cpp b/linden/indra/newview/llnotify.cpp index f486ca5..0bd039a 100644 --- a/linden/indra/newview/llnotify.cpp +++ b/linden/indra/newview/llnotify.cpp @@ -35,6 +35,7 @@ #include "llchat.h" #include "llfocusmgr.h" +#include "llglimmediate.h" #include "llbutton.h" #include "llfocusmgr.h" @@ -212,7 +213,7 @@ LLNotifyBox::LLNotifyBox(LLPointer xml_template, const LLSt // initialize mIsTip = xml_template->mIsTip; - mIsFocusRoot = !mIsTip; + setFocusRoot(!mIsTip); // caution flag can be set explicitly by specifying it in the // call to the c'tor, or it can be set implicitly if the @@ -241,7 +242,7 @@ LLNotifyBox::LLNotifyBox(LLPointer xml_template, const LLSt LLIconCtrl* icon; LLTextEditor* text; - const S32 TOP = mRect.getHeight() - (mIsTip ? (S32)sFont->getLineHeight() : 32); + const S32 TOP = getRect().getHeight() - (mIsTip ? (S32)sFont->getLineHeight() : 32); const S32 BOTTOM = (S32)sFont->getLineHeight(); S32 x = HPAD + HPAD; S32 y = TOP; @@ -274,7 +275,7 @@ LLNotifyBox::LLNotifyBox(LLPointer xml_template, const LLSt S32 caution_height = ((S32)sFont->getLineHeight() * 2) + VPAD; caution_box = new LLTextBox( "caution_box", - LLRect(x, y, mRect.getWidth() - 2, caution_height), + LLRect(x, y, getRect().getWidth() - 2, caution_height), "", sFont, FALSE); @@ -303,7 +304,7 @@ LLNotifyBox::LLNotifyBox(LLPointer xml_template, const LLSt DB_INV_ITEM_NAME_BUF_SIZE; // For script dialogs: add space for title. text = new LLTextEditor("box", - LLRect(x, y, mRect.getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16), + LLRect(x, y, getRect().getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16), MAX_LENGTH, mMessage, sFont, @@ -333,7 +334,7 @@ LLNotifyBox::LLNotifyBox(LLPointer xml_template, const LLSt { LLButton* btn; btn = new LLButton("next", - LLRect(mRect.getWidth()-18, BOTTOM_PAD+16, mRect.getWidth()-2, BOTTOM_PAD+2), + LLRect(getRect().getWidth()-18, BOTTOM_PAD+16, getRect().getWidth()-2, BOTTOM_PAD+2), "notify_next.tga", "notify_next.tga", "", @@ -418,7 +419,7 @@ LLNotifyBox::~LLNotifyBox() if (mUnique) { - sOpenUniqueNotifyBoxes.erase(mName + mMessage); + sOpenUniqueNotifyBoxes.erase(getName() + mMessage); } } @@ -474,7 +475,7 @@ void LLNotifyBox::draw() glMatrixMode(GL_MODELVIEW); LLUI::pushMatrix(); - S32 height = mRect.getHeight(); + S32 height = getRect().getHeight(); F32 fraction = display_time / ANIMATION_TIME; F32 voffset = (1.f - fraction) * height; if (mIsTip) voffset *= -1.f; @@ -509,7 +510,6 @@ void LLNotifyBox::drawBackground() const LLViewerImage* imagep = gImageList.getImage(image_id, MIPMAP_FALSE, TRUE); if (imagep) { - LLGLSTexture texture_enabled; LLViewerImage::bindTexture(imagep); // set proper background color depending on whether notify box is a caution or not LLColor4 color = mIsCaution? gColors.getColor("NotifyCautionBoxColor") : gColors.getColor("NotifyBoxColor"); @@ -517,27 +517,27 @@ void LLNotifyBox::drawBackground() const { const S32 focus_width = 2; color = gColors.getColor("FloaterFocusBorderColor"); - glColor4fv(color.mV); - gl_segmented_rect_2d_tex(-focus_width, mRect.getHeight() + focus_width, - mRect.getWidth() + focus_width, -focus_width, + gGL.color4fv(color.mV); + gl_segmented_rect_2d_tex(-focus_width, getRect().getHeight() + focus_width, + getRect().getWidth() + focus_width, -focus_width, imagep->getWidth(), imagep->getHeight(), 16, mIsTip ? ROUNDED_RECT_TOP : ROUNDED_RECT_BOTTOM); color = gColors.getColor("ColorDropShadow"); - glColor4fv(color.mV); - gl_segmented_rect_2d_tex(0, mRect.getHeight(), mRect.getWidth(), 0, imagep->getWidth(), imagep->getHeight(), 16, mIsTip ? ROUNDED_RECT_TOP : ROUNDED_RECT_BOTTOM); + gGL.color4fv(color.mV); + gl_segmented_rect_2d_tex(0, getRect().getHeight(), getRect().getWidth(), 0, imagep->getWidth(), imagep->getHeight(), 16, mIsTip ? ROUNDED_RECT_TOP : ROUNDED_RECT_BOTTOM); if( mIsCaution ) color = gColors.getColor("NotifyCautionBoxColor"); else color = gColors.getColor("NotifyBoxColor"); - glColor4fv(color.mV); - gl_segmented_rect_2d_tex(1, mRect.getHeight()-1, mRect.getWidth()-1, 1, imagep->getWidth(), imagep->getHeight(), 16, mIsTip ? ROUNDED_RECT_TOP : ROUNDED_RECT_BOTTOM); + gGL.color4fv(color.mV); + gl_segmented_rect_2d_tex(1, getRect().getHeight()-1, getRect().getWidth()-1, 1, imagep->getWidth(), imagep->getHeight(), 16, mIsTip ? ROUNDED_RECT_TOP : ROUNDED_RECT_BOTTOM); } else { - glColor4fv(color.mV); - gl_segmented_rect_2d_tex(0, mRect.getHeight(), mRect.getWidth(), 0, imagep->getWidth(), imagep->getHeight(), 16, mIsTip ? ROUNDED_RECT_TOP : ROUNDED_RECT_BOTTOM); + gGL.color4fv(color.mV); + gl_segmented_rect_2d_tex(0, getRect().getHeight(), getRect().getWidth(), 0, imagep->getWidth(), imagep->getHeight(), 16, mIsTip ? ROUNDED_RECT_TOP : ROUNDED_RECT_BOTTOM); } } } @@ -561,9 +561,9 @@ void LLNotifyBox::close() gNotifyBoxView->showOnly(front); // we're assuming that close is only called by user action (for non-tips), // so we then give focus to the next close button - if (front->mDefaultBtn) + if (front->getDefaultButton()) { - front->mDefaultBtn->setFocus(TRUE); + front->getDefaultButton()->setFocus(TRUE); } gFocusMgr.triggerFocusFlash(); // TODO it's ugly to call this here } @@ -619,7 +619,10 @@ void LLNotifyBox::moveToBack(bool getfocus) { // if are called from a user interaction // we give focus to the next next button - front->mNextBtn->setFocus(TRUE); + if (front->mNextBtn != NULL) + { + front->mNextBtn->setFocus(TRUE); + } gFocusMgr.triggerFocusFlash(); // TODO: it's ugly to call this here } } @@ -1002,3 +1005,20 @@ void LLNotifyBoxView::showOnly(LLView * view) sendChildToFront(shown); } } + +void LLNotifyBoxView::purgeMessagesMatching(const Matcher& matcher) +{ + // Make a *copy* of the child list to iterate over + // since we'll be removing items from the real list as we go. + LLView::child_list_t notification_queue(*getChildList()); + for(LLView::child_list_iter_t iter = notification_queue.begin(); + iter != notification_queue.end(); + iter++) + { + LLNotifyBox* notification = (LLNotifyBox*)*iter; + if(matcher.matches(notification->getNotifyCallback(), notification->getUserData())) + { + removeChild(notification); + } + } +} diff --git a/linden/indra/newview/llnotify.h b/linden/indra/newview/llnotify.h index 3084143..9421a5b 100644 --- a/linden/indra/newview/llnotify.h +++ b/linden/indra/newview/llnotify.h @@ -170,6 +170,17 @@ public: virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_VIEW; }; virtual LLString getWidgetTag() const { return LLString(); } + + class Matcher + { + public: + Matcher(){} + virtual ~Matcher() {} + virtual BOOL matches(LLNotifyBox::notify_callback_t callback, void* cb_data) const = 0; + }; + // Walks the list and removes any stacked messages for which the given matcher returns TRUE. + // Useful when muting people and things in order to clear out any similar previously queued messages. + void purgeMessagesMatching(const Matcher& matcher); }; // This view contains the stack of notification windows. diff --git a/linden/indra/newview/lloverlaybar.cpp b/linden/indra/newview/lloverlaybar.cpp index e24cbc7..0366e75 100644 --- a/linden/indra/newview/lloverlaybar.cpp +++ b/linden/indra/newview/lloverlaybar.cpp @@ -37,12 +37,12 @@ #include "lloverlaybar.h" #include "audioengine.h" +#include "llglimmediate.h" #include "llagent.h" #include "llbutton.h" #include "llchatbar.h" #include "llfocusmgr.h" #include "llimview.h" -#include "llmediaengine.h" #include "llmediaremotectrl.h" #include "llpanelaudiovolume.h" #include "llparcel.h" @@ -50,7 +50,10 @@ #include "llui.h" #include "llviewercontrol.h" #include "llviewerimagelist.h" +#include "llviewermedia.h" #include "llviewermenu.h" // handle_reset_view() +#include "llviewermedia.h" +#include "llviewerparcelmedia.h" #include "llviewerparcelmgr.h" #include "llvieweruictrlfactory.h" #include "llviewerwindow.h" @@ -97,7 +100,6 @@ LLOverlayBar::LLOverlayBar() : LLPanel(), mMediaRemote(NULL), mVoiceRemote(NULL), - mMediaState(STOPPED), mMusicState(STOPPED) { setMouseOpaque(FALSE); @@ -122,7 +124,7 @@ BOOL LLOverlayBar::postBuild() childSetAction("Stand Up",onClickStandUp,this); childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible")); - mIsFocusRoot = TRUE; + setFocusRoot(TRUE); mBuilt = true; layoutButtons(); @@ -219,7 +221,7 @@ void LLOverlayBar::refresh() BOOL controls_grabbed = gAgent.anyControlGrabbed(); button = LLUICtrlFactory::getButtonByName(this, "Release Keys"); - + if (button && button->getVisible() != controls_grabbed) { button->setVisible(controls_grabbed); @@ -230,7 +232,7 @@ void LLOverlayBar::refresh() BOOL mouselook_grabbed; mouselook_grabbed = gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX) - || gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX); + || gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX); button = LLUICtrlFactory::getButtonByName(this, "Mouselook"); if (button && button->getVisible() != mouselook_grabbed) @@ -256,7 +258,6 @@ void LLOverlayBar::refresh() buttons_changed = TRUE; } - enableMediaButtons(); moveChildToBackOfTabGroup(mMediaRemote); moveChildToBackOfTabGroup(mVoiceRemote); @@ -330,7 +331,15 @@ void LLOverlayBar::onClickStandUp(void*) //////////////////////////////////////////////////////////////////////////////// // static media helpers // *TODO: Move this into an audio manager abstraction - +//static +void LLOverlayBar::mediaStop(void*) +{ + if (!gOverlayBar) + { + return; + } + LLViewerParcelMedia::stop(); +} //static void LLOverlayBar::toggleMediaPlay(void*) { @@ -339,24 +348,23 @@ void LLOverlayBar::toggleMediaPlay(void*) return; } - if (gOverlayBar->mMediaState != PLAYING) + + if (LLViewerMedia::isMediaPaused()) + { + LLViewerParcelMedia::start(); + } + else if(LLViewerMedia::isMediaPlaying()) + { + LLViewerParcelMedia::pause(); + } + else { - gOverlayBar->mMediaState = PLAYING; // desired state LLParcel* parcel = gParcelMgr->getAgentParcel(); if (parcel) { - LLString path(""); - LLMediaEngine::getInstance()->convertImageAndLoadUrl( true, false, path ); + LLViewerParcelMedia::play(parcel); } } - else - { - gOverlayBar->mMediaState = PAUSED; // desired state - LLMediaEngine::getInstance()->pause(); - } - - //gOverlayBar->mMediaState = STOPPED; // desired state - //LLMediaEngine::getInstance()->stop(); } //static @@ -402,39 +410,3 @@ void LLOverlayBar::toggleMusicPlay(void*) } } -void LLOverlayBar::enableMediaButtons() -{ - if (mMediaRemote) - { - // Music - LLParcel* parcel = gParcelMgr->getAgentParcel(); - if (parcel - && gAudiop - && !parcel->getMusicURL().empty() - && gSavedSettings.getBOOL("AudioStreamingMusic")) - { - mMediaRemote->childSetEnabled("music_play", TRUE); - } - else - { - mMediaRemote->childSetEnabled("music_play", FALSE); - } - - // Media - // if there is a url and a texture and media is enabled and available and media streaming is on... (phew!) - if (LLMediaEngine::getInstance() - && LLMediaEngine::getInstance()->getUrl ().length () - && LLMediaEngine::getInstance()->getImageUUID ().notNull () - && LLMediaEngine::getInstance()->isEnabled () - && LLMediaEngine::getInstance()->isAvailable () - && gSavedSettings.getBOOL ( "AudioStreamingVideo" ) ) - { - mMediaRemote->childSetEnabled("media_play", TRUE); - } - else - { - mMediaRemote->childSetEnabled("media_play", FALSE); - } - } -} - diff --git a/linden/indra/newview/lloverlaybar.h b/linden/indra/newview/lloverlaybar.h index c4bf2cf..136c4e7 100644 --- a/linden/indra/newview/lloverlaybar.h +++ b/linden/indra/newview/lloverlaybar.h @@ -67,7 +67,6 @@ public: void layoutButtons(); // helpers for returning desired state - BOOL mediaPlaying() { return mMediaState == PLAYING; } BOOL musicPlaying() { return mMusicState == PLAYING; } static void onClickIMReceived(void* data); @@ -80,6 +79,11 @@ public: //static media helper functions static void toggleMediaPlay(void*); static void toggleMusicPlay(void*); + static void musicPause(void*); + static void musicStop(void*); + static void mediaStop(void*); + + static void toggleAudioVolumeFloater(void*); protected: static void* createMediaRemote(void* userdata); @@ -93,8 +97,7 @@ protected: LLVoiceRemoteCtrl* mVoiceRemote; bool mBuilt; // dialog constructed yet? enum { STOPPED=0, PLAYING=1, PAUSED=2 }; - BOOL mMediaState; - BOOL mMusicState; + S32 mMusicState; }; extern LLOverlayBar* gOverlayBar; diff --git a/linden/indra/newview/llpanelaudioprefs.cpp b/linden/indra/newview/llpanelaudioprefs.cpp index cf1c749..606eeb9 100644 --- a/linden/indra/newview/llpanelaudioprefs.cpp +++ b/linden/indra/newview/llpanelaudioprefs.cpp @@ -46,7 +46,6 @@ #include "llcheckboxctrl.h" #include "llcombobox.h" #include "llfirstuse.h" -#include "llmediaengine.h" #include "llnotify.h" #include "llpanelaudiovolume.h" #include "llparcel.h" diff --git a/linden/indra/newview/llpanelaudiovolume.cpp b/linden/indra/newview/llpanelaudiovolume.cpp index 522f73f..0464814 100644 --- a/linden/indra/newview/llpanelaudiovolume.cpp +++ b/linden/indra/newview/llpanelaudiovolume.cpp @@ -119,3 +119,4 @@ void LLPanelAudioVolume::onCommitVolumeChange(LLUICtrl* ctrl, void* user_data) } } + diff --git a/linden/indra/newview/llpanelaudiovolume.h b/linden/indra/newview/llpanelaudiovolume.h index d7ddb1f..0a2dbca 100644 --- a/linden/indra/newview/llpanelaudiovolume.h +++ b/linden/indra/newview/llpanelaudiovolume.h @@ -35,7 +35,6 @@ #include "llpanel.h" #include "llfloater.h" - class LLPanelAudioVolume : public LLPanel { public: diff --git a/linden/indra/newview/llpanelavatar.cpp b/linden/indra/newview/llpanelavatar.cpp index 664c9a6..5d32f4b 100644 --- a/linden/indra/newview/llpanelavatar.cpp +++ b/linden/indra/newview/llpanelavatar.cpp @@ -159,7 +159,7 @@ BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, { // check if inside //LLRect parent_rect = mParentView->getRect(); - //mRect.set(0, parent_rect.getHeight(), parent_rect.getWidth(), 0); + //getRect().set(0, parent_rect.getHeight(), parent_rect.getWidth(), 0); handled = TRUE; // check the type @@ -282,13 +282,12 @@ void LLPanelAvatarSecondLife::updatePartnerName() { if (mPartnerID.notNull()) { - char first[128]; /*Flawfinder: ignore*/ - char last[128]; /*Flawfinder: ignore*/ + std::string first, last; BOOL found = gCacheName->getName(mPartnerID, first, last); if (found) { - childSetTextArg("partner_edit", "[FIRST]", LLString(first)); - childSetTextArg("partner_edit", "[LAST]", LLString(last)); + childSetTextArg("partner_edit", "[FIRST]", first); + childSetTextArg("partner_edit", "[LAST]", last); } childSetEnabled("partner_info", TRUE); } @@ -301,7 +300,7 @@ void LLPanelAvatarSecondLife::updatePartnerName() //----------------------------------------------------------------------------- void LLPanelAvatarSecondLife::clearControls() { - LLTextureCtrl* image_ctrl = LLUICtrlFactory::getTexturePickerByName(this,"img"); + LLTextureCtrl* image_ctrl = getChild("img"); if(image_ctrl) { image_ctrl->setImageAssetID(LLUUID::null); @@ -495,15 +494,13 @@ BOOL LLPanelAvatarWeb::postBuild(void) childSetControlName("auto_load","AutoLoadWebProfiles"); -#if LL_LIBXUL_ENABLED - mWebBrowser = (LLWebBrowserCtrl*)getChildByName("profile_html"); + mWebBrowser = getChild("profile_html"); // links open in internally mWebBrowser->setOpenInExternalBrowser( false ); // observe browser events mWebBrowser->addObserver( this ); -#endif // LL_LIBXUL_ENABLED return TRUE; } @@ -563,13 +560,11 @@ LLPanelAvatarWeb::LLPanelAvatarWeb(const std::string& name, const LLRect& rect, LLPanelAvatarWeb::~LLPanelAvatarWeb() { -#if LL_LIBXUL_ENABLED // stop observing browser events if ( mWebBrowser ) { mWebBrowser->remObserver( this ); }; -#endif } void LLPanelAvatarWeb::enableControls(BOOL self) @@ -610,12 +605,6 @@ void LLPanelAvatarWeb::setWebURL(std::string url) BOOL own_avatar = (getPanelAvatar()->getAvatarID() == gAgent.getID() ); childSetVisible("status_text",!own_avatar && !mURL.empty()); -#if !LL_LIBXUL_ENABLED - childSetVisible("load",false); - childSetVisible("profile_html",false); - childSetVisible("status_text",false); -#endif - } // static @@ -631,18 +620,13 @@ void LLPanelAvatarWeb::onCommitURL(LLUICtrl* ctrl, void* data) // static void LLPanelAvatarWeb::onClickWebProfileHelp(void *) { -#if LL_LIBXUL_ENABLED gViewerWindow->alertXml("ClickWebProfileHelpAvatar"); -#else - gViewerWindow->alertXml("ClickWebProfileNoWebHelpAvatar"); -#endif } void LLPanelAvatarWeb::load(std::string url) { bool have_url = (!url.empty()); -#if LL_LIBXUL_ENABLED if (have_url) { llinfos << "Loading " << url << llendl; @@ -662,9 +646,6 @@ void LLPanelAvatarWeb::load(std::string url) childSetEnabled("home",use_home); childSetEnabled("open",have_url); -#else - childSetEnabled("open",have_url); -#endif } void LLPanelAvatarWeb::load() @@ -696,7 +677,6 @@ void LLPanelAvatarWeb::onClickOpen(void* data) } } -#if LL_LIBXUL_ENABLED void LLPanelAvatarWeb::onStatusTextChange( const EventType& eventIn ) { childSetText("status_text", eventIn.getStringValue() ); @@ -706,7 +686,6 @@ void LLPanelAvatarWeb::onLocationChange( const EventType& eventIn ) { childSetText("url_edit", eventIn.getStringValue() ); } -#endif //----------------------------------------------------------------------------- @@ -746,7 +725,7 @@ void LLPanelAvatarAdvanced::enableControls(BOOL self) // setEnable is called, for some reason if (mWantToEdit) mWantToEdit->setReadOnlyBgColor(LLColor4::transparent); if (mSkillsEdit) mSkillsEdit->setReadOnlyBgColor(LLColor4::transparent); - LLLineEditor* languages_edit = (LLLineEditor*)getChildByName("languages_edit"); + LLLineEditor* languages_edit = getChild("languages_edit"); languages_edit->setReadOnlyBgColor(LLColor4::transparent); } } @@ -822,7 +801,7 @@ void LLPanelAvatarNotes::refresh() void LLPanelAvatarNotes::clearControls() { - childSetText("notes edit", childGetText("Loading")); + childSetText("notes edit", getString("Loading")); childSetEnabled("notes edit", false); } @@ -849,7 +828,7 @@ void LLPanelAvatarClassified::refresh() { BOOL self = (gAgent.getID() == getPanelAvatar()->getAvatarID()); - LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName(this,"classified tab"); + LLTabContainer* tabs = LLUICtrlFactory::getTabContainerByName(this,"classified tab"); S32 tab_count = tabs ? tabs->getTabCount() : 0; @@ -883,7 +862,7 @@ void LLPanelAvatarClassified::refresh() BOOL LLPanelAvatarClassified::canClose() { - LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(this, "classified tab"); + LLTabContainer* tabs = LLViewerUICtrlFactory::getTabContainerByName(this, "classified tab"); for (S32 i = 0; i < tabs->getTabCount(); i++) { LLPanelClassified* panel = (LLPanelClassified*)tabs->getPanelByIndex(i); @@ -897,7 +876,7 @@ BOOL LLPanelAvatarClassified::canClose() BOOL LLPanelAvatarClassified::titleIsValid() { - LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(this, "classified tab"); + LLTabContainer* tabs = LLViewerUICtrlFactory::getTabContainerByName(this, "classified tab"); if ( tabs ) { LLPanelClassified* panel = (LLPanelClassified*)tabs->getCurrentPanel(); @@ -915,7 +894,7 @@ BOOL LLPanelAvatarClassified::titleIsValid() void LLPanelAvatarClassified::apply() { - LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(this, "classified tab"); + LLTabContainer* tabs = LLViewerUICtrlFactory::getTabContainerByName(this, "classified tab"); for (S32 i = 0; i < tabs->getTabCount(); i++) { LLPanelClassified* panel = (LLPanelClassified*)tabs->getPanelByIndex(i); @@ -926,7 +905,7 @@ void LLPanelAvatarClassified::apply() void LLPanelAvatarClassified::deleteClassifiedPanels() { - LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(this,"classified tab"); + LLTabContainer* tabs = LLViewerUICtrlFactory::getTabContainerByName(this,"classified tab"); if (tabs) { tabs->deleteAllTabs(); @@ -946,7 +925,7 @@ void LLPanelAvatarClassified::processAvatarClassifiedReply(LLMessageSystem* msg, char classified_name[DB_PICK_NAME_SIZE]; /*Flawfinder: ignore*/ LLPanelClassified* panel_classified = NULL; - LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(this,"classified tab"); + LLTabContainer* tabs = LLViewerUICtrlFactory::getTabContainerByName(this,"classified tab"); // Don't remove old panels. We need to be able to process multiple // packets for people who have lots of classifieds. JC @@ -957,7 +936,7 @@ void LLPanelAvatarClassified::processAvatarClassifiedReply(LLMessageSystem* msg, msg->getUUIDFast(_PREHASH_Data, _PREHASH_ClassifiedID, classified_id, block); msg->getStringFast(_PREHASH_Data, _PREHASH_Name, DB_PICK_NAME_SIZE, classified_name, block); - panel_classified = new LLPanelClassified(FALSE); + panel_classified = new LLPanelClassified(false, false); panel_classified->setClassifiedID(classified_id); @@ -1002,9 +981,9 @@ void LLPanelAvatarClassified::callbackNew(S32 option, void* data) if (0 == option) { - LLPanelClassified* panel_classified = new LLPanelClassified(FALSE); + LLPanelClassified* panel_classified = new LLPanelClassified(false, false); panel_classified->initNewClassified(); - LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(self,"classified tab"); + LLTabContainer* tabs = LLViewerUICtrlFactory::getTabContainerByName(self,"classified tab"); if(tabs) { tabs->addTabPanel(panel_classified, panel_classified->getClassifiedName()); @@ -1019,7 +998,7 @@ void LLPanelAvatarClassified::onClickDelete(void* data) { LLPanelAvatarClassified* self = (LLPanelAvatarClassified*)data; - LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(self,"classified tab"); + LLTabContainer* tabs = LLViewerUICtrlFactory::getTabContainerByName(self,"classified tab"); LLPanelClassified* panel_classified = NULL; if(tabs) { @@ -1038,7 +1017,7 @@ void LLPanelAvatarClassified::onClickDelete(void* data) void LLPanelAvatarClassified::callbackDelete(S32 option, void* data) { LLPanelAvatarClassified* self = (LLPanelAvatarClassified*)data; - LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(self,"classified tab"); + LLTabContainer* tabs = LLViewerUICtrlFactory::getTabContainerByName(self,"classified tab"); LLPanelClassified* panel_classified=NULL; if(tabs) { @@ -1083,14 +1062,12 @@ LLPanelAvatarPicks::LLPanelAvatarPicks(const std::string& name, void LLPanelAvatarPicks::refresh() { BOOL self = (gAgent.getID() == getPanelAvatar()->getAvatarID()); - - LLTabContainerCommon* tabs = LLViewerUICtrlFactory::getTabContainerByName(this,"picks tab"); + LLTabContainer* tabs = LLViewerUICtrlFactory::getTabContainerByName(this,"picks tab"); S32 tab_count = tabs ? tabs->getTabCount() : 0; - BOOL allow_new = (tab_count < MAX_AVATAR_PICKS); - BOOL allow_delete = (tab_count > 0); - - childSetEnabled("New...",self && allow_new); - childSetEnabled("Delete...",self && allow_delete); + childSetEnabled("New...", self && tab_count < MAX_AVATAR_PICKS); + childSetEnabled("Delete...", self && tab_count > 0); + childSetVisible("New...", self && getPanelAvatar()->isEditable()); + childSetVisible("Delete...", self && getPanelAvatar()->isEditable()); sendAvatarProfileRequestIfNeeded("avatarpicksrequest"); } @@ -1098,7 +1075,7 @@ void LLPanelAvatarPicks::refresh() void LLPanelAvatarPicks::deletePickPanels() { - LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName(this,"picks tab"); + LLTabContainer* tabs = LLUICtrlFactory::getTabContainerByName(this,"picks tab"); if(tabs) { tabs->deleteAllTabs(); @@ -1117,7 +1094,7 @@ void LLPanelAvatarPicks::processAvatarPicksReply(LLMessageSystem* msg, void**) char pick_name[DB_PICK_NAME_SIZE]; /*Flawfinder: ignore*/ LLPanelPick* panel_pick = NULL; - LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName(this,"picks tab"); + LLTabContainer* tabs = LLUICtrlFactory::getTabContainerByName(this,"picks tab"); // Clear out all the old panels. We'll replace them with the correct // number of new panels. @@ -1167,7 +1144,7 @@ void LLPanelAvatarPicks::onClickNew(void* data) { LLPanelAvatarPicks* self = (LLPanelAvatarPicks*)data; LLPanelPick* panel_pick = new LLPanelPick(FALSE); - LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName(self,"picks tab"); + LLTabContainer* tabs = LLUICtrlFactory::getTabContainerByName(self,"picks tab"); panel_pick->initNewPick(); if(tabs) @@ -1182,7 +1159,7 @@ void LLPanelAvatarPicks::onClickNew(void* data) void LLPanelAvatarPicks::onClickDelete(void* data) { LLPanelAvatarPicks* self = (LLPanelAvatarPicks*)data; - LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName(self,"picks tab"); + LLTabContainer* tabs = LLUICtrlFactory::getTabContainerByName(self,"picks tab"); LLPanelPick* panel_pick = tabs?(LLPanelPick*)tabs->getCurrentPanel():NULL; if (!panel_pick) return; @@ -1200,7 +1177,7 @@ void LLPanelAvatarPicks::onClickDelete(void* data) void LLPanelAvatarPicks::callbackDelete(S32 option, void* data) { LLPanelAvatarPicks* self = (LLPanelAvatarPicks*)data; - LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName(self,"picks tab"); + LLTabContainer* tabs = LLUICtrlFactory::getTabContainerByName(self,"picks tab"); LLPanelPick* panel_pick = tabs?(LLPanelPick*)tabs->getCurrentPanel():NULL; LLMessageSystem* msg = gMessageSystem; @@ -1417,7 +1394,7 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const LLString &name, // Teens don't have this. if (mPanelFirstLife) mPanelFirstLife->enableControls(own_avatar && mAllowEdit); - LLView *target_view = getChildByName("drop_target_rect", TRUE); + LLView *target_view = getChild("drop_target_rect"); if(target_view) { if (mDropTarget) @@ -1477,6 +1454,8 @@ void LLPanelAvatar::setAvatarID(const LLUUID &avatar_id, const LLString &name, { childSetVisible("OK",FALSE); childSetEnabled("OK",FALSE); + childSetVisible("Cancel",FALSE); + childSetEnabled("Cancel",FALSE); } childSetVisible("Instant Message...",FALSE); childSetEnabled("Instant Message...",FALSE); @@ -1700,7 +1679,7 @@ void LLPanelAvatar::onClickOK(void *userdata) { self->sendAvatarPropertiesUpdate(); - LLTabContainerCommon* tabs = LLUICtrlFactory::getTabContainerByName(self,"tab"); + LLTabContainer* tabs = LLUICtrlFactory::getTabContainerByName(self,"tab"); if ( tabs->getCurrentPanel() != self->mPanelClassified ) { self->mPanelClassified->apply(); @@ -1767,7 +1746,7 @@ void LLPanelAvatar::sendAvatarNotesUpdate() std::string notes = mPanelNotes->childGetValue("notes edit").asString(); if (!mHaveNotes - && (notes.empty() || notes == childGetText("Loading"))) + && (notes.empty() || notes == getString("Loading"))) { // no notes from server and no user updates return; @@ -1868,7 +1847,7 @@ void LLPanelAvatar::processAvatarPropertiesReply(LLMessageSystem *msg, void**) if(caption_text.empty()) { LLString::format_map_t args; - caption_text = self->mPanelSecondLife->childGetValue("CaptionTextAcctInfo").asString(); + caption_text = self->mPanelSecondLife->getString("CaptionTextAcctInfo"); const char* ACCT_TYPE[] = { "AcctTypeResident", @@ -1877,7 +1856,7 @@ void LLPanelAvatar::processAvatarPropertiesReply(LLMessageSystem *msg, void**) "AcctTypeEmployee" }; caption_index = llclamp(caption_index, (U8)0, (U8)(sizeof(ACCT_TYPE)/sizeof(ACCT_TYPE[0])-1)); - args["[ACCTTYPE]"] = self->mPanelSecondLife->childGetValue(ACCT_TYPE[caption_index]).asString(); + args["[ACCTTYPE]"] = self->mPanelSecondLife->getString(ACCT_TYPE[caption_index]); LLString payment_text = " "; const S32 DEFAULT_CAPTION_LINDEN_INDEX = 3; @@ -1895,10 +1874,10 @@ void LLPanelAvatar::processAvatarPropertiesReply(LLMessageSystem *msg, void**) { payment_text = "NoPaymentInfoOnFile"; } - args["[PAYMENTINFO]"] = self->mPanelSecondLife->childGetValue(payment_text).asString(); + args["[PAYMENTINFO]"] = self->mPanelSecondLife->getString(payment_text); LLString age_text = age_verified ? "AgeVerified" : "NotAgeVerified"; // Do not display age verification status at this time - //args["[AGEVERIFICATION]"] = self->mPanelSecondLife->childGetValue(age_text).asString(); + //args["[AGEVERIFICATION]"] = self->mPanelSecondLife->getString(age_text); args["[AGEVERIFICATION]"] = " "; } else @@ -1918,7 +1897,7 @@ void LLPanelAvatar::processAvatarPropertiesReply(LLMessageSystem *msg, void**) self->mPanelWeb->setWebURL(std::string(profile_url)); - LLTextureCtrl* image_ctrl = LLUICtrlFactory::getTexturePickerByName(self->mPanelSecondLife,"img"); + LLTextureCtrl* image_ctrl = self->mPanelSecondLife->getChild("img"); if(image_ctrl) { image_ctrl->setImageAssetID(image_id); @@ -1932,7 +1911,7 @@ void LLPanelAvatar::processAvatarPropertiesReply(LLMessageSystem *msg, void**) { // Teens don't get these self->mPanelFirstLife->childSetValue("about", fl_about_text); - LLTextureCtrl* image_ctrl = LLUICtrlFactory::getTexturePickerByName(self->mPanelFirstLife,"img"); + LLTextureCtrl* image_ctrl = self->mPanelFirstLife->getChild("img"); if(image_ctrl) { image_ctrl->setImageAssetID(fl_image_id); @@ -2098,7 +2077,7 @@ void LLPanelAvatar::sendAvatarPropertiesUpdate() if (mPanelFirstLife) { first_life_about_text = mPanelFirstLife->childGetValue("about").asString(); - LLTextureCtrl* image_ctrl = LLUICtrlFactory::getTexturePickerByName(mPanelFirstLife,"img"); + LLTextureCtrl* image_ctrl = mPanelFirstLife->getChild("img"); if(image_ctrl) { first_life_image_id = image_ctrl->getImageAssetID(); @@ -2115,7 +2094,7 @@ void LLPanelAvatar::sendAvatarPropertiesUpdate() msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); msg->nextBlockFast(_PREHASH_PropertiesData); - LLTextureCtrl* image_ctrl = LLUICtrlFactory::getTexturePickerByName(mPanelSecondLife,"img"); + LLTextureCtrl* image_ctrl = mPanelSecondLife->getChild("img"); if(image_ctrl) { msg->addUUIDFast( _PREHASH_ImageID, image_ctrl->getImageAssetID()); diff --git a/linden/indra/newview/llpanelavatar.h b/linden/indra/newview/llpanelavatar.h index 318b4cf..2a3d36c 100644 --- a/linden/indra/newview/llpanelavatar.h +++ b/linden/indra/newview/llpanelavatar.h @@ -35,7 +35,6 @@ #include "llpanel.h" #include "v3dmath.h" #include "lluuid.h" -#include "linked_lists.h" #include "llwebbrowserctrl.h" class LLButton; @@ -46,7 +45,7 @@ class LLLineEditor; class LLNameEditor; class LLPanelAvatar; class LLScrollListCtrl; -class LLTabContainerCommon; +class LLTabContainer; class LLTextBox; class LLTextEditor; class LLTextureCtrl; @@ -137,9 +136,7 @@ private: // WARNING! The order of the inheritance here matters!! Do not change. - KLW class LLPanelAvatarWeb : public LLPanelAvatarTab -#if LL_LIBXUL_ENABLED , public LLWebBrowserCtrlObserver -#endif { public: LLPanelAvatarWeb(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar); @@ -157,11 +154,9 @@ public: static void onCommitURL(LLUICtrl* ctrl, void* data); static void onClickWebProfileHelp(void *); -#if LL_LIBXUL_ENABLED // browser observer impls virtual void onStatusTextChange( const EventType& eventIn ); virtual void onLocationChange( const EventType& eventIn ); -#endif private: std::string mURL; @@ -306,6 +301,7 @@ public: void selectTabByName(std::string tab_name); BOOL haveData() { return mHaveProperties && mHaveStatistics; } + BOOL isEditable() const { return mAllowEdit; } static void processAvatarPropertiesReply(LLMessageSystem *msg, void **); static void processAvatarInterestsReply(LLMessageSystem *msg, void **); @@ -370,7 +366,7 @@ private: // note is changed from database version bool mHaveNotes; std::string mLastNotes; - LLTabContainerCommon* mTab; + LLTabContainer* mTab; BOOL mAllowEdit; typedef std::list panel_list_t; diff --git a/linden/indra/newview/llpanelclassified.cpp b/linden/indra/newview/llpanelclassified.cpp index e8d6b0d..7b9c3f8 100644 --- a/linden/indra/newview/llpanelclassified.cpp +++ b/linden/indra/newview/llpanelclassified.cpp @@ -104,6 +104,9 @@ public: static LLDispatchClassifiedClickThrough sClassifiedClickThrough; +/* Re-expose this if we need to have classified ad HTML detail + pages. JC + // We need to count classified teleport clicks from the search HTML detail pages, // so we need have a teleport that also sends a click count message. class LLClassifiedTeleportHandler : public LLCommandHandler @@ -139,9 +142,9 @@ public: }; // Creating the object registers with the dispatcher. LLClassifiedTeleportHandler gClassifiedTeleportHandler; +*/ - -LLPanelClassified::LLPanelClassified(BOOL in_finder, bool from_search) +LLPanelClassified::LLPanelClassified(bool in_finder, bool from_search) : LLPanel("Classified Panel"), mInFinder(in_finder), mFromSearch(from_search), @@ -238,7 +241,7 @@ BOOL LLPanelClassified::postBuild() mDescEditor->setFocusReceivedCallback(onFocusReceived, this); mDescEditor->setCommitCallback(onCommitAny); mDescEditor->setCallbackUserData(this); - mDescEditor->setTabToNextField(TRUE); + mDescEditor->setTabsToNextField(TRUE); mLocationEditor = LLViewerUICtrlFactory::getLineEditorByName(this, "location_editor"); @@ -400,13 +403,7 @@ void LLPanelClassified::initNewClassified() mCategoryCombo->setCurrentByIndex(0); } - // default new classifieds to publish - //mEnabledCheck->set(TRUE); - - // delay commit until user hits save - // sendClassifiedInfoUpdate(); - - mUpdateBtn->setLabel(childGetText("publish_txt")); + mUpdateBtn->setLabel(getString("publish_txt")); } @@ -499,7 +496,7 @@ void LLPanelClassified::sendClassifiedInfoRequest() if (!url.empty()) { llinfos << "Classified stat request via capability" << llendl; - LLHTTPClient::post(url, body, new LLClassifiedStatsResponder(this->getHandle(), mClassifiedID)); + LLHTTPClient::post(url, body, new LLClassifiedStatsResponder(((LLView*)this)->getHandle(), mClassifiedID)); } } } @@ -536,8 +533,6 @@ void LLPanelClassified::sendClassifiedInfoUpdate() msg->addUUIDFast(_PREHASH_SnapshotID, mSnapshotCtrl->getImageAssetID()); msg->addVector3dFast(_PREHASH_PosGlobal, mPosGlobal); BOOL mature = mMatureCheck->get(); - // Classifieds are always enabled/published 11/2005 JC - //BOOL enabled = mEnabledCheck->get(); BOOL auto_renew = FALSE; if (mAutoRenewCheck) { @@ -668,14 +663,15 @@ void LLPanelClassified::processClassifiedInfoReply(LLMessageSystem *msg, void ** } LLString datestr = llformat("%02d/%02d/%d", now->tm_mon+1, now->tm_mday, now->tm_year+1900); - self->childSetTextArg("ad_placed_paid", "[DATE]", datestr); - self->childSetTextArg("ad_placed_paid", "[AMT]", llformat("%d", price_for_listing)); - self->childSetText("classified_info_text", self->childGetValue("ad_placed_paid").asString()); + LLString::format_map_t string_args; + string_args["[DATE]"] = datestr; + string_args["[AMT]"] = llformat("%d", price_for_listing); + self->childSetText("classified_info_text", self->getString("ad_placed_paid", string_args)); // If we got data from the database, we know the listing is paid for. self->mPaidFor = TRUE; - self->mUpdateBtn->setLabel(self->childGetText("update_txt")); + self->mUpdateBtn->setLabel(self->getString("update_txt")); self->resetDirty(); } @@ -726,9 +722,6 @@ void LLPanelClassified::refresh() mCategoryCombo->setEnabled(godlike); mCategoryCombo->setVisible(godlike); - //mEnabledCheck->setVisible(godlike); - //mEnabledCheck->setEnabled(godlike); - mMatureCheck->setEnabled(godlike); mMatureCheck->setVisible(godlike); @@ -749,8 +742,6 @@ void LLPanelClassified::refresh() //mPriceEditor->setEnabled(is_self); mCategoryCombo->setEnabled(is_self); - //mEnabledCheck->setVisible(FALSE); - //mEnabledCheck->setEnabled(is_self); mMatureCheck->setEnabled(is_self); if (mAutoRenewCheck) @@ -863,7 +854,7 @@ void LLPanelClassified::confirmPublish(S32 option) } else { - LLTabContainerVertical* tab = (LLTabContainerVertical*)getParent(); + LLTabContainer* tab = (LLTabContainer*)getParent(); tab->setCurrentTabName(mNameEditor->getText()); } @@ -887,7 +878,7 @@ void LLPanelClassified::onClickTeleport(void* data) gAgent.teleportViaLocation(self->mPosGlobal); gFloaterWorldMap->trackLocation(self->mPosGlobal); - sendClassifiedClickMessage(self->mClassifiedID, "teleport", self->mFromSearch); + self->sendClassifiedClickMessage("teleport"); } } @@ -899,7 +890,7 @@ void LLPanelClassified::onClickMap(void* data) gFloaterWorldMap->trackLocation(self->mPosGlobal); LLFloaterWorldMap::show(NULL, TRUE); - sendClassifiedClickMessage(self->mClassifiedID, "map", self->mFromSearch); + self->sendClassifiedClickMessage("map"); } // static @@ -907,7 +898,7 @@ void LLPanelClassified::onClickProfile(void* data) { LLPanelClassified* self = (LLPanelClassified*)data; LLFloaterAvatarInfo::showFromDirectory(self->mCreatorID); - sendClassifiedClickMessage(self->mClassifiedID, "profile", self->mFromSearch); + self->sendClassifiedClickMessage("profile"); } // static @@ -981,35 +972,21 @@ void LLPanelClassified::onFocusReceived(LLFocusableElement* ctrl, void* data) } -// static -void LLPanelClassified::sendClassifiedClickMessage(const LLUUID& classified_id, - const char* type, - bool from_search) +void LLPanelClassified::sendClassifiedClickMessage(const char* type) { // You're allowed to click on your own ads to reassure yourself // that the system is working. - std::vector strings; - strings.push_back(classified_id.asString()); - strings.push_back(type); - LLUUID no_invoice; - - // New classified click-through handling LLSD body; body["type"] = type; - body["from_search"] = from_search; - body["classified_id"] = classified_id; - std::string url = gAgent.getRegion()->getCapability("SearchStatTracking"); + body["from_search"] = mFromSearch; + body["classified_id"] = mClassifiedID; + body["parcel_id"] = mParcelID; + body["dest_pos_global"] = mPosGlobal.getValue(); + body["region_name"] = mSimName; - // If the capability exists send to the new database, otherwise send to the old one. - if (!url.empty()) - { - llinfos << "LLPanelClassified::sendClassifiedClickMessage via capability" << llendl; - LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); - } - else - { - send_generic_message("classifiedclick", strings, no_invoice); - } + std::string url = gAgent.getRegion()->getCapability("SearchStatTracking"); + llinfos << "LLPanelClassified::sendClassifiedClickMessage via capability" << llendl; + LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); } //////////////////////////////////////////////////////////////////////////////////////////// diff --git a/linden/indra/newview/llpanelclassified.h b/linden/indra/newview/llpanelclassified.h index 087aae0..ecc196a 100644 --- a/linden/indra/newview/llpanelclassified.h +++ b/linden/indra/newview/llpanelclassified.h @@ -57,7 +57,7 @@ class LLMessageSystem; class LLPanelClassified : public LLPanel { public: - LLPanelClassified(BOOL in_finder, bool from_search = false); + LLPanelClassified(bool in_finder, bool from_search); /*virtual*/ ~LLPanelClassified(); void reset(); @@ -102,7 +102,7 @@ public: static void callbackGotPriceForListing(S32 option, LLString text, void* data); static void callbackConfirmPublish(S32 option, void* data); - static void sendClassifiedClickMessage(const LLUUID& classified_id, const char* type, bool from_search); + void sendClassifiedClickMessage(const char* type); protected: static void saveCallback(S32 option, void* data); @@ -119,8 +119,8 @@ protected: BOOL checkDirty(); // Update and return mDirty protected: - BOOL mInFinder; - bool mFromSearch; + bool mInFinder; + bool mFromSearch; // from web-based "All" search sidebar BOOL mDirty; bool mForceClose; bool mLocationChanged; diff --git a/linden/indra/newview/llpaneldirbrowser.cpp b/linden/indra/newview/llpaneldirbrowser.cpp index 5d3236d..cd9e6ae 100644 --- a/linden/indra/newview/llpaneldirbrowser.cpp +++ b/linden/indra/newview/llpaneldirbrowser.cpp @@ -69,6 +69,11 @@ #include "llviewermessage.h" #include "llvieweruictrlfactory.h" +#include +#include +#include +#include + // // Globals @@ -203,7 +208,7 @@ void LLPanelDirBrowser::updateResultCount() // add none found response if (list->getItemCount() == 0) { - list->addCommentText(getFormattedUIString("not_found_text")); + list->addCommentText(getString("not_found_text")); list->operateOnAll(LLCtrlListInterface::OP_DESELECT); } } @@ -228,6 +233,44 @@ void LLPanelDirBrowser::onClickNext(void* data) self->nextPage(); } +// static +const std::string LLPanelDirBrowser::filter_short_words( const std::string source_string, + int shortest_word_length, + bool& was_filtered ) +{ + // degenerate case + if ( source_string.length() < 1 ) + return ""; + + std::stringstream codec( source_string ); + std::string each_word; + std::vector< std::string > all_words; + + while( codec >> each_word ) + all_words.push_back( each_word ); + + std::ostringstream dest_string( "" ); + + was_filtered = false; + + std::vector< std::string >::iterator iter = all_words.begin(); + while( iter != all_words.end() ) + { + if ( (int)(*iter).length() >= shortest_word_length ) + { + dest_string << *iter; + dest_string << " "; + } + else + { + was_filtered = true; + } + + ++iter; + }; + + return dest_string.str(); +} void LLPanelDirBrowser::selectByUUID(const LLUUID& id) { @@ -1170,7 +1213,7 @@ void LLPanelDirBrowser::setupNewSearch() // ready the list for results list->operateOnAll(LLCtrlListInterface::OP_DELETE); - list->addCommentText(getFormattedUIString("searching_text")); + list->addCommentText(getString("searching_text")); childDisable("results"); mResultsReceived = 0; diff --git a/linden/indra/newview/llpaneldirbrowser.h b/linden/indra/newview/llpaneldirbrowser.h index 6b8578f..23df195 100644 --- a/linden/indra/newview/llpaneldirbrowser.h +++ b/linden/indra/newview/llpaneldirbrowser.h @@ -121,6 +121,8 @@ public: static void processDirPopularReply(LLMessageSystem* msg, void**); static void processDirLandReply(LLMessageSystem *msg, void**); + const std::string filter_short_words( const std::string source_string, int shortest_word_length, bool& was_filtered ); + protected: void updateResultCount(); diff --git a/linden/indra/newview/llpaneldirfind.cpp b/linden/indra/newview/llpaneldirfind.cpp index b3d1580..5d34d47 100644 --- a/linden/indra/newview/llpaneldirfind.cpp +++ b/linden/indra/newview/llpaneldirfind.cpp @@ -98,17 +98,13 @@ private: // Debugging info to console private: -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* mWebBrowser; -#endif // LL_LIBXUL_ENABLED }; LLPanelDirFindAll::LLPanelDirFindAll(const std::string& name, LLFloaterDirectory* floater) : LLPanelDirBrowser(name, floater) -#if LL_LIBXUL_ENABLED ,mWebBrowser(NULL) -#endif // LL_LIBXUL_ENABLED { mMinSearchChars = 3; } @@ -129,7 +125,6 @@ BOOL LLPanelDirFindAll::postBuild() childSetValue("mature_check", false); } -#if LL_LIBXUL_ENABLED mWebBrowser = LLViewerUICtrlFactory::getWebBrowserByName(this, "find_browser"); if (mWebBrowser) { @@ -141,30 +136,27 @@ BOOL LLPanelDirFindAll::postBuild() mWebBrowser->setOpenAppSLURLs( true ); // redirect 404 pages from S3 somewhere else - mWebBrowser->set404RedirectUrl( childGetText("redirect_404_url") ); - + mWebBrowser->set404RedirectUrl( getString("redirect_404_url") ); + // Track updates for progress display. mWebBrowser->addObserver(this); navigateToDefaultPage(); } -#endif // LL_LIBXUL_ENABLED return TRUE; } LLPanelDirFindAll::~LLPanelDirFindAll() { -#if LL_LIBXUL_ENABLED - if (mWebBrowser) mWebBrowser->remObserver(this); -#endif // LL_LIBXUL_ENABLED + if (mWebBrowser) + mWebBrowser->remObserver(this); } // virtual void LLPanelDirFindAll::draw() { // enable/disable buttons depending on state -#if LL_LIBXUL_ENABLED if ( mWebBrowser ) { bool enable_back = mWebBrowser->canNavigateBack(); @@ -173,7 +165,6 @@ void LLPanelDirFindAll::draw() bool enable_forward = mWebBrowser->canNavigateForward(); childSetEnabled( "forward_btn", enable_forward ); } -#endif // LL_LIBXUL_ENABLED LLPanelDirBrowser::draw(); } @@ -218,12 +209,10 @@ void LLPanelDirFindAll::search(const std::string& search_text) llinfos << "url " << url << llendl; -#if LL_LIBXUL_ENABLED if (mWebBrowser) { mWebBrowser->navigateTo(url); } -#endif // LL_LIBXUL_ENABLED } else { @@ -247,12 +236,10 @@ void LLPanelDirFindAll::navigateToDefaultPage() llinfos << "default url: " << start_url << llendl; -#if LL_LIBXUL_ENABLED if (mWebBrowser) { mWebBrowser->navigateTo( start_url ); } -#endif //LL_LIBXUL_ENABLED } // static @@ -317,37 +304,31 @@ std::string LLPanelDirFindAll::getSearchURLSuffix(bool mature_in) // static void LLPanelDirFindAll::onClickBack( void* data ) { -#if LL_LIBXUL_ENABLED LLPanelDirFindAll* self = ( LLPanelDirFindAll* )data; if ( self->mWebBrowser ) { self->mWebBrowser->navigateBack(); } -#endif // LL_LIBXUL_ENABLED } // static void LLPanelDirFindAll::onClickForward( void* data ) { -#if LL_LIBXUL_ENABLED LLPanelDirFindAll* self = ( LLPanelDirFindAll* )data; if ( self->mWebBrowser ) { self->mWebBrowser->navigateForward(); } -#endif // LL_LIBXUL_ENABLED } // static void LLPanelDirFindAll::onClickHome( void* data ) { -#if LL_LIBXUL_ENABLED LLPanelDirFindAll* self = ( LLPanelDirFindAll* )data; if ( self->mWebBrowser ) { self->mWebBrowser->navigateHome(); } -#endif // LL_LIBXUL_ENABLED } // static @@ -368,12 +349,12 @@ void LLPanelDirFindAll::onClickSearch(void* data) void LLPanelDirFindAll::onNavigateBegin( const EventType& eventIn ) { - childSetText("status_text", childGetText("loading_text")); + childSetText("status_text", getString("loading_text")); } void LLPanelDirFindAll::onNavigateComplete( const EventType& eventIn ) { - childSetText("status_text", childGetText("done_text")); + childSetText("status_text", getString("done_text")); } void LLPanelDirFindAll::onLocationChange( const EventType& eventIn ) diff --git a/linden/indra/newview/llpaneldirgroups.cpp b/linden/indra/newview/llpaneldirgroups.cpp index 777908d..ab2ec38 100644 --- a/linden/indra/newview/llpaneldirgroups.cpp +++ b/linden/indra/newview/llpaneldirgroups.cpp @@ -39,6 +39,7 @@ #include "message.h" #include "llqueryflags.h" #include "llviewercontrol.h" +#include "llviewerwindow.h" // viewer project includes @@ -86,6 +87,29 @@ void LLPanelDirGroups::performQuery() return; } + // filter short words out of the query string + // and indidate if we did have to filter it + bool query_was_filtered = false; + std::string query_string = LLPanelDirBrowser::filter_short_words( + childGetValue("name").asString(), + mMinSearchChars, + query_was_filtered ); + + // possible we threw away all the short words in the query so check length + if ( query_string.length() < mMinSearchChars ) + { + gViewerWindow->alertXml("SeachFilteredOnShortWordsEmpty"); + return; + }; + + // if we filtered something out, display a popup + if ( query_was_filtered ) + { + LLString::format_map_t args; + args["[FINALQUERY]"] = query_string; + gViewerWindow->alertXml("SeachFilteredOnShortWords"); + }; + setupNewSearch(); // groups @@ -105,7 +129,7 @@ void LLPanelDirGroups::performQuery() sendDirFindQuery( gMessageSystem, mSearchID, - childGetValue("name").asString(), + query_string, scope, mSearchStart); } diff --git a/linden/indra/newview/llpaneldirland.cpp b/linden/indra/newview/llpaneldirland.cpp index d376ccf..6e8af5f 100644 --- a/linden/indra/newview/llpaneldirland.cpp +++ b/linden/indra/newview/llpaneldirland.cpp @@ -96,7 +96,7 @@ BOOL LLPanelDirLand::postBuild() mCurrentSortColumn = "per_meter"; - LLScrollListCtrl* results = (LLScrollListCtrl*)getChildByName("results"); + LLScrollListCtrl* results = getChild("results"); if (results) { results->setSortChangedCallback(onClickSort); @@ -168,7 +168,7 @@ void LLPanelDirLand::performQuery() query_flags |= DFQ_MATURE_SIMS_ONLY; } - LLScrollListCtrl* list = (LLScrollListCtrl*)getChildByName("results"); + LLScrollListCtrl* list = getChild("results"); if (list) { std::string sort_name = list->getSortColumnName(); diff --git a/linden/indra/newview/llpaneldirpeople.cpp b/linden/indra/newview/llpaneldirpeople.cpp index bca502a..64cde2d 100644 --- a/linden/indra/newview/llpaneldirpeople.cpp +++ b/linden/indra/newview/llpaneldirpeople.cpp @@ -32,6 +32,7 @@ #include "llviewerprecompiledheaders.h" #include "llpaneldirpeople.h" +#include "llviewerwindow.h" // linden library includes #include "message.h" @@ -72,6 +73,29 @@ void LLPanelDirPeople::performQuery() return; } + // filter short words out of the query string + // and indidate if we did have to filter it + bool query_was_filtered = false; + std::string query_string = LLPanelDirBrowser::filter_short_words( + childGetValue("name").asString(), + mMinSearchChars, + query_was_filtered ); + + // possible we threw away all the short words in the query so check length + if ( query_string.length() < mMinSearchChars ) + { + gViewerWindow->alertXml("SeachFilteredOnShortWordsEmpty"); + return; + }; + + // if we filtered something out, display a popup + if ( query_was_filtered ) + { + LLString::format_map_t args; + args["[FINALQUERY]"] = query_string; + gViewerWindow->alertXml("SeachFilteredOnShortWords"); + }; + setupNewSearch(); U32 scope = DFQ_PEOPLE; @@ -80,7 +104,7 @@ void LLPanelDirPeople::performQuery() sendDirFindQuery( gMessageSystem, mSearchID, - childGetValue("name").asString(), + query_string, scope, mSearchStart); } diff --git a/linden/indra/newview/llpaneldirplaces.cpp b/linden/indra/newview/llpaneldirplaces.cpp index ebeca07..9a761c4 100644 --- a/linden/indra/newview/llpaneldirplaces.cpp +++ b/linden/indra/newview/llpaneldirplaces.cpp @@ -48,6 +48,7 @@ #include "llcombobox.h" #include "llfloaterdirectory.h" #include "lllineeditor.h" +#include "llviewerwindow.h" #include "llpaneldirbrowser.h" #include "lltextbox.h" #include "lluiconstants.h" @@ -104,6 +105,29 @@ void LLPanelDirPlaces::performQuery() return; } + // filter short words out of the query string + // and indidate if we did have to filter it + bool query_was_filtered = false; + std::string query_string = LLPanelDirBrowser::filter_short_words( + name, + mMinSearchChars, + query_was_filtered ); + + // possible we threw away all the short words in the query so check length + if ( query_string.length() < mMinSearchChars ) + { + gViewerWindow->alertXml("SeachFilteredOnShortWordsEmpty"); + return; + }; + + // if we filtered something out, display a popup + if ( query_was_filtered ) + { + LLString::format_map_t args; + args["[FINALQUERY]"] = query_string; + gViewerWindow->alertXml("SeachFilteredOnShortWords"); + }; + LLString catstring = childGetValue("Category").asString(); // Because LLParcel::C_ANY is -1, must do special check @@ -120,7 +144,7 @@ void LLPanelDirPlaces::performQuery() BOOL pg_only = !gSavedSettings.getBOOL("ShowMatureSims") || gAgent.isTeen(); - queryCore(name, category, pg_only); + queryCore(query_string, category, pg_only); } void LLPanelDirPlaces::initialQuery() diff --git a/linden/indra/newview/llpaneldisplay.cpp b/linden/indra/newview/llpaneldisplay.cpp index 81b173a..5bc1f7e 100644 --- a/linden/indra/newview/llpaneldisplay.cpp +++ b/linden/indra/newview/llpaneldisplay.cpp @@ -45,7 +45,6 @@ #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcombobox.h" -#include "lldrawpoolterrain.h" #include "llflexibleobject.h" #include "lllineeditor.h" #include "llradiogroup.h" @@ -71,18 +70,22 @@ #include "llvieweruictrlfactory.h" #include "llfeaturemanager.h" #include "llglslshader.h" +#include "llfloaterhardwaresettings.h" +#include "llboost.h" //RN temporary includes for resolution switching #include "llglheaders.h" #include "llviewercontrol.h" #include "llsky.h" +// parent +#include "llfloaterpreference.h" + const F32 MAX_USER_FAR_CLIP = 512.f; const F32 MIN_USER_FAR_CLIP = 64.f; const S32 ASPECT_RATIO_STR_LEN = 100; - LLPanelDisplay::LLPanelDisplay() { gUICtrlFactory->buildPanel(this, "panel_preferences_graphics1.xml"); @@ -92,20 +95,65 @@ BOOL LLPanelDisplay::postBuild() { requires("windowed mode", WIDGET_TYPE_CHECKBOX); requires("fullscreen combo", WIDGET_TYPE_COMBO_BOX); - requires("resolution_format", WIDGET_TYPE_TEXT_BOX); - requires("aspect_ratio_text", WIDGET_TYPE_TEXT_BOX); requires("aspect_ratio", WIDGET_TYPE_COMBO_BOX); requires("aspect_auto_detect", WIDGET_TYPE_CHECKBOX); - requires("UI Scale", WIDGET_TYPE_SLIDER); - requires("ui_auto_scale", WIDGET_TYPE_CHECKBOX); - requires("draw_distance", WIDGET_TYPE_SPINNER); - requires("avfp", WIDGET_TYPE_CHECKBOX); + requires("AspectRatioLabel1", WIDGET_TYPE_TEXT_BOX); + requires("DisplayResLabel", WIDGET_TYPE_TEXT_BOX); + requires("FullScreenInfo", WIDGET_TYPE_TEXT_EDITOR); + + requires("QualityPerformanceSelection", WIDGET_TYPE_SLIDER); + requires("CustomSettings", WIDGET_TYPE_CHECKBOX); + + requires("GraphicsHardwareButton", WIDGET_TYPE_BUTTON); + requires("Defaults", WIDGET_TYPE_BUTTON); + + requires("BumpShiny", WIDGET_TYPE_CHECKBOX); + requires("BasicShaders", WIDGET_TYPE_CHECKBOX); + requires("AvatarVertexProgram", WIDGET_TYPE_CHECKBOX); + requires("WindLightUseAtmosShaders", WIDGET_TYPE_CHECKBOX); + requires("Reflections", WIDGET_TYPE_CHECKBOX); + + requires("AvatarImpostors", WIDGET_TYPE_CHECKBOX); + requires("AvatarCloth", WIDGET_TYPE_CHECKBOX); + + requires("DrawDistance", WIDGET_TYPE_SLIDER); + requires("DrawDistanceMeterText1", WIDGET_TYPE_TEXT_BOX); + requires("DrawDistanceMeterText2", WIDGET_TYPE_TEXT_BOX); + + requires("ObjectMeshDetail", WIDGET_TYPE_SLIDER); + requires("FlexibleMeshDetail", WIDGET_TYPE_SLIDER); + requires("TreeMeshDetail", WIDGET_TYPE_SLIDER); + requires("AvatarMeshDetail", WIDGET_TYPE_SLIDER); + requires("TerrainMeshDetail", WIDGET_TYPE_SLIDER); + requires("SkyMeshDetail", WIDGET_TYPE_SLIDER); + requires("MaxParticleCount", WIDGET_TYPE_SLIDER); + requires("RenderPostProcess", WIDGET_TYPE_SLIDER); + + requires("ObjectMeshDetailText", WIDGET_TYPE_TEXT_BOX); + requires("FlexibleMeshDetailText", WIDGET_TYPE_TEXT_BOX); + requires("TreeMeshDetailText", WIDGET_TYPE_TEXT_BOX); + requires("AvatarMeshDetailText", WIDGET_TYPE_TEXT_BOX); + requires("TerrainMeshDetailText", WIDGET_TYPE_TEXT_BOX); + requires("SkyMeshDetailText", WIDGET_TYPE_TEXT_BOX); + requires("PostProcessText", WIDGET_TYPE_TEXT_BOX); + + requires("LightingDetailRadio", WIDGET_TYPE_RADIO_GROUP); + requires("TerrainDetailRadio", WIDGET_TYPE_RADIO_GROUP); if (!checkRequirements()) { return FALSE; } + // return to default values + childSetAction("Defaults", setHardwareDefaults, NULL); + + // Help button + childSetAction("GraphicsPreferencesHelpButton", onOpenHelp, this); + + // Hardware settings button + childSetAction("GraphicsHardwareButton", onOpenHardwareSettings, NULL); + //============================================================================ // Resolution @@ -115,6 +163,10 @@ BOOL LLPanelDisplay::postBuild() mCtrlWindowed->setCommitCallback(onCommitWindowedMode); mCtrlWindowed->setCallbackUserData(this); + mAspectRatioLabel1 = LLUICtrlFactory::getTextBoxByName(this, "AspectRatioLabel1"); + mFullScreenInfo = LLUICtrlFactory::getTextEditorByName(this, "FullScreenInfo"); + mDisplayResLabel = LLUICtrlFactory::getTextBoxByName(this, "DisplayResLabel"); + S32 num_resolutions = 0; LLWindow::LLWindowResolution* supported_resolutions = gViewerWindow->getWindow()->getSupportedResolutions(num_resolutions); @@ -122,7 +174,7 @@ BOOL LLPanelDisplay::postBuild() mCtrlFullScreen = LLUICtrlFactory::getComboBoxByName(this, "fullscreen combo"); - LLUIString resolution_label = childGetText("resolution_format"); + LLUIString resolution_label = getUIString("resolution_format"); for (S32 i = 0; i < num_resolutions; i++) { @@ -151,7 +203,7 @@ BOOL LLPanelDisplay::postBuild() } mCtrlFullScreen->setCurrentByIndex(fullscreen_mode); mCtrlWindowed->set(FALSE); - mCtrlFullScreen->setEnabled(TRUE); + mCtrlFullScreen->setVisible(TRUE); } else { @@ -159,7 +211,7 @@ BOOL LLPanelDisplay::postBuild() //fullscreen_mode = mCtrlFullScreen->getItemCount() - 1; mCtrlWindowed->set(TRUE); mCtrlFullScreen->setCurrentByIndex(0); - mCtrlFullScreen->setEnabled(FALSE); + mCtrlFullScreen->setVisible(FALSE); } } @@ -176,7 +228,7 @@ BOOL LLPanelDisplay::postBuild() S32 denominator = 0; fractionFromDecimal(mAspectRatio, numerator, denominator); - LLUIString aspect_ratio_text = childGetText("aspect_ratio_text"); + LLUIString aspect_ratio_text = getUIString("aspect_ratio_text"); if (numerator != 0) { aspect_ratio_text.setArg("[NUM]", llformat("%d", numerator)); @@ -199,6 +251,122 @@ BOOL LLPanelDisplay::postBuild() mCtrlAutoDetectAspect->setCommitCallback(onCommitAutoDetectAspect); mCtrlAutoDetectAspect->setCallbackUserData(this); + // radio performance box + mCtrlSliderQuality = LLUICtrlFactory::getSliderByName(this, + "QualityPerformanceSelection"); + mCtrlSliderQuality->setSliderMouseUpCallback(onChangeQuality); + mCtrlSliderQuality->setCallbackUserData(this); + + mCtrlCustomSettings = LLUICtrlFactory::getCheckBoxByName(this, "CustomSettings"); + mCtrlCustomSettings->setCommitCallback(onChangeCustom); + mCtrlCustomSettings->setCallbackUserData(this); + + mGraphicsBorder = static_cast(getChildByName("GraphicsBorder")); + llassert(mGraphicsBorder != NULL); + + //---------------------------------------------------------------------------- + // Enable Bump/Shiny + mCtrlBumpShiny = LLUICtrlFactory::getCheckBoxByName(this, "BumpShiny"); + + //---------------------------------------------------------------------------- + // Enable Reflections + mCtrlReflections = LLUICtrlFactory::getCheckBoxByName(this, "Reflections"); + mCtrlReflections->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable); + mCtrlReflections->setCallbackUserData(this); + mRadioReflectionDetail = LLUICtrlFactory::getRadioGroupByName(this, "ReflectionDetailRadio"); + + // WindLight + mCtrlWindLight = LLUICtrlFactory::getCheckBoxByName(this, "WindLightUseAtmosShaders"); + mCtrlWindLight->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable); + mCtrlWindLight->setCallbackUserData(this); + + //---------------------------------------------------------------------------- + // Enable Avatar Shaders + mCtrlAvatarVP = LLUICtrlFactory::getCheckBoxByName(this, "AvatarVertexProgram"); + mCtrlAvatarVP->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable); + mCtrlAvatarVP->setCallbackUserData(this); + + //---------------------------------------------------------------------------- + // Avatar Render Mode + mCtrlAvatarCloth = LLUICtrlFactory::getCheckBoxByName(this, "AvatarCloth"); + mCtrlAvatarImpostors = LLUICtrlFactory::getCheckBoxByName(this, "AvatarImpostors"); + + //---------------------------------------------------------------------------- + // radio set for lighting detail + mRadioLightingDetail2 = LLUICtrlFactory::getRadioGroupByName(this, "LightingDetailRadio"); + + //---------------------------------------------------------------------------- + // radio set for terrain detail mode + mRadioTerrainDetail = LLUICtrlFactory::getRadioGroupByName(this, "TerrainDetailRadio"); + + //---------------------------------------------------------------------------- + // Global Shader Enable + mCtrlShaderEnable = LLUICtrlFactory::getCheckBoxByName(this, "BasicShaders"); + mCtrlShaderEnable->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable); + mCtrlShaderEnable->setCallbackUserData(this); + + //============================================================================ + + // Object detail slider + mCtrlDrawDistance = LLUICtrlFactory::getSliderByName(this, "DrawDistance"); + mDrawDistanceMeterText1 = LLUICtrlFactory::getTextBoxByName(this, "DrawDistanceMeterText1"); + mDrawDistanceMeterText2 = LLUICtrlFactory::getTextBoxByName(this, "DrawDistanceMeterText2"); + mCtrlDrawDistance->setCommitCallback(&LLPanelDisplay::updateMeterText); + mCtrlDrawDistance->setCallbackUserData(this); + + // Object detail slider + mCtrlLODFactor = LLUICtrlFactory::getSliderByName(this, "ObjectMeshDetail"); + mLODFactorText = LLUICtrlFactory::getTextBoxByName(this, "ObjectMeshDetailText"); + mCtrlLODFactor->setCommitCallback(&LLPanelDisplay::updateSliderText); + mCtrlLODFactor->setCallbackUserData(mLODFactorText); + + // Flex object detail slider + mCtrlFlexFactor = LLUICtrlFactory::getSliderByName(this, "FlexibleMeshDetail"); + mFlexFactorText = LLUICtrlFactory::getTextBoxByName(this, "FlexibleMeshDetailText"); + mCtrlFlexFactor->setCommitCallback(&LLPanelDisplay::updateSliderText); + mCtrlFlexFactor->setCallbackUserData(mFlexFactorText); + + // Tree detail slider + mCtrlTreeFactor = LLUICtrlFactory::getSliderByName(this, "TreeMeshDetail"); + mTreeFactorText = LLUICtrlFactory::getTextBoxByName(this, "TreeMeshDetailText"); + mCtrlTreeFactor->setCommitCallback(&LLPanelDisplay::updateSliderText); + mCtrlTreeFactor->setCallbackUserData(mTreeFactorText); + + // Avatar detail slider + mCtrlAvatarFactor = LLUICtrlFactory::getSliderByName(this, "AvatarMeshDetail"); + mAvatarFactorText = LLUICtrlFactory::getTextBoxByName(this, "AvatarMeshDetailText"); + mCtrlAvatarFactor->setCommitCallback(&LLPanelDisplay::updateSliderText); + mCtrlAvatarFactor->setCallbackUserData(mAvatarFactorText); + + // Terrain detail slider + mCtrlTerrainFactor = LLUICtrlFactory::getSliderByName(this, "TerrainMeshDetail"); + mTerrainFactorText = LLUICtrlFactory::getTextBoxByName(this, "TerrainMeshDetailText"); + mCtrlTerrainFactor->setCommitCallback(&LLPanelDisplay::updateSliderText); + mCtrlTerrainFactor->setCallbackUserData(mTerrainFactorText); + + // Terrain detail slider + mCtrlSkyFactor = LLUICtrlFactory::getSliderByName(this, "SkyMeshDetail"); + mSkyFactorText = LLUICtrlFactory::getTextBoxByName(this, "SkyMeshDetailText"); + mCtrlSkyFactor->setCommitCallback(&LLPanelDisplay::updateSliderText); + mCtrlSkyFactor->setCallbackUserData(mSkyFactorText); + + // Particle detail slider + mCtrlMaxParticle = LLUICtrlFactory::getSliderByName(this, "MaxParticleCount"); + + // Glow detail slider + mCtrlPostProcess = LLUICtrlFactory::getSliderByName(this, "RenderPostProcess"); + mPostProcessText = LLUICtrlFactory::getTextBoxByName(this, "PostProcessText"); + mCtrlPostProcess->setCommitCallback(&LLPanelDisplay::updateSliderText); + mCtrlPostProcess->setCallbackUserData(mPostProcessText); + + // Text boxes (for enabling/disabling) + mShaderText = LLUICtrlFactory::getTextBoxByName(this, "ShadersText"); + mReflectionText = LLUICtrlFactory::getTextBoxByName(this, "ReflectionDetailText"); + mAvatarText = LLUICtrlFactory::getTextBoxByName(this, "AvatarRenderingText"); + mTerrainText = LLUICtrlFactory::getTextBoxByName(this, "TerrainDetailText"); + mLightingText = LLUICtrlFactory::getTextBoxByName(this, "LightingDetailText"); + mMeshDetailText = LLUICtrlFactory::getTextBoxByName(this, "MeshDetailText"); + refresh(); return TRUE; @@ -220,24 +388,322 @@ void LLPanelDisplay::refresh() mFSAutoDetectAspect = gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio"); - mUIScaleFactor = gSavedSettings.getF32("UIScaleFactor"); - mUIAutoScale = gSavedSettings.getBOOL("UIAutoScale"); - - // First Person Visibility - mFirstPersonAvatarVisible = gSavedSettings.getBOOL("FirstPersonAvatarVisible"); + mQualityPerformance = gSavedSettings.getU32("RenderQualityPerformance"); + mCustomSettings = gSavedSettings.getBOOL("RenderCustomSettings"); + + // shader settings + mBumpShiny = gSavedSettings.getBOOL("RenderObjectBump"); + mShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable"); + mWindLight = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); + mReflections = gSavedSettings.getBOOL("RenderWaterReflections"); + mAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP"); + + // reflection radio + mReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail"); + + // avatar settings + mAvatarImpostors = gSavedSettings.getBOOL("RenderUseImpostors"); + mAvatarCloth = gSavedSettings.getBOOL("RenderAvatarCloth"); // Draw distance mRenderFarClip = gSavedSettings.getF32("RenderFarClip"); + + // sliders and their text boxes + mPrimLOD = gSavedSettings.getF32("RenderVolumeLODFactor"); + mFlexLOD = gSavedSettings.getF32("RenderFlexTimeFactor"); + mTreeLOD = gSavedSettings.getF32("RenderTreeLODFactor"); + mAvatarLOD = gSavedSettings.getF32("RenderAvatarLODFactor"); + mTerrainLOD = gSavedSettings.getF32("RenderTerrainLODFactor"); + mSkyLOD = gSavedSettings.getU32("WLSkyDetail"); + mParticleCount = gSavedSettings.getS32("RenderMaxPartCount"); + mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow"); + // lighting and terrain radios + mLightingDetail = gSavedSettings.getS32("RenderLightingDetail"); + mTerrainDetail = gSavedSettings.getS32("RenderTerrainDetail"); + + // slider text boxes + updateSliderText(mCtrlLODFactor, mLODFactorText); + updateSliderText(mCtrlFlexFactor, mFlexFactorText); + updateSliderText(mCtrlTreeFactor, mTreeFactorText); + updateSliderText(mCtrlAvatarFactor, mAvatarFactorText); + updateSliderText(mCtrlTerrainFactor, mTerrainFactorText); + updateSliderText(mCtrlPostProcess, mPostProcessText); + updateSliderText(mCtrlSkyFactor, mSkyFactorText); + + refreshEnabledState(); +} + +void LLPanelDisplay::refreshEnabledState() +{ + // if in windowed mode, disable full screen options + bool isFullScreen = !mCtrlWindowed->get(); + + mDisplayResLabel->setVisible(isFullScreen); + mCtrlFullScreen->setVisible(isFullScreen); + mCtrlAspectRatio->setVisible(isFullScreen); + mAspectRatioLabel1->setVisible(isFullScreen); + mCtrlAutoDetectAspect->setVisible(isFullScreen); + mFullScreenInfo->setVisible(!isFullScreen); + + // disable graphics settings and exit if it's not set to custom + if(!gSavedSettings.getBOOL("RenderCustomSettings")) + { + setHiddenGraphicsState(true); + return; + } + + // otherwise turn them all on and selectively turn off others + else + { + setHiddenGraphicsState(false); + } + + // Reflections + BOOL reflections = gSavedSettings.getBOOL("VertexShaderEnable") + && gGLManager.mHasCubeMap + && gFeatureManagerp->isFeatureAvailable("RenderCubeMap"); + mCtrlReflections->setEnabled(reflections); + + // Bump & Shiny + bool bumpshiny = gGLManager.mHasCubeMap && gFeatureManagerp->isFeatureAvailable("RenderCubeMap") && gFeatureManagerp->isFeatureAvailable("RenderObjectBump"); + mCtrlBumpShiny->setEnabled(bumpshiny ? TRUE : FALSE); + + for (S32 i = 0; i < mRadioReflectionDetail->getItemCount(); ++i) + { + mRadioReflectionDetail->setIndexEnabled(i, mCtrlReflections->get() && reflections); + } + + // Avatar Mode + S32 max_avatar_shader = LLShaderMgr::sMaxAvatarShaderLevel; + mCtrlAvatarVP->setEnabled((max_avatar_shader > 0) ? TRUE : FALSE); + + if (gSavedSettings.getBOOL("VertexShaderEnable") == FALSE || + gSavedSettings.getBOOL("RenderAvatarVP") == FALSE) + { + mCtrlAvatarCloth->setEnabled(false); + } + else + { + mCtrlAvatarCloth->setEnabled(true); + } + + // Vertex Shaders + mCtrlShaderEnable->setEnabled(gFeatureManagerp->isFeatureAvailable("VertexShaderEnable")); + + BOOL shaders = mCtrlShaderEnable->get(); + if (shaders) + { + mRadioTerrainDetail->setValue(1); + mRadioTerrainDetail->setEnabled(FALSE); + } + else + { + mRadioTerrainDetail->setEnabled(TRUE); + } + + // *HACK just checks to see if we can use shaders... + // maybe some cards that use shaders, but don't support windlight + mCtrlWindLight->setEnabled(mCtrlShaderEnable->getEnabled() && shaders); + + // turn off sky detail if atmostpherics isn't on + mCtrlSkyFactor->setEnabled(gSavedSettings.getBOOL("WindLightUseAtmosShaders")); + mSkyFactorText->setEnabled(gSavedSettings.getBOOL("WindLightUseAtmosShaders")); + + // now turn off any features that are unavailable + disableUnavailableSettings(); +} + +void LLPanelDisplay::disableUnavailableSettings() +{ + // if vertex shaders off, disable all shader related products + if(!gFeatureManagerp->isFeatureAvailable("VertexShaderEnable")) + { + mCtrlShaderEnable->setEnabled(FALSE); + mCtrlShaderEnable->setValue(FALSE); + + mCtrlWindLight->setEnabled(FALSE); + mCtrlWindLight->setValue(FALSE); + + mCtrlReflections->setEnabled(FALSE); + mCtrlReflections->setValue(FALSE); + + mCtrlAvatarVP->setEnabled(FALSE); + mCtrlAvatarVP->setValue(FALSE); + + mCtrlAvatarCloth->setEnabled(FALSE); + mCtrlAvatarCloth->setValue(FALSE); + } + + // disabled windlight + if(!gFeatureManagerp->isFeatureAvailable("WindLightUseAtmosShaders")) + { + mCtrlWindLight->setEnabled(FALSE); + mCtrlWindLight->setValue(FALSE); + } + + // disabled reflections + if(!gFeatureManagerp->isFeatureAvailable("RenderWaterReflections")) + { + mCtrlReflections->setEnabled(FALSE); + mCtrlReflections->setValue(FALSE); + } + + // disabled av + if(!gFeatureManagerp->isFeatureAvailable("RenderAvatarVP")) + { + mCtrlAvatarVP->setEnabled(FALSE); + mCtrlAvatarVP->setValue(FALSE); + + mCtrlAvatarCloth->setEnabled(FALSE); + mCtrlAvatarCloth->setValue(FALSE); + } + // disabled cloth + if(!gFeatureManagerp->isFeatureAvailable("RenderAvatarCloth")) + { + mCtrlAvatarCloth->setEnabled(FALSE); + mCtrlAvatarCloth->setValue(FALSE); + } + // disabled impostors + if(!gFeatureManagerp->isFeatureAvailable("RenderUseImpostors")) + { + mCtrlAvatarImpostors->setEnabled(FALSE); + mCtrlAvatarImpostors->setValue(FALSE); + } +} + +void LLPanelDisplay::setHiddenGraphicsState(bool isHidden) +{ + // quick check + llassert(mGraphicsBorder != NULL); + + llassert(mCtrlDrawDistance != NULL); + llassert(mCtrlLODFactor != NULL); + llassert(mCtrlFlexFactor != NULL); + llassert(mCtrlTreeFactor != NULL); + llassert(mCtrlAvatarFactor != NULL); + llassert(mCtrlTerrainFactor != NULL); + llassert(mCtrlSkyFactor != NULL); + llassert(mCtrlMaxParticle != NULL); + llassert(mCtrlPostProcess != NULL); + + llassert(mLODFactorText != NULL); + llassert(mFlexFactorText != NULL); + llassert(mTreeFactorText != NULL); + llassert(mAvatarFactorText != NULL); + llassert(mTerrainFactorText != NULL); + llassert(mSkyFactorText != NULL); + llassert(mPostProcessText != NULL); + + llassert(mCtrlBumpShiny != NULL); + llassert(mCtrlReflections != NULL); + llassert(mCtrlWindLight != NULL); + llassert(mCtrlAvatarVP != NULL); + llassert(mCtrlShaderEnable != NULL); + llassert(mCtrlAvatarImpostors != NULL); + llassert(mCtrlAvatarCloth != NULL); + llassert(mRadioLightingDetail2 != NULL); + + llassert(mRadioTerrainDetail != NULL); + llassert(mRadioReflectionDetail != NULL); + + llassert(mMeshDetailText != NULL); + llassert(mShaderText != NULL); + llassert(mReflectionText != NULL); + llassert(mAvatarText != NULL); + llassert(mLightingText != NULL); + llassert(mTerrainText != NULL); + llassert(mDrawDistanceMeterText1 != NULL); + llassert(mDrawDistanceMeterText2 != NULL); + + // enable/disable the states + mGraphicsBorder->setVisible(!isHidden); + /* + LLColor4 light(.45098f, .51765f, .6078f, 1.0f); + LLColor4 dark(.10196f, .10196f, .10196f, 1.0f); + b ? mGraphicsBorder->setColors(dark, light) : mGraphicsBorder->setColors(dark, dark); + */ + + mCtrlDrawDistance->setVisible(!isHidden); + mCtrlLODFactor->setVisible(!isHidden); + mCtrlFlexFactor->setVisible(!isHidden); + mCtrlTreeFactor->setVisible(!isHidden); + mCtrlAvatarFactor->setVisible(!isHidden); + mCtrlTerrainFactor->setVisible(!isHidden); + mCtrlSkyFactor->setVisible(!isHidden); + mCtrlMaxParticle->setVisible(!isHidden); + mCtrlPostProcess->setVisible(!isHidden); + + mLODFactorText->setVisible(!isHidden); + mFlexFactorText->setVisible(!isHidden); + mTreeFactorText->setVisible(!isHidden); + mAvatarFactorText->setVisible(!isHidden); + mTerrainFactorText->setVisible(!isHidden); + mSkyFactorText->setVisible(!isHidden); + mPostProcessText->setVisible(!isHidden); + + mCtrlBumpShiny->setVisible(!isHidden); + mCtrlReflections->setVisible(!isHidden); + mCtrlWindLight->setVisible(!isHidden); + mCtrlAvatarVP->setVisible(!isHidden); + mCtrlShaderEnable->setVisible(!isHidden); + mCtrlAvatarImpostors->setVisible(!isHidden); + mCtrlAvatarCloth->setVisible(!isHidden); + mRadioLightingDetail2->setVisible(!isHidden); + + mRadioTerrainDetail->setVisible(!isHidden); + mRadioReflectionDetail->setVisible(!isHidden); + + // text boxes + mShaderText->setVisible(!isHidden); + mReflectionText->setVisible(!isHidden); + mAvatarText->setVisible(!isHidden); + mLightingText->setVisible(!isHidden); + mTerrainText->setVisible(!isHidden); + mDrawDistanceMeterText1->setVisible(!isHidden); + mDrawDistanceMeterText2->setVisible(!isHidden); + + // hide one meter text if we're making things visible + if(!isHidden) + { + updateMeterText(mCtrlDrawDistance, this); + } + + mMeshDetailText->setVisible(!isHidden); } void LLPanelDisplay::cancel() { gSavedSettings.setBOOL("FullScreenAutoDetectAspectRatio", mFSAutoDetectAspect); - gSavedSettings.setF32("UIScaleFactor", mUIScaleFactor); - gSavedSettings.setBOOL("UIAutoScale", mUIAutoScale); - gSavedSettings.setBOOL("FirstPersonAvatarVisible", mFirstPersonAvatarVisible); + gSavedSettings.setF32("FullScreenAspectRatio", mAspectRatio); + + gSavedSettings.setU32("RenderQualityPerformance", mQualityPerformance); + + gSavedSettings.setBOOL("RenderCustomSettings", mCustomSettings); + + gSavedSettings.setBOOL("RenderObjectBump", mBumpShiny); + gSavedSettings.setBOOL("VertexShaderEnable", mShaderEnable); + gSavedSettings.setBOOL("WindLightUseAtmosShaders", mWindLight); + gSavedSettings.setBOOL("RenderWaterReflections", mReflections); + gSavedSettings.setBOOL("RenderAvatarVP", mAvatarVP); + + gSavedSettings.setS32("RenderReflectionDetail", mReflectionDetail); + + gSavedSettings.setBOOL("RenderUseImpostors", mAvatarImpostors); + gSavedSettings.setBOOL("RenderAvatarCloth", mAvatarCloth); + + gSavedSettings.setS32("RenderLightingDetail", mLightingDetail); + gSavedSettings.setS32("RenderTerrainDetail", mTerrainDetail); + gSavedSettings.setF32("RenderFarClip", mRenderFarClip); + gSavedSettings.setF32("RenderVolumeLODFactor", mPrimLOD); + gSavedSettings.setF32("RenderFlexTimeFactor", mFlexLOD); + gSavedSettings.setF32("RenderTreeLODFactor", mTreeLOD); + gSavedSettings.setF32("RenderAvatarLODFactor", mAvatarLOD); + gSavedSettings.setF32("RenderTerrainLODFactor", mTerrainLOD); + gSavedSettings.setU32("WLSkyDetail", mSkyLOD); + gSavedSettings.setS32("RenderMaxPartCount", mParticleCount); + gSavedSettings.setS32("RenderGlowResolutionPow", mPostProcess); } void LLPanelDisplay::apply() @@ -245,6 +711,49 @@ void LLPanelDisplay::apply() applyResolution(); } +void LLPanelDisplay::onChangeQuality(LLUICtrl *ctrl, void *data) +{ + LLSliderCtrl* sldr = static_cast(ctrl); + LLPanelDisplay* cur_panel = static_cast(data); + + if(sldr == NULL || cur_panel == NULL) + { + return; + } + + U32 set = (U32)sldr->getValueF32(); + gFeatureManagerp->setGraphicsLevel(set, true); + + LLFloaterPreference::refreshEnabledGraphics(); + cur_panel->refresh(); +} + +void LLPanelDisplay::onChangeCustom(LLUICtrl *ctrl, void *data) +{ + LLFloaterPreference::refreshEnabledGraphics(); +} + +void LLPanelDisplay::onOpenHelp(void* user_data) +{ + LLPanelDisplay* self = static_cast(user_data); + + const char* xml_alert = "GraphicsPreferencesHelp"; + LLAlertDialog* dialogp = gViewerWindow->alertXml(xml_alert); + if (dialogp) + { + LLFloater* root_floater = gFloaterView->getParentFloater(self); + if (root_floater) + { + root_floater->addDependentFloater(dialogp); + } + } +} + +void LLPanelDisplay::onOpenHardwareSettings(void* user_data) +{ + LLFloaterHardwareSettings::show(); +} + void LLPanelDisplay::onApplyResolution(LLUICtrl* src, void* user_data) { ((LLPanelDisplay*) src)->applyResolution(); @@ -369,16 +878,7 @@ void LLPanelDisplay::onCommitWindowedMode(LLUICtrl* ctrl, void *data) { LLPanelDisplay *panel = (LLPanelDisplay*)data; - BOOL windowed_mode = ((LLCheckBoxCtrl*)ctrl)->get(); - - if (windowed_mode) - { - panel->mCtrlFullScreen->setEnabled(FALSE); - } - else - { - panel->mCtrlFullScreen->setEnabled(TRUE); - } + panel->refresh(); } //static @@ -387,11 +887,13 @@ void LLPanelDisplay::onCommitAutoDetectAspect(LLUICtrl *ctrl, void *data) LLPanelDisplay *panel = (LLPanelDisplay*)data; BOOL auto_detect = ((LLCheckBoxCtrl*)ctrl)->get(); + F32 ratio; if (auto_detect) { S32 numerator = 0; S32 denominator = 0; + // clear any aspect ratio override gViewerWindow->mWindow->setNativeAspectRatio(0.f); fractionFromDecimal(gViewerWindow->mWindow->getNativeAspectRatio(), numerator, denominator); @@ -407,6 +909,9 @@ void LLPanelDisplay::onCommitAutoDetectAspect(LLUICtrl *ctrl, void *data) } panel->mCtrlAspectRatio->setLabel(aspect); + + ratio = gViewerWindow->mWindow->getNativeAspectRatio(); + gSavedSettings.setF32("FullScreenAspectRatio", ratio); } } @@ -442,276 +947,71 @@ void LLPanelDisplay::fractionFromDecimal(F32 decimal_val, S32& numerator, S32& d } } -//============================================================================ - -LLPanelDisplay2::LLPanelDisplay2() +//static +void LLPanelDisplay::onVertexShaderEnable(LLUICtrl* self, void* data) { - gUICtrlFactory->buildPanel(this, "panel_preferences_graphics3.xml"); + LLFloaterPreference::refreshEnabledGraphics(); } -BOOL LLPanelDisplay2::postBuild() +void LLPanelDisplay::setHardwareDefaults(void* user_data) { - requires("ani", WIDGET_TYPE_CHECKBOX); - requires("gamma", WIDGET_TYPE_SPINNER); - requires("vbo", WIDGET_TYPE_CHECKBOX); - requires("video card memory radio", WIDGET_TYPE_RADIO_GROUP); - requires("fog", WIDGET_TYPE_SPINNER); - requires("particles", WIDGET_TYPE_SPINNER); - requires("comp limit", WIDGET_TYPE_SPINNER); - requires("debug beacon line width", WIDGET_TYPE_SPINNER); - - if (!checkRequirements()) + if (gFeatureManagerp) { - return FALSE; + gFeatureManagerp->applyRecommendedSettings(); + LLFloaterPreference::refreshEnabledGraphics(); } - - // Graphics Card Memory - mRadioVideoCardMem = LLUICtrlFactory::getRadioGroupByName(this, "video card memory radio"); - -#if !LL_WINDOWS - // The probe_hardware_checkbox setting is only used in the Windows build - // (It apparently controls a time-consuming DX9 hardware probe.) - // Disable the checkbox everywhere else - gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE ); - childSetEnabled("probe_hardware_checkbox", false); -#endif // !LL_WINDOWS - - refresh(); - - return TRUE; } - -LLPanelDisplay2::~LLPanelDisplay2() +void LLPanelDisplay::updateSliderText(LLUICtrl* ctrl, void* user_data) { - // Children all cleaned up by default view destructor. -} - -void LLPanelDisplay2::refresh() -{ - LLPanel::refresh(); - - mUseVBO = gSavedSettings.getBOOL("RenderVBOEnable"); - mUseAniso = gSavedSettings.getBOOL("RenderAnisotropic"); - mGamma = gSavedSettings.getF32("RenderGamma"); - mBrightness = gSavedSettings.getF32("RenderNightBrightness"); - mVideoCardMem = gSavedSettings.getS32("GraphicsCardMemorySetting"); - mFogRatio = gSavedSettings.getF32("RenderFogRatio"); - mParticleCount = gSavedSettings.getS32("RenderMaxPartCount"); - mCompositeLimit = gSavedSettings.getS32("AvatarCompositeLimit"); - mDebugBeaconLineWidth = gSavedSettings.getS32("DebugBeaconLineWidth"); - mProbeHardwareOnStartup = gSavedSettings.getBOOL("ProbeHardwareOnStartup"); - - refreshEnabledState(); -} - -void LLPanelDisplay2::refreshEnabledState() -{ - S32 max_setting = LLViewerImageList::getMaxVideoRamSetting(); - max_setting = llclamp(max_setting, 0, 5); - for (S32 i=max_setting+1; i < mRadioVideoCardMem->getItemCount(); i++) - { - mRadioVideoCardMem->getRadioButton(i)->setEnabled(FALSE); - } - - if (!gFeatureManagerp->isFeatureAvailable("RenderVBO") || - !gGLManager.mHasVertexBufferObject) + // get our UI widgets + LLTextBox* text_box = (LLTextBox*)user_data; + LLSliderCtrl* slider = (LLSliderCtrl*) ctrl; + if(text_box == NULL || slider == NULL) { - childSetEnabled("vbo", FALSE); + return; } -} -void LLPanelDisplay2::apply() -{ + // get range and points when text should change + F32 range = slider->getMaxValue() - slider->getMinValue(); + llassert(range > 0); + F32 midPoint = slider->getMinValue() + range / 3.0f; + F32 highPoint = slider->getMinValue() + (2.0f * range / 3.0f); - // Anisotropic rendering - BOOL old_anisotropic = LLImageGL::sGlobalUseAnisotropic; - LLImageGL::sGlobalUseAnisotropic = childGetValue("ani"); - if (old_anisotropic != LLImageGL::sGlobalUseAnisotropic) + // choose the right text + if(slider->getValueF32() < midPoint) { - BOOL logged_in = (LLStartUp::getStartupState() >= STATE_STARTED); - gViewerWindow->restartDisplay(logged_in); + text_box->setText(LLString("Low")); + } + else if (slider->getValueF32() < highPoint) + { + text_box->setText(LLString("Mid")); } - - refresh(); -} - - -void LLPanelDisplay2::cancel() -{ - gSavedSettings.setBOOL("RenderVBOEnable", mUseVBO); - gSavedSettings.setBOOL("RenderAnisotropic", mUseAniso); - gSavedSettings.setF32("RenderGamma", mGamma); - gSavedSettings.setF32("RenderNightBrightness", mBrightness); - gSavedSettings.setS32("GraphicsCardMemorySetting", mVideoCardMem); - gSavedSettings.setF32("RenderFogRatio", mFogRatio); - gSavedSettings.setS32("RenderMaxPartCount", mParticleCount); - gSavedSettings.setS32("AvatarCompositeLimit", mCompositeLimit); - gSavedSettings.setS32("DebugBeaconLineWidth", mDebugBeaconLineWidth); - gSavedSettings.setBOOL("ProbeHardwareOnStartup", mProbeHardwareOnStartup ); -} - -//============================================================================ - -LLPanelDisplay3::LLPanelDisplay3() -{ - gUICtrlFactory->buildPanel(this, "panel_preferences_graphics2.xml"); -} - -BOOL LLPanelDisplay3::postBuild() -{ - requires("bumpshiny", WIDGET_TYPE_CHECKBOX); - requires("ripple", WIDGET_TYPE_CHECKBOX); - requires("avatarvp", WIDGET_TYPE_CHECKBOX); - requires("shaders", WIDGET_TYPE_CHECKBOX); - - requires("Avatar Appearance", WIDGET_TYPE_RADIO_GROUP); - requires("lighting detail radio", WIDGET_TYPE_RADIO_GROUP); - requires("terrain detail radio", WIDGET_TYPE_RADIO_GROUP); - - requires("Prim LOD Factor", WIDGET_TYPE_SLIDER_BAR); - requires("Flex Factor", WIDGET_TYPE_SLIDER_BAR); - requires("Tree LOD Factor", WIDGET_TYPE_SLIDER_BAR); - requires("Avatar LOD Factor", WIDGET_TYPE_SLIDER_BAR); - - if (!checkRequirements()) + else { - return FALSE; + text_box->setText(LLString("High")); } - - //---------------------------------------------------------------------------- - // Enable Bump/Shiny - mCtrlBumpShiny = LLUICtrlFactory::getCheckBoxByName(this, "bumpshiny"); - - //---------------------------------------------------------------------------- - // Enable Ripple Water - mCtrlRippleWater = LLUICtrlFactory::getCheckBoxByName(this, "ripple"); - - //---------------------------------------------------------------------------- - // Enable Avatar Shaders - mCtrlAvatarVP = LLUICtrlFactory::getCheckBoxByName(this, "avatarvp"); - mCtrlAvatarVP->setCommitCallback(&LLPanelDisplay3::onVertexShaderEnable); - mCtrlAvatarVP->setCallbackUserData(this); - - //---------------------------------------------------------------------------- - // Avatar Render Mode - mCtrlAvatarMode = LLUICtrlFactory::getRadioGroupByName(this, "Avatar Appearance"); - - //---------------------------------------------------------------------------- - // radio set for lighting detail - mRadioLightingDetail2 = LLUICtrlFactory::getRadioGroupByName(this, "lighting detail radio"); - - //---------------------------------------------------------------------------- - // radio set for terrain detail mode - mRadioTerrainDetail = LLUICtrlFactory::getRadioGroupByName(this, "terrain detail radio"); - - //---------------------------------------------------------------------------- - // Global Shader Enable - mCtrlShaderEnable = LLUICtrlFactory::getCheckBoxByName(this, "shaders"); - mCtrlShaderEnable->setCommitCallback(&LLPanelDisplay3::onVertexShaderEnable); - mCtrlShaderEnable->setCallbackUserData(this); - - - //============================================================================ - - // Object detail slider - mCtrlLODFactor = LLUICtrlFactory::getSliderBarByName(this, "Prim LOD Factor"); - - // Flex object detail slider - mCtrlFlexFactor = LLUICtrlFactory::getSliderBarByName(this, "Flex Factor"); - - // Tree detail slider - mCtrlTreeFactor = LLUICtrlFactory::getSliderBarByName(this, "Tree LOD Factor"); - - // Avatar detail slider - mCtrlAvatarFactor = LLUICtrlFactory::getSliderBarByName(this, "Avatar LOD Factor"); - - refresh(); - - return TRUE; -} - - -LLPanelDisplay3::~LLPanelDisplay3() -{ -} - -void LLPanelDisplay3::refresh() -{ - LLPanel::refresh(); - - mBumpShiny = gSavedSettings.getBOOL("RenderObjectBump"); - mRippleWater = gSavedSettings.getBOOL("RenderRippleWater"); - mAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP"); - mShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable"); - mAvatarMode = gSavedSettings.getS32("RenderAvatarMode"); - mLightingDetail = gSavedSettings.getS32("RenderLightingDetail"); - mTerrainDetail = gSavedSettings.getS32("RenderTerrainDetail"); - mPrimLOD = gSavedSettings.getF32("RenderVolumeLODFactor"); - mFlexLOD = gSavedSettings.getF32("RenderFlexTimeFactor"); - mTreeLOD = gSavedSettings.getF32("RenderTreeLODFactor"); - mAvatarLOD = gSavedSettings.getF32("RenderAvatarLODFactor"); - - refreshEnabledState(); } -void LLPanelDisplay3::refreshEnabledState() +void LLPanelDisplay::updateMeterText(LLUICtrl* ctrl, void* user_data) { - // Ripple Water - bool ripple = (LLShaderMgr::getMaxVertexShaderLevel(LLShaderMgr::SHADER_ENVIRONMENT) >= 2) && gGLManager.mHasCubeMap && gFeatureManagerp->isFeatureAvailable("RenderCubeMap"); - mCtrlRippleWater->setEnabled(ripple ? TRUE : FALSE); - - // Bump & Shiny - bool bumpshiny = gGLManager.mHasCubeMap && gFeatureManagerp->isFeatureAvailable("RenderCubeMap") && gFeatureManagerp->isFeatureAvailable("RenderObjectBump"); - mCtrlBumpShiny->setEnabled(bumpshiny ? TRUE : FALSE); + // get our UI widgets + LLPanelDisplay* panel = (LLPanelDisplay*)user_data; + LLSliderCtrl* slider = (LLSliderCtrl*) ctrl; - // Avatar Mode - S32 max_avatar_shader = LLShaderMgr::getMaxVertexShaderLevel(LLShaderMgr::SHADER_AVATAR); - mCtrlAvatarVP->setEnabled((max_avatar_shader > 0) ? TRUE : FALSE); - - if (gSavedSettings.getBOOL("RenderAvatarVP") == FALSE) + LLTextBox* m1 = LLUICtrlFactory::getTextBoxByName(panel, "DrawDistanceMeterText1"); + LLTextBox* m2 = LLUICtrlFactory::getTextBoxByName(panel, "DrawDistanceMeterText2"); + if(m1 == NULL || m2 == NULL || slider == NULL) { - max_avatar_shader = 1; + return; } - max_avatar_shader = llmax(max_avatar_shader, 1); - for (S32 i = 0; i < mCtrlAvatarMode->getItemCount(); i++) - { - mCtrlAvatarMode->setIndexEnabled(i, i < max_avatar_shader); - } - if (mCtrlAvatarMode->getSelectedIndex() >= max_avatar_shader) - { - mCtrlAvatarMode->setSelectedIndex(llmax(max_avatar_shader-1,0)); - } - // Vertex Shaders - mCtrlShaderEnable->setEnabled(gPipeline.canUseVertexShaders()); -} -void LLPanelDisplay3::apply() -{ - + // toggle the two text boxes based on whether we have 1 or two digits + F32 val = slider->getValueF32(); + bool two_digits = val < 100; + m1->setVisible(two_digits); + m2->setVisible(!two_digits); } -void LLPanelDisplay3::setDefaults() -{ -} -void LLPanelDisplay3::cancel() -{ - gSavedSettings.setBOOL("RenderObjectBump", mBumpShiny); - gSavedSettings.setBOOL("RenderRippleWater", mRippleWater); - gSavedSettings.setBOOL("RenderAvatarVP", mAvatarVP); - gSavedSettings.setS32("RenderAvatarMode", mAvatarMode); - gSavedSettings.setS32("RenderLightingDetail", mLightingDetail); - gSavedSettings.setS32("RenderTerrainDetail", mTerrainDetail); - gSavedSettings.setF32("RenderVolumeLODFactor", mPrimLOD); - gSavedSettings.setF32("RenderFlexTimeFactor", mFlexLOD); - gSavedSettings.setF32("RenderTreeLODFactor", mTreeLOD); - gSavedSettings.setF32("RenderAvatarLODFactor", mAvatarLOD); -} - -//static -void LLPanelDisplay3::onVertexShaderEnable(LLUICtrl* self, void* data) -{ - ((LLPanelDisplay3*) data)->refreshEnabledState(); -} diff --git a/linden/indra/newview/llpaneldisplay.h b/linden/indra/newview/llpaneldisplay.h index 7251ac3..cc39f93 100644 --- a/linden/indra/newview/llpaneldisplay.h +++ b/linden/indra/newview/llpaneldisplay.h @@ -34,6 +34,8 @@ #include "llpanel.h" +#include "llcontrol.h" + class LLSlider; class LLSpinCtrl; class LLCheckBoxCtrl; @@ -41,6 +43,17 @@ class LLRadioGroup; class LLComboBox; class LLLineEditor; class LLSliderCtrl; +class LLTextBox; +class LLTextEditor; + +typedef enum +{ + GS_LOW_GRAPHICS, + GS_MID_GRAPHICS, + GS_HIGH_GRAPHICS, + GS_ULTRA_GRAPHICS + +} EGraphicsSettings; class LLPanelDisplay : public LLPanel @@ -52,104 +65,131 @@ public: virtual ~LLPanelDisplay(); virtual BOOL postBuild(); + void refresh(); // Refresh enable/disable + void refreshEnabledState(); + void disableUnavailableSettings(); + void setHiddenGraphicsState(bool isHidden); void apply(); // Apply the changed values. void applyResolution(); void cancel(); protected: + // aspect ratio sliders and boxes LLComboBox *mCtrlFullScreen; // Fullscreen resolution LLCheckBoxCtrl *mCtrlWindowed; // windowed mode LLCheckBoxCtrl *mCtrlAutoDetectAspect; // automatically detect aspect ratio LLComboBox *mCtrlAspectRatio; // user provided aspect ratio - BOOL mFSAutoDetectAspect; - F32 mUIScaleFactor; - BOOL mUIAutoScale; - BOOL mFirstPersonAvatarVisible; - F32 mRenderFarClip; - F32 mAspectRatio; - static void onCommitAutoDetectAspect(LLUICtrl *ctrl, void *data); - static void onKeystrokeAspectRatio(LLLineEditor* caller, void* user_data); - static void onSelectAspectRatio(LLUICtrl*, void*); - static void onCommitWindowedMode(LLUICtrl* ctrl, void *data); - static void onApplyResolution(LLUICtrl* ctrl, void* data); - - // helper function - static void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator); -}; - -class LLPanelDisplay2 : public LLPanel -{ - friend class LLPreferenceCore; - -public: - LLPanelDisplay2(); - virtual ~LLPanelDisplay2(); - - virtual BOOL postBuild(); - void refresh(); // Refresh enable/disable - void apply(); // Apply the changed values. - void cancel(); - void refreshEnabledState(); + /// performance radio group + LLSliderCtrl *mCtrlSliderQuality; + LLCheckBoxCtrl *mCtrlCustomSettings; -protected: - LLRadioGroup* mRadioVideoCardMem; - - BOOL mUseVBO; - BOOL mUseAniso; - F32 mGamma; - F32 mBrightness; - S32 mVideoCardMem; - F32 mFogRatio; - S32 mParticleCount; - S32 mCompositeLimit; - S32 mDebugBeaconLineWidth; - BOOL mProbeHardwareOnStartup; -}; + // performance sliders and boxes + LLViewBorder *mGraphicsBorder; -class LLPanelDisplay3 : public LLPanel -{ - friend class LLPreferenceCore; - -public: - LLPanelDisplay3(); - virtual ~LLPanelDisplay3(); + LLSliderCtrl *mCtrlDrawDistance; // the draw distance slider + LLSliderCtrl *mCtrlLODFactor; // LOD for volume objects + LLSliderCtrl *mCtrlFlexFactor; // Timeslice for flexible objects + LLSliderCtrl *mCtrlTreeFactor; // Control tree cutoff distance + LLSliderCtrl *mCtrlAvatarFactor; // LOD for avatars + LLSliderCtrl *mCtrlTerrainFactor; // LOD for terrain + LLSliderCtrl *mCtrlSkyFactor; // LOD for terrain + LLSliderCtrl *mCtrlMaxParticle; // Max Particle + LLSliderCtrl *mCtrlPostProcess; // Max Particle - virtual BOOL postBuild(); - void refresh(); // Refresh enable/disable - void apply(); // Apply the changed values. - void setDefaults(); - void cancel(); - void refreshEnabledState(); - static void onVertexShaderEnable(LLUICtrl*, void*); - -protected: LLCheckBoxCtrl *mCtrlBumpShiny; - LLCheckBoxCtrl *mCtrlRippleWater; + LLCheckBoxCtrl *mCtrlReflections; + LLCheckBoxCtrl *mCtrlWindLight; LLCheckBoxCtrl *mCtrlAvatarVP; LLCheckBoxCtrl *mCtrlShaderEnable; - LLRadioGroup *mCtrlAvatarMode; + LLCheckBoxCtrl *mCtrlAvatarImpostors; + LLCheckBoxCtrl *mCtrlAvatarCloth; LLRadioGroup *mRadioLightingDetail2; LLRadioGroup *mRadioTerrainDetail; - - LLSlider *mCtrlLODFactor; // LOD for volume objects - LLSlider *mCtrlFlexFactor; // Timeslice for flexible objects - LLSlider *mCtrlTreeFactor; // Control tree cutoff distance - LLSlider *mCtrlAvatarFactor; // LOD for avatars + LLRadioGroup *mRadioReflectionDetail; + + LLTextBox *mAspectRatioLabel1; + LLTextBox *mDisplayResLabel; + LLTextEditor *mFullScreenInfo; + + LLTextBox *mShaderText; + LLTextBox *mReflectionText; + LLTextBox *mAvatarText; + LLTextBox *mTerrainText; + LLTextBox *mLightingText; + LLTextBox *mDrawDistanceMeterText1; + LLTextBox *mDrawDistanceMeterText2; + + LLTextBox *mMeshDetailText; + LLTextBox *mLODFactorText; + LLTextBox *mFlexFactorText; + LLTextBox *mTreeFactorText; + LLTextBox *mAvatarFactorText; + LLTextBox *mTerrainFactorText; + LLTextBox *mSkyFactorText; + LLTextBox *mPostProcessText; + + BOOL mFSAutoDetectAspect; + F32 mAspectRatio; + + // performance value holders for cancel + + S32 mQualityPerformance; + BOOL mCustomSettings; BOOL mBumpShiny; - BOOL mRippleWater; - BOOL mAvatarVP; BOOL mShaderEnable; + BOOL mWindLight; + BOOL mReflections; + BOOL mAvatarVP; + + S32 mReflectionDetail; + + BOOL mAvatarImpostors; + BOOL mAvatarCloth; S32 mAvatarMode; S32 mLightingDetail; S32 mTerrainDetail; + + F32 mRenderFarClip; F32 mPrimLOD; F32 mFlexLOD; F32 mTreeLOD; F32 mAvatarLOD; + F32 mTerrainLOD; + S32 mSkyLOD; + S32 mParticleCount; + S32 mPostProcess; + + static void setGraphicsSettings(LLControlGroup& group); + static void createGroup(); + + // if the quality radio buttons are changed + static void onChangeQuality(LLUICtrl *ctrl, void *data); + + // if the custom settings box is clicked + static void onChangeCustom(LLUICtrl *ctrl, void *data); + + static void onOpenHelp(void *data); + static void onOpenHardwareSettings(void *data); + static void onCommitAutoDetectAspect(LLUICtrl *ctrl, void *data); + static void onKeystrokeAspectRatio(LLLineEditor* caller, void* user_data); + static void onSelectAspectRatio(LLUICtrl*, void*); + static void onCommitWindowedMode(LLUICtrl* ctrl, void *data); + static void onApplyResolution(LLUICtrl* ctrl, void* data); + static void updateSliderText(LLUICtrl* ctrl, void* user_data); + static void updateMeterText(LLUICtrl* ctrl, void* user_data); + + /// callback for defaults + static void setHardwareDefaults(void *data); + + // callback for when client turns on shaders + static void onVertexShaderEnable(LLUICtrl*, void*); + + // helper function + static void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator); }; const S32 LL_MAX_VRAM_INDEX = 6; diff --git a/linden/indra/newview/llpanelevent.cpp b/linden/indra/newview/llpanelevent.cpp index 403684c..2bf61b3 100644 --- a/linden/indra/newview/llpanelevent.cpp +++ b/linden/indra/newview/llpanelevent.cpp @@ -177,7 +177,7 @@ void LLPanelEvent::processEventInfoReply(LLMessageSystem *msg, void **) if (!self->mEventInfo.mHasCover) { - self->mTBCover->setText(self->childGetText("none")); + self->mTBCover->setText(self->getString("none")); } else { @@ -216,11 +216,11 @@ void LLPanelEvent::processEventInfoReply(LLMessageSystem *msg, void **) if (gEventNotifier.hasNotification(self->mEventInfo.mID)) { - self->mNotifyBtn->setLabel(self->childGetText("dont_notify")); + self->mNotifyBtn->setLabel(self->getString("dont_notify")); } else { - self->mNotifyBtn->setLabel(self->childGetText("notify")); + self->mNotifyBtn->setLabel(self->getString("notify")); } } } @@ -228,14 +228,9 @@ void LLPanelEvent::processEventInfoReply(LLMessageSystem *msg, void **) void LLPanelEvent::draw() { - char firstname[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char lastname[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - gCacheName->getName(mEventInfo.mRunByID, firstname, lastname); - - LLString name; - name = firstname; - name += " "; - name += lastname; + std::string name; + gCacheName->getFullName(mEventInfo.mRunByID, name); + mTBRunBy->setText(name); LLPanel::draw(); @@ -312,12 +307,12 @@ void LLPanelEvent::onClickNotify(void *data) if (!gEventNotifier.hasNotification(self->mEventID)) { gEventNotifier.add(self->mEventInfo); - self->mNotifyBtn->setLabel(self->childGetText("dont_notify")); + self->mNotifyBtn->setLabel(self->getString("dont_notify")); } else { gEventNotifier.remove(self->mEventInfo.mID); - self->mNotifyBtn->setLabel(self->childGetText("notify")); + self->mNotifyBtn->setLabel(self->getString("notify")); } } diff --git a/linden/indra/newview/llpanelface.cpp b/linden/indra/newview/llpanelface.cpp index 5ae7b55..a52c57f 100644 --- a/linden/indra/newview/llpanelface.cpp +++ b/linden/indra/newview/llpanelface.cpp @@ -57,10 +57,9 @@ #include "lltooldraganddrop.h" #include "llui.h" #include "llviewercontrol.h" +#include "llviewermedia.h" #include "llviewerobject.h" #include "llviewerstats.h" -#include "llmediaengine.h" - #include "llvieweruictrlfactory.h" // @@ -81,8 +80,11 @@ BOOL LLPanelFace::postBuild() LLTextBox* mLabelColorTransp; LLSpinCtrl* mCtrlColorTransp; // transparency = 1 - alpha + LLTextBox* mLabelGlow; + LLSpinCtrl* mCtrlGlow; + setMouseOpaque(FALSE); - mTextureCtrl = LLUICtrlFactory::getTexturePickerByName(this,"texture control"); + mTextureCtrl = getChild("texture control"); if(mTextureCtrl) { mTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectTexture" ))); @@ -114,7 +116,7 @@ BOOL LLPanelFace::postBuild() } } - mColorSwatch = LLUICtrlFactory::getColorSwatchByName(this,"colorswatch"); + mColorSwatch = getChild("colorswatch"); if(mColorSwatch) { mColorSwatch->setCommitCallback(LLPanelFace::onCommitColor); @@ -157,6 +159,15 @@ BOOL LLPanelFace::postBuild() mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP); mComboTexGen->setCallbackUserData( this ); } + + mLabelGlow = LLUICtrlFactory::getTextBoxByName(this,"glow label"); + mCtrlGlow = LLUICtrlFactory::getSpinnerByName(this,"glow"); + if(mCtrlGlow) + { + mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow); + mCtrlGlow->setCallbackUserData(this); + } + childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this); childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this); childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this); @@ -188,7 +199,7 @@ LLPanelFace::~LLPanelFace() void LLPanelFace::sendTexture() { - LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(this,"texture control"); + LLTextureCtrl* mTextureCtrl = getChild("texture control"); if(!mTextureCtrl) return; if( !mTextureCtrl->getTentative() ) { @@ -255,6 +266,15 @@ void LLPanelFace::sendAlpha() } +void LLPanelFace::sendGlow() +{ + LLSpinCtrl* mCtrlGlow = LLViewerUICtrlFactory::getSpinnerByName(this,"glow"); + if(!mCtrlGlow)return; + F32 glow = mCtrlGlow->get(); + + gSelectMgr->selectionSetGlow( glow ); +} + struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor { LLPanelFaceSetTEFunctor(LLPanelFace* panel) : mPanel(panel) {} @@ -364,7 +384,8 @@ void LLPanelFace::getState() LLViewerObject* objectp = gSelectMgr->getSelection()->getFirstObject(); if( objectp - && objectp->getPCode() == LL_PCODE_VOLUME) + && objectp->getPCode() == LL_PCODE_VOLUME + && objectp->permModify()) { BOOL editable = objectp->permModify(); @@ -374,14 +395,19 @@ void LLPanelFace::getState() childSetEnabled("button align",FALSE); //mBtnAutoFix->setEnabled ( FALSE ); - if ( LLMediaEngine::getInstance()->getMediaRenderer () ) - if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () ) - { - childSetEnabled("textbox autofix",editable); - //mLabelTexAutoFix->setEnabled ( editable ); - childSetEnabled("button align",editable); - //mBtnAutoFix->setEnabled ( editable ); - } + if(LLViewerMedia::hasMedia()) + { + childSetEnabled("textbox autofix",editable); + childSetEnabled("button align",editable); + } + //if ( LLMediaEngine::getInstance()->getMediaRenderer () ) + // if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () ) + // { + // + // //mLabelTexAutoFix->setEnabled ( editable ); + // + // //mBtnAutoFix->setEnabled ( editable ); + // } childSetEnabled("button apply",editable); bool identical; @@ -574,10 +600,28 @@ void LLPanelFace::getState() childSetEnabled("ColorTrans",editable); } + { + F32 glow = 0.f; + struct f8 : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + return object->getTE(face)->getGlow(); + } + } func; + identical = gSelectMgr->getSelection()->getSelectedTEValue( &func, glow ); + + childSetValue("glow",glow); + childSetEnabled("glow",editable); + childSetTentative("glow",!identical); + childSetEnabled("glow label",editable); + + } + // Bump { F32 shinyf = 0.f; - struct f8 : public LLSelectedTEGetFunctor + struct f9 : public LLSelectedTEGetFunctor { F32 get(LLViewerObject* object, S32 face) { @@ -602,7 +646,7 @@ void LLPanelFace::getState() { F32 bumpf = 0.f; - struct f9 : public LLSelectedTEGetFunctor + struct f10 : public LLSelectedTEGetFunctor { F32 get(LLViewerObject* object, S32 face) { @@ -627,7 +671,7 @@ void LLPanelFace::getState() { F32 genf = 0.f; - struct f10 : public LLSelectedTEGetFunctor + struct f11 : public LLSelectedTEGetFunctor { F32 get(LLViewerObject* object, S32 face) { @@ -652,20 +696,20 @@ void LLPanelFace::getState() if (selected_texgen == 1) { - childSetText("tex scale",childGetText("string repeats per meter")); + childSetText("tex scale",getString("string repeats per meter")); childSetValue("TexScaleU", 2.0f * childGetValue("TexScaleU").asReal() ); childSetValue("TexScaleV", 2.0f * childGetValue("TexScaleV").asReal() ); } else { - childSetText("tex scale",childGetText("string repeats per face")); + childSetText("tex scale",getString("string repeats per face")); } } { F32 fullbrightf = 0.f; - struct f11 : public LLSelectedTEGetFunctor + struct f12 : public LLSelectedTEGetFunctor { F32 get(LLViewerObject* object, S32 face) { @@ -687,7 +731,7 @@ void LLPanelFace::getState() // Repeats per meter { F32 repeats = 1.f; - struct f12 : public LLSelectedTEGetFunctor + struct f13 : public LLSelectedTEGetFunctor { F32 get(LLViewerObject* object, S32 face) { @@ -718,14 +762,14 @@ void LLPanelFace::getState() clearCtrls(); // Disable non-UICtrls - LLTextureCtrl* texture_ctrl = LLUICtrlFactory::getTexturePickerByName(this,"texture control"); + LLTextureCtrl* texture_ctrl = getChild("texture control"); if(texture_ctrl) { texture_ctrl->setImageAssetID( LLUUID::null ); texture_ctrl->setEnabled( FALSE ); // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl. // texture_ctrl->setValid(FALSE); } - LLColorSwatchCtrl* mColorSwatch = LLUICtrlFactory::getColorSwatchByName(this,"colorswatch"); + LLColorSwatchCtrl* mColorSwatch = getChild("colorswatch"); if(mColorSwatch) { mColorSwatch->setEnabled( FALSE ); @@ -757,6 +801,12 @@ void LLPanelFace::refresh() // Static functions // +// static +F32 LLPanelFace::valueGlow(LLViewerObject* object, S32 face) +{ + return (F32)(object->getTE(face)->getGlow()); +} + // static void LLPanelFace::onCommitColor(LLUICtrl* ctrl, void* userdata) @@ -815,6 +865,13 @@ void LLPanelFace::onCommitFullbright(LLUICtrl* ctrl, void* userdata) } // static +void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + self->sendGlow(); +} + +// static BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item, void*) { BOOL accept = TRUE; @@ -884,27 +941,25 @@ struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor virtual bool apply(LLViewerObject* object, S32 te) { // only do this if it's a media texture - if ( object->getTE ( te )->getID() == LLMediaEngine::getInstance()->getImageUUID () ) + if ( object->getTE ( te )->getID() == LLViewerMedia::getMediaTextureID() ) { - // make sure we're valid - if ( LLMediaEngine::getInstance()->getMediaRenderer() ) + S32 media_width, media_height; + S32 texture_width, texture_height; + if ( LLViewerMedia::getMediaSize( &media_width, &media_height ) + && LLViewerMedia::getTextureSize( &texture_width, &texture_height ) ) { - // calculate correct scaling based on media dimensions and next-power-of-2 texture dimensions - F32 scaleS = (F32)LLMediaEngine::getInstance()->getMediaRenderer()->getMediaWidth() / - (F32)LLMediaEngine::getInstance()->getMediaRenderer()->getTextureWidth(); - - F32 scaleT = (F32)LLMediaEngine::getInstance()->getMediaRenderer()->getMediaHeight() / - (F32)LLMediaEngine::getInstance()->getMediaRenderer()->getTextureHeight(); + F32 scale_s = (F32)media_width / (F32)texture_width; + F32 scale_t = (F32)media_height / (F32)texture_height; // set scale and adjust offset - object->setTEScaleS( te, scaleS ); - object->setTEScaleT( te, scaleT ); // don't need to flip Y anymore since QT does this for us now. - object->setTEOffsetS( te, -( 1.0f - scaleS ) / 2.0f ); - object->setTEOffsetT( te, -( 1.0f - scaleT ) / 2.0f ); + object->setTEScaleS( te, scale_s ); + object->setTEScaleT( te, scale_t ); // don't need to flip Y anymore since QT does this for us now. + object->setTEOffsetS( te, -( 1.0f - scale_s ) / 2.0f ); + object->setTEOffsetT( te, -( 1.0f - scale_t ) / 2.0f ); } } return true; - } + }; }; void LLPanelFace::onClickAutoFix(void* userdata) diff --git a/linden/indra/newview/llpanelface.h b/linden/indra/newview/llpanelface.h index 9e35003..230772b 100644 --- a/linden/indra/newview/llpanelface.h +++ b/linden/indra/newview/llpanelface.h @@ -67,6 +67,7 @@ protected: void sendTexGen(); // applies and sends bump map void sendShiny(); // applies and sends shininess void sendFullbright(); // applies and sends full bright + void sendGlow(); // this function is to return TRUE if the dra should succeed. static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item, void* ud); @@ -83,9 +84,11 @@ protected: static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); static void onCommitShiny( LLUICtrl* ctrl, void* userdata); static void onCommitFullbright( LLUICtrl* ctrl, void* userdata); + static void onCommitGlow( LLUICtrl* ctrl, void *userdata); static void onClickApply(void*); static void onClickAutoFix(void*); + static F32 valueGlow(LLViewerObject* object, S32 face); }; #endif diff --git a/linden/indra/newview/llpanelgeneral.cpp b/linden/indra/newview/llpanelgeneral.cpp index 5831ed1..2c68e9a 100644 --- a/linden/indra/newview/llpanelgeneral.cpp +++ b/linden/indra/newview/llpanelgeneral.cpp @@ -101,13 +101,14 @@ LLPanelGeneral::LLPanelGeneral() BOOL LLPanelGeneral::postBuild() { requires("location_combobox", WIDGET_TYPE_COMBO_BOX); - requires("region_name_prompt", WIDGET_TYPE_TEXT_BOX); requires("show_location_checkbox", WIDGET_TYPE_CHECKBOX); requires("fade_out_radio", WIDGET_TYPE_RADIO_GROUP); requires("show_my_name_checkbox", WIDGET_TYPE_CHECKBOX); requires("show_my_title_checkbox", WIDGET_TYPE_CHECKBOX); requires("small_avatar_names_checkbox", WIDGET_TYPE_CHECKBOX); requires("effect_color_swatch", WIDGET_TYPE_COLOR_SWATCH); + requires("UI Scale", WIDGET_TYPE_SLIDER); + requires("ui_auto_scale", WIDGET_TYPE_CHECKBOX); requires("afk_timeout_spinner", WIDGET_TYPE_SPINNER); requires("rotate_mini_map_checkbox", WIDGET_TYPE_CHECKBOX); requires("friends_online_notify_checkbox", WIDGET_TYPE_CHECKBOX); @@ -120,7 +121,7 @@ BOOL LLPanelGeneral::postBuild() return FALSE; } - LLString region_name_prompt = childGetText("region_name_prompt"); + LLString region_name_prompt = getString("region_name_prompt"); // location combobox @@ -206,6 +207,10 @@ void LLPanelGeneral::refresh() mNotifyMoney = gSavedSettings.getBOOL("NotifyMoneyChange"); mUseDefaultColor = gSavedSettings.getBOOL("UseDefaultColorPicker"); mEffectColor = gSavedSettings.getColor4("EffectColor"); + mShowSearch = gSavedSettings.getBOOL("ShowSearchBar"); + + mUIScaleFactor = gSavedSettings.getF32("UIScaleFactor"); + mUIAutoScale = gSavedSettings.getBOOL("UIAutoScale"); mLanguage = gSavedSettings.getString("Language"); } @@ -225,7 +230,10 @@ void LLPanelGeneral::cancel() gSavedSettings.setBOOL("MiniMapRotate", mMiniMapRotate ); gSavedSettings.setBOOL("NotifyMoneyChange", mNotifyMoney ); gSavedSettings.setBOOL("UseDefaultColorPicker", mUseDefaultColor ); + gSavedSettings.setBOOL("ShowSearchBar", mShowSearch); gSavedSettings.setColor4("EffectColor", mEffectColor ); + gSavedSettings.setF32("UIScaleFactor", mUIScaleFactor); + gSavedSettings.setBOOL("UIAutoScale", mUIAutoScale); gSavedSettings.setString("Language", mLanguage); LLURLSimString::setString(mLoginLocation); diff --git a/linden/indra/newview/llpanelgeneral.h b/linden/indra/newview/llpanelgeneral.h index cd818b9..d84aa20 100644 --- a/linden/indra/newview/llpanelgeneral.h +++ b/linden/indra/newview/llpanelgeneral.h @@ -63,10 +63,13 @@ protected: BOOL mSmallAvatarNames; BOOL mRenderHideGroupTitle; BOOL mChatOnlineNotification; + BOOL mShowSearch; F32 mAFKTimeout; BOOL mNotifyMoney; BOOL mUseDefaultColor; LLColor4 mEffectColor; + F32 mUIScaleFactor; + BOOL mUIAutoScale; BOOL mMiniMapRotate; S32 mCrashBehavior; LLString mLoginLocation; diff --git a/linden/indra/newview/llpanelgroup.cpp b/linden/indra/newview/llpanelgroup.cpp index e26d1d2..b6f4681 100644 --- a/linden/indra/newview/llpanelgroup.cpp +++ b/linden/indra/newview/llpanelgroup.cpp @@ -67,22 +67,14 @@ BOOL LLPanelGroupTab::isVisibleByAgent(LLAgent* agentp) BOOL LLPanelGroupTab::postBuild() { // Hook up the help button callback. - LLButton* button = (LLButton*) getChildByName("help_button"); + LLButton* button = getChild("help_button"); if (button) { button->setClickedCallback(onClickHelp); button->setCallbackUserData(this); } - // Read help text from the xml file. - LLTextBox* txt; - // Don't recurse for this, since we don't currently have a recursive removeChild() - txt = (LLTextBox*) getChildByName("help_text"); - if (txt) - { - mHelpText = txt->getText(); - removeChild(txt, TRUE); - } + mHelpText = getString("help_text"); return TRUE; } @@ -219,14 +211,14 @@ void LLPanelGroup::updateTabVisibility() BOOL LLPanelGroup::postBuild() { - mTabContainer = (LLTabContainerCommon*) getChildByName("group_tab_container"); + mTabContainer = getChild("group_tab_container"); if (mTabContainer) { // Select the initial tab specified via constructor const BOOL recurse = TRUE; LLPanelGroupTab* tabp = - (LLPanelGroupTab*) getChildByName(mInitialTab, recurse); + getChild(mInitialTab, recurse); if (!tabp) { @@ -272,23 +264,10 @@ BOOL LLPanelGroup::postBuild() mCurrentTab->activate(); } - // Read apply text from the xml file. - LLTextBox* txt; - // Don't recurse for this, since we don't currently have a recursive removeChild() - txt = (LLTextBox*)getChildByName("default_needs_apply_text"); - if (txt) - { - mDefaultNeedsApplyMesg = txt->getText(); - removeChild(txt, TRUE); - } - txt = (LLTextBox*)getChildByName("want_apply_text"); - if (txt) - { - mWantApplyMesg = txt->getText(); - removeChild(txt, TRUE); - } + mDefaultNeedsApplyMesg = getString("default_needs_apply_text"); + mWantApplyMesg = getString("want_apply_text"); - LLButton* button = (LLButton*) getChildByName("btn_ok"); + LLButton* button = getChild("btn_ok"); if (button) { button->setClickedCallback(onBtnOK); @@ -296,7 +275,7 @@ BOOL LLPanelGroup::postBuild() button->setVisible(mAllowEdit); } - button = (LLButton*) getChildByName("btn_cancel"); + button = getChild("btn_cancel"); if (button) { button->setClickedCallback(onBtnCancel); @@ -304,7 +283,7 @@ BOOL LLPanelGroup::postBuild() button->setVisible(mAllowEdit); } - button = (LLButton*) getChildByName("btn_apply"); + button = getChild("btn_apply"); if (button) { button->setClickedCallback(onBtnApply); @@ -314,7 +293,7 @@ BOOL LLPanelGroup::postBuild() mApplyBtn = button; } - button = (LLButton*) getChildByName("btn_refresh"); + button = getChild("btn_refresh"); if (button) { button->setClickedCallback(onBtnRefresh); @@ -400,7 +379,7 @@ void LLPanelGroup::selectTab(std::string tab_name) const BOOL recurse = TRUE; LLPanelGroupTab* tabp = - (LLPanelGroupTab*) getChildByName(tab_name, recurse); + getChild(tab_name, recurse); if ( tabp && mTabContainer ) { diff --git a/linden/indra/newview/llpanelgroup.h b/linden/indra/newview/llpanelgroup.h index 6e22ebc..2157b34 100644 --- a/linden/indra/newview/llpanelgroup.h +++ b/linden/indra/newview/llpanelgroup.h @@ -41,7 +41,7 @@ const S32 UPDATE_MEMBERS_PER_FRAME = 500; // Forward declares class LLPanelGroupTab; -class LLTabContainerCommon; +class LLTabContainer; class LLAgent; class LLPanelGroupTabObserver @@ -111,7 +111,7 @@ public: protected: LLPanelGroupTab* mCurrentTab; LLPanelGroupTab* mRequestedTab; - LLTabContainerCommon* mTabContainer; + LLTabContainer* mTabContainer; BOOL mIgnoreTransition; LLButton* mApplyBtn; @@ -183,7 +183,7 @@ public: protected: LLUUID mGroupID; - LLTabContainerCommon* mTabContainer; + LLTabContainer* mTabContainer; LLString mHelpText; BOOL mAllowEdit; diff --git a/linden/indra/newview/llpanelgroupgeneral.cpp b/linden/indra/newview/llpanelgroupgeneral.cpp index 1ecc2e5..e2572f1 100644 --- a/linden/indra/newview/llpanelgroupgeneral.cpp +++ b/linden/indra/newview/llpanelgroupgeneral.cpp @@ -99,10 +99,10 @@ BOOL LLPanelGroupGeneral::postBuild() bool recurse = true; // General info - mGroupNameEditor = (LLLineEditor*) getChildByName("group_name_editor", recurse); - mGroupName = (LLTextBox*) getChildByName("group_name", recurse); + mGroupNameEditor = getChild("group_name_editor", recurse); + mGroupName = getChild("group_name", recurse); - mInsignia = (LLTextureCtrl*) getChildByName("insignia", recurse); + mInsignia = getChild("insignia", recurse); if (mInsignia) { mInsignia->setCommitCallback(onCommitAny); @@ -110,7 +110,7 @@ BOOL LLPanelGroupGeneral::postBuild() mDefaultIconID = mInsignia->getImageAssetID(); } - mEditCharter = (LLTextEditor*) getChildByName("charter", recurse); + mEditCharter = getChild("charter", recurse); if(mEditCharter) { mEditCharter->setCommitCallback(onCommitAny); @@ -119,21 +119,21 @@ BOOL LLPanelGroupGeneral::postBuild() mEditCharter->setCallbackUserData(this); } - mBtnJoinGroup = (LLButton*) getChildByName("join_button", recurse); + mBtnJoinGroup = getChild("join_button", recurse); if ( mBtnJoinGroup ) { mBtnJoinGroup->setClickedCallback(onClickJoin); mBtnJoinGroup->setCallbackUserData(this); } - mBtnInfo = (LLButton*) getChildByName("info_button", recurse); + mBtnInfo = getChild("info_button", recurse); if ( mBtnInfo ) { mBtnInfo->setClickedCallback(onClickInfo); mBtnInfo->setCallbackUserData(this); } - LLTextBox* founder = (LLTextBox*) getChildByName("founder_name"); + LLTextBox* founder = getChild("founder_name"); if (founder) { mFounderName = new LLNameBox(founder->getName(),founder->getRect(),LLUUID::null,FALSE,founder->getFont(),founder->getMouseOpaque()); @@ -141,7 +141,7 @@ BOOL LLPanelGroupGeneral::postBuild() addChild(mFounderName); } - mListVisibleMembers = (LLNameListCtrl*) getChildByName("visible_members", recurse); + mListVisibleMembers = getChild("visible_members", recurse); if (mListVisibleMembers) { mListVisibleMembers->setDoubleClickCallback(openProfile); @@ -149,14 +149,14 @@ BOOL LLPanelGroupGeneral::postBuild() } // Options - mCtrlShowInGroupList = (LLCheckBoxCtrl*) getChildByName("show_in_group_list", recurse); + mCtrlShowInGroupList = getChild("show_in_group_list", recurse); if (mCtrlShowInGroupList) { mCtrlShowInGroupList->setCommitCallback(onCommitAny); mCtrlShowInGroupList->setCallbackUserData(this); } - mCtrlMature = (LLCheckBoxCtrl*) getChildByName("mature", recurse); + mCtrlMature = getChild("mature", recurse); if (mCtrlMature) { mCtrlMature->setCommitCallback(onCommitAny); @@ -164,21 +164,21 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlMature->setVisible( !gAgent.isTeen() ); } - mCtrlOpenEnrollment = (LLCheckBoxCtrl*) getChildByName("open_enrollement", recurse); + mCtrlOpenEnrollment = getChild("open_enrollement", recurse); if (mCtrlOpenEnrollment) { mCtrlOpenEnrollment->setCommitCallback(onCommitAny); mCtrlOpenEnrollment->setCallbackUserData(this); } - mCtrlEnrollmentFee = (LLCheckBoxCtrl*) getChildByName("check_enrollment_fee", recurse); + mCtrlEnrollmentFee = getChild("check_enrollment_fee", recurse); if (mCtrlEnrollmentFee) { mCtrlEnrollmentFee->setCommitCallback(onCommitEnrollment); mCtrlEnrollmentFee->setCallbackUserData(this); } - mSpinEnrollmentFee = (LLSpinCtrl*) getChildByName("spin_enrollment_fee", recurse); + mSpinEnrollmentFee = getChild("spin_enrollment_fee", recurse); if (mSpinEnrollmentFee) { mSpinEnrollmentFee->setCommitCallback(onCommitAny); @@ -194,7 +194,7 @@ BOOL LLPanelGroupGeneral::postBuild() accept_notices = data.mAcceptNotices; list_in_profile = data.mListInProfile; } - mCtrlReceiveNotices = (LLCheckBoxCtrl*) getChildByName("receive_notices", recurse); + mCtrlReceiveNotices = getChild("receive_notices", recurse); if (mCtrlReceiveNotices) { mCtrlReceiveNotices->setCommitCallback(onCommitUserOnly); @@ -203,7 +203,7 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlReceiveNotices->setEnabled(data.mID.notNull()); } - mCtrlListGroup = (LLCheckBoxCtrl*) getChildByName("list_groups_in_profile", recurse); + mCtrlListGroup = getChild("list_groups_in_profile", recurse); if (mCtrlListGroup) { mCtrlListGroup->setCommitCallback(onCommitUserOnly); @@ -212,31 +212,17 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlListGroup->setEnabled(data.mID.notNull()); } - mActiveTitleLabel = (LLTextBox*) getChildByName("active_title_label", recurse); + mActiveTitleLabel = getChild("active_title_label", recurse); - mComboActiveTitle = (LLComboBox*) getChildByName("active_title", recurse); + mComboActiveTitle = getChild("active_title", recurse); if (mComboActiveTitle) { mComboActiveTitle->setCommitCallback(onCommitTitle); mComboActiveTitle->setCallbackUserData(this); } - // Extra data - LLTextBox* txt; - // Don't recurse for this, since we don't currently have a recursive removeChild() - txt = (LLTextBox*)getChildByName("incomplete_member_data_str"); - if (txt) - { - mIncompleteMemberDataStr = txt->getText(); - removeChild(txt, TRUE); - } - - txt = (LLTextBox*)getChildByName("confirm_group_create_str"); - if (txt) - { - mConfirmGroupCreateStr = txt->getText(); - removeChild(txt, TRUE); - } + mIncompleteMemberDataStr = getString("incomplete_member_data_str"); + mConfirmGroupCreateStr = getString("confirm_group_create_str"); // If the group_id is null, then we are creating a new group if (mGroupID.isNull()) diff --git a/linden/indra/newview/llpanelgroupinvite.cpp b/linden/indra/newview/llpanelgroupinvite.cpp index 73900f0..c393854 100644 --- a/linden/indra/newview/llpanelgroupinvite.cpp +++ b/linden/indra/newview/llpanelgroupinvite.cpp @@ -474,12 +474,12 @@ BOOL LLPanelGroupInvite::postBuild() { BOOL recurse = TRUE; - mImplementation->mLoadingText = childGetText("loading"); - mImplementation->mRoleNames = (LLComboBox*) getChildByName("role_name", + mImplementation->mLoadingText = getString("loading"); + mImplementation->mRoleNames = getChild("role_name", recurse); - mImplementation->mGroupName = (LLTextBox*) getChildByName("group_name_text", recurse); + mImplementation->mGroupName = getChild("group_name_text", recurse); mImplementation->mInvitees = - (LLNameListCtrl*) getChildByName("invitee_list", recurse); + getChild("invitee_list", recurse); if ( mImplementation->mInvitees ) { mImplementation->mInvitees->setCallbackUserData(mImplementation); @@ -487,7 +487,7 @@ BOOL LLPanelGroupInvite::postBuild() mImplementation->mInvitees->setCommitCallback(impl::callbackSelect); } - LLButton* button = (LLButton*) getChildByName("add_button", recurse); + LLButton* button = getChild("add_button", recurse); if ( button ) { // default to opening avatarpicker automatically @@ -497,7 +497,7 @@ BOOL LLPanelGroupInvite::postBuild() } mImplementation->mRemoveButton = - (LLButton*) getChildByName("remove_button", recurse); + getChild("remove_button", recurse); if ( mImplementation->mRemoveButton ) { mImplementation->mRemoveButton-> @@ -507,7 +507,7 @@ BOOL LLPanelGroupInvite::postBuild() } mImplementation->mOKButton = - (LLButton*) getChildByName("ok_button", recurse); + getChild("ok_button", recurse); if ( mImplementation->mOKButton ) { mImplementation->mOKButton-> @@ -516,7 +516,7 @@ BOOL LLPanelGroupInvite::postBuild() mImplementation->mOKButton->setEnabled(FALSE); } - button = (LLButton*) getChildByName("cancel_button", recurse); + button = getChild("cancel_button", recurse); if ( button ) { button->setClickedCallback(impl::callbackClickCancel); diff --git a/linden/indra/newview/llpanelgrouplandmoney.cpp b/linden/indra/newview/llpanelgrouplandmoney.cpp index 483aff1..7cfe460 100644 --- a/linden/indra/newview/llpanelgrouplandmoney.cpp +++ b/linden/indra/newview/llpanelgrouplandmoney.cpp @@ -60,7 +60,7 @@ public: LLGroupMoneyTabEventHandler(LLButton* earlier_button, LLButton* later_button, LLTextEditor* text_editor, - LLTabContainerCommon* tab_containerp, + LLTabContainer* tab_containerp, LLPanel* panelp, const LLString& loading_text, const LLUUID& group_id, @@ -92,7 +92,7 @@ public: LLGroupMoneyDetailsTabEventHandler(LLButton* earlier_buttonp, LLButton* later_buttonp, LLTextEditor* text_editorp, - LLTabContainerCommon* tab_containerp, + LLTabContainer* tab_containerp, LLPanel* panelp, const LLString& loading_text, const LLUUID& group_id); @@ -109,7 +109,7 @@ public: LLGroupMoneySalesTabEventHandler(LLButton* earlier_buttonp, LLButton* later_buttonp, LLTextEditor* text_editorp, - LLTabContainerCommon* tab_containerp, + LLTabContainer* tab_containerp, LLPanel* panelp, const LLString& loading_text, const LLUUID& group_id); @@ -123,7 +123,7 @@ class LLGroupMoneyPlanningTabEventHandler : public LLGroupMoneyTabEventHandler { public: LLGroupMoneyPlanningTabEventHandler(LLTextEditor* text_editor, - LLTabContainerCommon* tab_containerp, + LLTabContainer* tab_containerp, LLPanel* panelp, const LLString& loading_text, const LLUUID& group_id); @@ -311,7 +311,6 @@ void LLPanelGroupLandMoney::impl::setYourContributionTextField(int contrib) if ( mYourContributionEditorp ) { mYourContributionEditorp->setText(buffer); - mYourContributionEditorp->draw(); } } @@ -501,7 +500,7 @@ void LLPanelGroupLandMoney::activate() if ( !mImplementationp->mBeenActivated ) { //select the first tab - LLTabContainerCommon* tabp = (LLTabContainerCommon*) getChildByName("group_money_tab_container"); + LLTabContainer* tabp = getChild("group_money_tab_container"); if ( tabp ) { @@ -541,7 +540,7 @@ void LLPanelGroupLandMoney::update(LLGroupChange gc) { if (gc != GC_ALL) return; //Don't update if it's the wrong panel! - LLTabContainerCommon* tabp = (LLTabContainerCommon*) getChildByName("group_money_tab_container"); + LLTabContainer* tabp = getChild("group_money_tab_container"); if ( tabp ) { @@ -605,12 +604,12 @@ BOOL LLPanelGroupLandMoney::postBuild() bool can_view = gAgent.isInGroup(mGroupID); mImplementationp->mGroupOverLimitIconp = - (LLIconCtrl*) getChildByName("group_over_limit_icon"); + getChild("group_over_limit_icon"); mImplementationp->mGroupOverLimitTextp = - (LLTextBox*) getChildByName("group_over_limit_text"); + getChild("group_over_limit_text"); mImplementationp->mYourContributionEditorp - = (LLLineEditor*) getChildByName("your_contribution_line_editor"); + = getChild("your_contribution_line_editor"); if ( mImplementationp->mYourContributionEditorp ) { LLLineEditor* editor = mImplementationp->mYourContributionEditorp; @@ -620,26 +619,13 @@ BOOL LLPanelGroupLandMoney::postBuild() editor->setCallbackUserData(this); } - mImplementationp->mMapButtonp = (LLButton*) getChildByName("map_button"); + mImplementationp->mMapButtonp = getChild("map_button"); mImplementationp->mGroupParcelsp = - (LLScrollListCtrl*) getChildByName("group_parcel_list"); - - LLTextBox *no_permsp = - (LLTextBox*) getChildByName("cant_view_group_land_text"); - if ( no_permsp ) - { - mImplementationp->mCantViewParcelsText = no_permsp->getText(); - removeChild(no_permsp, TRUE); - } - - no_permsp = (LLTextBox*) getChildByName("cant_view_group_accounting_text"); - if ( no_permsp ) - { - mImplementationp->mCantViewAccountsText = no_permsp->getText(); - removeChild(no_permsp, TRUE); - } + getChild("group_parcel_list"); + mImplementationp->mCantViewParcelsText = getString("cant_view_group_land_text"); + mImplementationp->mCantViewAccountsText = getString("cant_view_group_accounting_text"); if ( mImplementationp->mMapButtonp ) { @@ -677,8 +663,7 @@ BOOL LLPanelGroupLandMoney::postBuild() LLTextEditor* textp; LLPanel* panelp; - LLTabContainerCommon* tabcp = (LLTabContainerCommon*) - getChildByName("group_money_tab_container", true); + LLTabContainer* tabcp = getChild("group_money_tab_container"); if ( !can_view ) { @@ -694,13 +679,13 @@ BOOL LLPanelGroupLandMoney::postBuild() } } - LLString loading_text = childGetText("loading_txt"); + LLString loading_text = getString("loading_txt"); //pull out the widgets for the L$ details tab - earlierp = (LLButton*) getChildByName("earlier_details_button", true); - laterp = (LLButton*) getChildByName("later_details_button", true); - textp = (LLTextEditor*) getChildByName("group_money_details_text", true); - panelp = (LLPanel*) getChildByName("group_money_details_tab", true); + earlierp = getChild("earlier_details_button", true); + laterp = getChild("later_details_button", true); + textp = getChild("group_money_details_text", true); + panelp = getChild("group_money_details_tab", true); if ( !can_view ) { @@ -718,8 +703,8 @@ BOOL LLPanelGroupLandMoney::postBuild() mGroupID); } - textp = (LLTextEditor*) getChildByName("group_money_planning_text", true); - panelp = (LLPanel*) getChildByName("group_money_planning_tab", true); + textp = getChild("group_money_planning_text", true); + panelp = getChild("group_money_planning_tab", true); if ( !can_view ) { @@ -736,10 +721,10 @@ BOOL LLPanelGroupLandMoney::postBuild() } //pull out the widgets for the L$ sales tab - earlierp = (LLButton*) getChildByName("earlier_sales_button", true); - laterp = (LLButton*) getChildByName("later_sales_button", true); - textp = (LLTextEditor*) getChildByName("group_money_sales_text", true); - panelp = (LLPanel*) getChildByName("group_money_sales_tab", true); + earlierp = getChild("earlier_sales_button", true); + laterp = getChild("later_sales_button", true); + textp = getChild("group_money_sales_text", true); + panelp = getChild("group_money_sales_tab", true); if ( !can_view ) { @@ -881,7 +866,7 @@ std::map LLGroupMoneyTabEventHandler::sT LLGroupMoneyTabEventHandler::LLGroupMoneyTabEventHandler(LLButton* earlier_buttonp, LLButton* later_buttonp, LLTextEditor* text_editorp, - LLTabContainerCommon* tab_containerp, + LLTabContainer* tab_containerp, LLPanel* panelp, const LLString& loading_text, const LLUUID& group_id, @@ -998,7 +983,7 @@ void LLGroupMoneyTabEventHandler::clickTabCallback(void* data, bool from_click) LLGroupMoneyDetailsTabEventHandler::LLGroupMoneyDetailsTabEventHandler(LLButton* earlier_buttonp, LLButton* later_buttonp, LLTextEditor* text_editorp, - LLTabContainerCommon* tab_containerp, + LLTabContainer* tab_containerp, LLPanel* panelp, const LLString& loading_text, const LLUUID& group_id) @@ -1138,7 +1123,7 @@ void LLPanelGroupLandMoney::processGroupAccountDetailsReply(LLMessageSystem* msg LLGroupMoneySalesTabEventHandler::LLGroupMoneySalesTabEventHandler(LLButton* earlier_buttonp, LLButton* later_buttonp, LLTextEditor* text_editorp, - LLTabContainerCommon* tab_containerp, + LLTabContainer* tab_containerp, LLPanel* panelp, const LLString& loading_text, const LLUUID& group_id) @@ -1315,7 +1300,7 @@ void LLPanelGroupLandMoney::processGroupAccountTransactionsReply(LLMessageSystem //*************************************************** LLGroupMoneyPlanningTabEventHandler::LLGroupMoneyPlanningTabEventHandler(LLTextEditor* text_editorp, - LLTabContainerCommon* tab_containerp, + LLTabContainer* tab_containerp, LLPanel* panelp, const LLString& loading_text, const LLUUID& group_id) diff --git a/linden/indra/newview/llpanelgroupnotices.cpp b/linden/indra/newview/llpanelgroupnotices.cpp index 5fdfdba..ef57aff 100644 --- a/linden/indra/newview/llpanelgroupnotices.cpp +++ b/linden/indra/newview/llpanelgroupnotices.cpp @@ -129,7 +129,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, { // check if inside //LLRect parent_rect = mParentView->getRect(); - //mRect.set(0, parent_rect.getHeight(), parent_rect.getWidth(), 0); + //getRect().set(0, parent_rect.getHeight(), parent_rect.getWidth(), 0); handled = TRUE; // check the type @@ -229,67 +229,62 @@ BOOL LLPanelGroupNotices::postBuild() { bool recurse = true; - mNoticesList = (LLScrollListCtrl*)getChildByName("notice_list",recurse); + mNoticesList = getChild("notice_list",recurse); mNoticesList->setCommitOnSelectionChange(TRUE); mNoticesList->setCommitCallback(onSelectNotice); mNoticesList->setCallbackUserData(this); - mBtnNewMessage = (LLButton*)getChildByName("create_new_notice",recurse); + mBtnNewMessage = getChild("create_new_notice",recurse); mBtnNewMessage->setClickedCallback(onClickNewMessage); mBtnNewMessage->setCallbackUserData(this); mBtnNewMessage->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_NOTICES_SEND)); - mBtnGetPastNotices = (LLButton*)getChildByName("refresh_notices",recurse); + mBtnGetPastNotices = getChild("refresh_notices",recurse); mBtnGetPastNotices->setClickedCallback(onClickRefreshNotices); mBtnGetPastNotices->setCallbackUserData(this); // Create - mCreateSubject = (LLLineEditor*)getChildByName("create_subject",recurse); - mCreateMessage = (LLTextEditor*)getChildByName("create_message",recurse); + mCreateSubject = getChild("create_subject",recurse); + mCreateMessage = getChild("create_message",recurse); - mCreateInventoryName = (LLLineEditor*)getChildByName("create_inventory_name",recurse); + mCreateInventoryName = getChild("create_inventory_name",recurse); mCreateInventoryName->setTabStop(FALSE); mCreateInventoryName->setEnabled(FALSE); - mCreateInventoryIcon = (LLIconCtrl*)getChildByName("create_inv_icon",recurse); + mCreateInventoryIcon = getChild("create_inv_icon",recurse); mCreateInventoryIcon->setVisible(FALSE); - mBtnSendMessage = (LLButton*)getChildByName("send_notice",recurse); + mBtnSendMessage = getChild("send_notice",recurse); mBtnSendMessage->setClickedCallback(onClickSendMessage); mBtnSendMessage->setCallbackUserData(this); - mBtnRemoveAttachment = (LLButton*)getChildByName("remove_attachment",recurse); + mBtnRemoveAttachment = getChild("remove_attachment",recurse); mBtnRemoveAttachment->setClickedCallback(onClickRemoveAttachment); mBtnRemoveAttachment->setCallbackUserData(this); mBtnRemoveAttachment->setEnabled(FALSE); // View - mViewSubject = (LLLineEditor*)getChildByName("view_subject",recurse); - mViewMessage = (LLTextEditor*)getChildByName("view_message",recurse); + mViewSubject = getChild("view_subject",recurse); + mViewMessage = getChild("view_message",recurse); - mViewInventoryName = (LLLineEditor*)getChildByName("view_inventory_name",recurse); + mViewInventoryName = getChild("view_inventory_name",recurse); mViewInventoryName->setTabStop(FALSE); mViewInventoryName->setEnabled(FALSE); - mViewInventoryIcon = (LLIconCtrl*)getChildByName("view_inv_icon",recurse); + mViewInventoryIcon = getChild("view_inv_icon",recurse); mViewInventoryIcon->setVisible(FALSE); - mBtnOpenAttachment = (LLButton*)getChildByName("open_attachment",recurse); + mBtnOpenAttachment = getChild("open_attachment",recurse); mBtnOpenAttachment->setClickedCallback(onClickOpenAttachment); mBtnOpenAttachment->setCallbackUserData(this); - LLTextBox *txt = (LLTextBox*) getChildByName("no_notices_text",false); - if (txt) - { - mNoNoticesStr = txt->getText(); - removeChild(txt, TRUE); - } + mNoNoticesStr = getString("no_notices_text"); - mPanelCreateNotice = (LLPanel*) getChildByName("panel_create_new_notice",recurse); - mPanelViewNotice = (LLPanel*) getChildByName("panel_view_past_notice",recurse); + mPanelCreateNotice = getChild("panel_create_new_notice",recurse); + mPanelViewNotice = getChild("panel_view_past_notice",recurse); // Must be in front of all other UI elements. - LLPanel* dtv = (LLPanel*)getChildByName("drop_target",recurse); + LLPanel* dtv = getChild("drop_target",recurse); LLGroupDropTarget* target = new LLGroupDropTarget("drop_target", dtv->getRect(), this, mGroupID); diff --git a/linden/indra/newview/llpanelgrouproles.cpp b/linden/indra/newview/llpanelgrouproles.cpp index 5a2d9db..194f880 100644 --- a/linden/indra/newview/llpanelgrouproles.cpp +++ b/linden/indra/newview/llpanelgrouproles.cpp @@ -133,7 +133,7 @@ BOOL LLPanelGroupRoles::postBuild() { lldebugs << "LLPanelGroupRoles::postBuild()" << llendl; - mSubTabContainer = (LLTabContainerCommon*) getChildByName("roles_tab_container"); + mSubTabContainer = getChild("roles_tab_container"); if (!mSubTabContainer) return FALSE; @@ -169,20 +169,8 @@ BOOL LLPanelGroupRoles::postBuild() mCurrentTab->activate(); // Read apply text from the xml file. - LLTextBox* txt; - // Don't recurse for this, since we don't currently have a recursive removeChild() - txt = (LLTextBox*)getChildByName("default_needs_apply_text"); - if (txt) - { - mDefaultNeedsApplyMesg = txt->getText(); - removeChild(txt, TRUE); - } - txt = (LLTextBox*)getChildByName("want_apply_text"); - if (txt) - { - mWantApplyMesg = txt->getText(); - removeChild(txt, TRUE); - } + mDefaultNeedsApplyMesg = getString("default_needs_apply_text"); + mWantApplyMesg = getString("want_apply_text"); return LLPanelGroupTab::postBuild(); } @@ -515,20 +503,20 @@ BOOL LLPanelGroupSubTab::postBuild() { // Hook up the search widgets. bool recurse = true; - mSearchLineEditor = (LLLineEditor*) getChildByName("search_text", recurse); + mSearchLineEditor = getChild("search_text", recurse); if (!mSearchLineEditor) return FALSE; mSearchLineEditor->setKeystrokeCallback(onSearchKeystroke); mSearchLineEditor->setCallbackUserData(this); - mSearchButton = (LLButton*) getChildByName("search_button", recurse); + mSearchButton = getChild("search_button", recurse); if (!mSearchButton) return FALSE; mSearchButton->setClickedCallback(onClickSearch); mSearchButton->setCallbackUserData(this); mSearchButton->setEnabled(FALSE); - mShowAllButton = (LLButton*) getChildByName("show_all_button", recurse); + mShowAllButton = getChild("show_all_button", recurse); if (!mShowAllButton) return FALSE; mShowAllButton->setClickedCallback(onClickShowAll); @@ -540,21 +528,21 @@ BOOL LLPanelGroupSubTab::postBuild() bool no_recurse = false; - LLIconCtrl* icon = (LLIconCtrl*) getChildByName("power_folder_icon",no_recurse); + LLIconCtrl* icon = getChild("power_folder_icon",no_recurse); if (icon && icon->getImage().notNull()) { mActionIcons["folder"] = icon->getImage(); removeChild(icon, TRUE); } - icon = (LLIconCtrl*) getChildByName("power_all_have_icon",no_recurse); + icon = getChild("power_all_have_icon",no_recurse); if (icon && icon->getImage().notNull()) { mActionIcons["full"] = icon->getImage(); removeChild(icon, TRUE); } - icon = (LLIconCtrl*) getChildByName("power_partial_icon",no_recurse); + icon = getChild("power_partial_icon",no_recurse); if (icon && icon->getImage().notNull()) { mActionIcons["partial"] = icon->getImage(); @@ -913,12 +901,12 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) // Look recursively from the parent to find all our widgets. bool recurse = true; - mHeader = (LLPanel*) parent->getChildByName("members_header", recurse); - mFooter = (LLPanel*) parent->getChildByName("members_footer", recurse); + mHeader = parent->getChild("members_header", recurse); + mFooter = parent->getChild("members_footer", recurse); - mMembersList = (LLNameListCtrl*) parent->getChildByName("member_list", recurse); - mAssignedRolesList = (LLScrollListCtrl*) parent->getChildByName("member_assigned_roles", recurse); - mAllowedActionsList = (LLScrollListCtrl*) parent->getChildByName("member_allowed_actions", recurse); + mMembersList = parent->getChild("member_list", recurse); + mAssignedRolesList = parent->getChild("member_assigned_roles", recurse); + mAllowedActionsList = parent->getChild("member_allowed_actions", recurse); if (!mMembersList || !mAssignedRolesList || !mAllowedActionsList) return FALSE; @@ -929,7 +917,7 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) // Show the member's profile on double click. mMembersList->setDoubleClickCallback(onMemberDoubleClick); - LLButton* button = (LLButton*) parent->getChildByName("member_invite", recurse); + LLButton* button = parent->getChild("member_invite", recurse); if ( button ) { button->setClickedCallback(onInviteMember); @@ -937,7 +925,7 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE)); } - mEjectBtn = (LLButton*) parent->getChildByName("member_eject", recurse); + mEjectBtn = parent->getChild("member_eject", recurse); if ( mEjectBtn ) { mEjectBtn->setClickedCallback(onEjectMembers); @@ -1467,19 +1455,16 @@ void LLPanelGroupMembersSubTab::applyMemberChanges() notifyObservers(); } -bool LLPanelGroupMembersSubTab::matchesSearchFilter(char* first, char* last) +bool LLPanelGroupMembersSubTab::matchesSearchFilter(const std::string& fullname) { // If the search filter is empty, everything passes. if (mSearchFilter.empty()) return true; // Create a full name, and compare it to the search filter. - LLString fullname; - fullname.assign(first); - fullname.append(1, ' '); - fullname.append(last); - LLString::toLower(fullname); + std::string fullname_lc(fullname); + LLString::toLower(fullname_lc); - std::string::size_type match = fullname.find(mSearchFilter); + std::string::size_type match = fullname_lc.find(mSearchFilter); if (std::string::npos == match) { @@ -1682,8 +1667,6 @@ void LLPanelGroupMembersSubTab::updateMembers() LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end(); - char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ - char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/ S32 i = 0; for( ; mMemberProgress != end && igetName(mMemberProgress->first, first, last)) + std::string fullname; + if (gCacheName->getFullName(mMemberProgress->first, fullname)) { - if ( !matchesSearchFilter(first, last) ) + if ( !matchesSearchFilter(fullname) ) { add_member = false; } @@ -1775,19 +1759,19 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root) // Look recursively from the parent to find all our widgets. bool recurse = true; - mHeader = (LLPanel*) parent->getChildByName("roles_header", recurse); - mFooter = (LLPanel*) parent->getChildByName("roles_footer", recurse); + mHeader = parent->getChild("roles_header", recurse); + mFooter = parent->getChild("roles_footer", recurse); - mRolesList = (LLScrollListCtrl*) parent->getChildByName("role_list", recurse); - mAssignedMembersList = (LLNameListCtrl*) parent->getChildByName("role_assigned_members", recurse); - mAllowedActionsList = (LLScrollListCtrl*) parent->getChildByName("role_allowed_actions", recurse); + mRolesList = parent->getChild("role_list", recurse); + mAssignedMembersList = parent->getChild("role_assigned_members", recurse); + mAllowedActionsList = parent->getChild("role_allowed_actions", recurse); - mRoleName = (LLLineEditor*) parent->getChildByName("role_name", recurse); - mRoleTitle = (LLLineEditor*) parent->getChildByName("role_title", recurse); - mRoleDescription = (LLTextEditor*) parent->getChildByName("role_description", recurse); + mRoleName = parent->getChild("role_name", recurse); + mRoleTitle = parent->getChild("role_title", recurse); + mRoleDescription = parent->getChild("role_description", recurse); - mMemberVisibleCheck = (LLCheckBoxCtrl*) parent->getChildByName("role_visible_in_list", recurse); + mMemberVisibleCheck = parent->getChild("role_visible_in_list", recurse); if (!mRolesList || !mAssignedMembersList || !mAllowedActionsList || !mRoleName || !mRoleTitle || !mRoleDescription || !mMemberVisibleCheck) @@ -1796,15 +1780,10 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root) return FALSE; } - LLTextBox* txt = (LLTextBox*) parent->getChildByName("cant_delete_role", FALSE); - if (txt) - { - mRemoveEveryoneTxt = txt->getText(); - parent->removeChild(txt, TRUE); - } + mRemoveEveryoneTxt = getString("cant_delete_role"); mCreateRoleButton = - (LLButton*) parent->getChildByName("role_create", recurse); + parent->getChild("role_create", recurse); if ( mCreateRoleButton ) { mCreateRoleButton->setCallbackUserData(this); @@ -1813,7 +1792,7 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root) } mDeleteRoleButton = - (LLButton*) parent->getChildByName("role_delete", recurse); + parent->getChild("role_delete", recurse); if ( mDeleteRoleButton ) { mDeleteRoleButton->setCallbackUserData(this); @@ -2488,14 +2467,14 @@ BOOL LLPanelGroupActionsSubTab::postBuildSubTab(LLView* root) // Look recursively from the parent to find all our widgets. bool recurse = true; - mHeader = (LLPanel*) parent->getChildByName("actions_header", recurse); - mFooter = (LLPanel*) parent->getChildByName("actions_footer", recurse); + mHeader = parent->getChild("actions_header", recurse); + mFooter = parent->getChild("actions_footer", recurse); - mActionDescription = (LLTextEditor*) parent->getChildByName("action_description", recurse); + mActionDescription = parent->getChild("action_description", recurse); - mActionList = (LLScrollListCtrl*) parent->getChildByName("action_list",recurse); - mActionRoles = (LLScrollListCtrl*) parent->getChildByName("action_roles",recurse); - mActionMembers = (LLNameListCtrl*) parent->getChildByName("action_members",recurse); + mActionList = parent->getChild("action_list",recurse); + mActionRoles = parent->getChild("action_roles",recurse); + mActionMembers = parent->getChild("action_members",recurse); if (!mActionList || !mActionDescription || !mActionRoles || !mActionMembers) return FALSE; diff --git a/linden/indra/newview/llpanelgrouproles.h b/linden/indra/newview/llpanelgrouproles.h index f84cb93..5a0ea31 100644 --- a/linden/indra/newview/llpanelgrouproles.h +++ b/linden/indra/newview/llpanelgrouproles.h @@ -93,7 +93,7 @@ public: protected: LLPanelGroupTab* mCurrentTab; LLPanelGroupTab* mRequestedTab; - LLTabContainerCommon* mSubTabContainer; + LLTabContainer* mSubTabContainer; BOOL mFirstUse; BOOL mIgnoreTransition; @@ -204,7 +204,7 @@ protected: typedef std::map role_change_data_map_t; typedef std::map member_role_changes_map_t; - bool matchesSearchFilter(char* first, char* last); + bool matchesSearchFilter(const std::string& fullname); U64 getAgentPowersBasedOnRoleChanges(const LLUUID& agent_id); bool getRoleChangeType(const LLUUID& member_id, diff --git a/linden/indra/newview/llpanelgroupvoting.cpp b/linden/indra/newview/llpanelgroupvoting.cpp index 58a4842..d0e513c 100644 --- a/linden/indra/newview/llpanelgroupvoting.cpp +++ b/linden/indra/newview/llpanelgroupvoting.cpp @@ -234,8 +234,8 @@ void LLPanelGroupVoting::impl::setEnableListProposals() return; - mPanel.childSetText("proposal_header", mPanel.childGetText("proposals_header_view_txt")); - mPanel.childSetText("proposal_instructions", mPanel.childGetText("proposals_header_view_inst")); + mPanel.childSetText("proposal_header", mPanel.getString("proposals_header_view_txt")); + mPanel.childSetText("proposal_instructions", mPanel.getString("proposals_header_view_inst")); mPanel.childSetVisible("proposal_lbl", FALSE); mPanel.childSetVisible("proposal_voting_lbl", TRUE); mProposals->setVisible(TRUE); @@ -389,7 +389,7 @@ void LLPanelGroupVoting::impl::setEnableVoteProposal() if (already_voted == "Yes") { - LLUIString votestr = mPanel.childGetText("proposals_header_voted_inst"); + LLUIString votestr = mPanel.getString("proposals_header_voted_inst"); votestr.setArg("[VOTE]", vote_cast); mPanel.childSetText("proposal_instructions", votestr.getString()); @@ -399,14 +399,14 @@ void LLPanelGroupVoting::impl::setEnableVoteProposal() } else { - mPanel.childSetText("proposal_instructions", mPanel.childGetText("proposals_header_vote_inst")); + mPanel.childSetText("proposal_instructions", mPanel.getString("proposals_header_vote_inst")); mBtnYes->setEnabled(TRUE); mBtnNo->setEnabled(TRUE); mBtnAbstain->setEnabled(TRUE); } - mPanel.childSetText("proposal_header", mPanel.childGetText("proposals_header_vote_txt")); + mPanel.childSetText("proposal_header", mPanel.getString("proposals_header_vote_txt")); mPanel.childSetVisible("proposal_lbl", TRUE); mPanel.childSetVisible("proposal_voting_lbl", FALSE); mProposals->setVisible(FALSE); @@ -453,8 +453,8 @@ void LLPanelGroupVoting::impl::setEnableCreateProposal() if ( !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) ) return; - mPanel.childSetText("proposal_header", mPanel.childGetText("proposals_header_create_txt")); - mPanel.childSetText("proposal_instructions", mPanel.childGetText("proposals_header_create_inst")); + mPanel.childSetText("proposal_header", mPanel.getString("proposals_header_create_txt")); + mPanel.childSetText("proposal_instructions", mPanel.getString("proposals_header_create_inst")); mPanel.childSetVisible("proposal_lbl", TRUE); mPanel.childSetVisible("proposal_voting_lbl", FALSE); mProposals->setVisible(FALSE); @@ -634,11 +634,11 @@ void LLPanelGroupVoting::handleResponse( if (success) { - args["[MESSAGE]"] = self->mPanel.childGetText("vote_recorded"); + args["[MESSAGE]"] = self->mPanel.getString("vote_recorded"); } else { - args["[MESSAGE]"] = self->mPanel.childGetText("vote_previously_recorded"); + args["[MESSAGE]"] = self->mPanel.getString("vote_previously_recorded"); } LLNotifyBox::showXml("SystemMessage", args); @@ -1284,7 +1284,7 @@ void LLPanelGroupVoting::impl::onClickYes(void *userdata) if ( self ) { - self->mPanel.childSetText("proposal_instructions", self->mPanel.childGetText("proposals_submit_yes_txt")); + self->mPanel.childSetText("proposal_instructions", self->mPanel.getString("proposals_submit_yes_txt")); self->sendGroupProposalBallot("Yes"); } } @@ -1296,7 +1296,7 @@ void LLPanelGroupVoting::impl::onClickNo(void *userdata) if ( self ) { - self->mPanel.childSetText("proposal_instructions", self->mPanel.childGetText("proposals_submit_no_txt")); + self->mPanel.childSetText("proposal_instructions", self->mPanel.getString("proposals_submit_no_txt")); self->sendGroupProposalBallot("No"); } } @@ -1308,7 +1308,7 @@ void LLPanelGroupVoting::impl::onClickAbstain(void *userdata) if ( self ) { - self->mPanel.childSetText("proposal_instructions", self->mPanel.childGetText("proposals_submit_abstain_txt")); + self->mPanel.childSetText("proposal_instructions", self->mPanel.getString("proposals_submit_abstain_txt")); self->sendGroupProposalBallot("Abstain"); } } @@ -1328,12 +1328,12 @@ void LLPanelGroupVoting::impl::onClickSubmitProposal(void *userdata) { //throw up an error dialog LLString::format_map_t args; - args["[MESSAGE]"] = self->mPanel.childGetText("empty_proposal_txt"); + args["[MESSAGE]"] = self->mPanel.getString("empty_proposal_txt"); gViewerWindow->alertXml("GenericAlert", args); return; } - self->mPanel.childSetText("proposal_instructions", self->mPanel.childGetText("proposals_submit_new_txt")); + self->mPanel.childSetText("proposal_instructions", self->mPanel.getString("proposals_submit_new_txt")); self->sendStartGroupProposal(); } } @@ -1458,54 +1458,54 @@ BOOL LLPanelGroupVoting::postBuild() { bool recurse = true; - mImpl->mDurationText = (LLTextBox*) getChildByName("duration_text", + mImpl->mDurationText = getChild("duration_text", recurse); - mImpl->mQuorum = (LLSpinCtrl*) getChildByName("quorum", recurse); - mImpl->mQuorumLbl = (LLTextBox*) getChildByName("quorum_lbl", recurse); - mImpl->mDuration = (LLSpinCtrl*) getChildByName("duration", recurse); - mImpl->mDurationLbl = (LLTextBox*) getChildByName("duration_lbl", recurse); - mImpl->mMajority = (LLRadioGroup*) getChildByName("majority", recurse); - mImpl->mMajorityLbl = (LLTextBox*) getChildByName("majority_lbl", recurse); - - mImpl->mStartLbl = (LLTextBox*) getChildByName("start_lbl", recurse); - mImpl->mEndLbl = (LLTextBox*) getChildByName("end_lbl", recurse); - mImpl->mStartDate = (LLTextBox*) getChildByName("start_date", recurse); - mImpl->mEndDate = (LLTextBox*) getChildByName("end_date", recurse); - - mImpl->mBtnYes = (LLButton*) getChildByName("btn_yes", recurse); - mImpl->mBtnNo = (LLButton*) getChildByName("btn_no", recurse); - mImpl->mBtnAbstain = (LLButton*) getChildByName("btn_abstain", recurse); + mImpl->mQuorum = getChild("quorum", recurse); + mImpl->mQuorumLbl = getChild("quorum_lbl", recurse); + mImpl->mDuration = getChild("duration", recurse); + mImpl->mDurationLbl = getChild("duration_lbl", recurse); + mImpl->mMajority = getChild("majority", recurse); + mImpl->mMajorityLbl = getChild("majority_lbl", recurse); + + mImpl->mStartLbl = getChild("start_lbl", recurse); + mImpl->mEndLbl = getChild("end_lbl", recurse); + mImpl->mStartDate = getChild("start_date", recurse); + mImpl->mEndDate = getChild("end_date", recurse); + + mImpl->mBtnYes = getChild("btn_yes", recurse); + mImpl->mBtnNo = getChild("btn_no", recurse); + mImpl->mBtnAbstain = getChild("btn_abstain", recurse); mImpl->mProposals = - (LLScrollListCtrl*) getChildByName("proposals", recurse); + getChild("proposals", recurse); mImpl->mProposalText = - (LLTextEditor*) getChildByName("proposal_text", recurse); + getChild("proposal_text", recurse); - mImpl->mBtnCreateProposal = (LLButton*) getChildByName("btn_proposal", + mImpl->mBtnCreateProposal = getChild("btn_proposal", recurse); - mImpl->mBtnSubmitProposal = (LLButton*) getChildByName("btn_submit", + mImpl->mBtnSubmitProposal = getChild("btn_submit", recurse); - mImpl->mBtnCancelProposal = (LLButton*) getChildByName("btn_cancel", + mImpl->mBtnCancelProposal = getChild("btn_cancel", recurse); mImpl->mBtnViewProposalList = - (LLButton*) getChildByName("btn_view_proposal_list", recurse); + getChild("btn_view_proposal_list", recurse); mImpl->mBtnViewProposalItem = - (LLButton*) getChildByName("btn_view_proposal_item", recurse); + getChild("btn_view_proposal_item", recurse); - mImpl->mVotesHistory = (LLScrollListCtrl*)getChildByName("history_list", + mImpl->mVotesHistory = getChild("history_list", recurse); - mImpl->mVotesHistoryLbl = (LLTextBox*) getChildByName("history_list_lbl", + mImpl->mVotesHistoryLbl = getChild("history_list_lbl", recurse); - mImpl->mVoteHistoryText = (LLTextEditor*) getChildByName("vote_text", + mImpl->mVoteHistoryText = getChild("vote_text", recurse); - mImpl->mVoteHistoryTextLbl = (LLTextBox*) getChildByName("vote_text_lbl", + mImpl->mVoteHistoryTextLbl = getChild("vote_text_lbl", recurse); mImpl->mBtnViewHistoryList = - (LLButton*)getChildByName("btn_view_history_list", recurse); + getChild("btn_view_history_list", recurse); mImpl->mBtnViewHistoryItem = - (LLButton*)getChildByName("btn_view_history_item", recurse); + getChild("btn_view_history_item", recurse); mImpl->updateQuorumText(); diff --git a/linden/indra/newview/llpanelinput.cpp b/linden/indra/newview/llpanelinput.cpp index 77ebec9..7fac7f8 100644 --- a/linden/indra/newview/llpanelinput.cpp +++ b/linden/indra/newview/llpanelinput.cpp @@ -84,6 +84,7 @@ BOOL LLPanelInput::postBuild() requires("dynamic camera", WIDGET_TYPE_SLIDER); requires("edit camera movement", WIDGET_TYPE_CHECKBOX); requires("appearance camera movement", WIDGET_TYPE_CHECKBOX); + requires("avfp", WIDGET_TYPE_CHECKBOX); if (!checkRequirements()) { @@ -112,6 +113,9 @@ void LLPanelInput::refresh() mAppearanceCameraMovement = gSavedSettings.getBOOL("AppearanceCameraMovement"); mDynamicCameraStrengthVal = gSavedSettings.getF32("DynamicCameraStrength"); mNumpadControlVal = gSavedSettings.getS32("NumpadControl"); + + // First Person Visibility + mFirstPersonAvatarVisible = gSavedSettings.getBOOL("FirstPersonAvatarVisible"); } void LLPanelInput::apply() @@ -128,5 +132,6 @@ void LLPanelInput::cancel() gSavedSettings.setBOOL("AppearanceCameraMovement", mAppearanceCameraMovement); gSavedSettings.setF32("DynamicCameraStrength", mDynamicCameraStrengthVal); gSavedSettings.setS32("NumpadControl", mNumpadControlVal); + gSavedSettings.setBOOL("FirstPersonAvatarVisible", mFirstPersonAvatarVisible); } diff --git a/linden/indra/newview/llpanelinput.h b/linden/indra/newview/llpanelinput.h index 0a50462..c90c03c 100644 --- a/linden/indra/newview/llpanelinput.h +++ b/linden/indra/newview/llpanelinput.h @@ -56,6 +56,7 @@ protected: BOOL mInvertMouse; BOOL mEditCameraMovement; BOOL mAppearanceCameraMovement; + BOOL mFirstPersonAvatarVisible; F32 mDynamicCameraStrengthVal; S32 mNumpadControlVal; diff --git a/linden/indra/newview/llpanelinventory.cpp b/linden/indra/newview/llpanelinventory.cpp index e39f45f..0d85e94 100644 --- a/linden/indra/newview/llpanelinventory.cpp +++ b/linden/indra/newview/llpanelinventory.cpp @@ -147,7 +147,7 @@ public: virtual BOOL hasChildren() const { return FALSE; } virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; } // LLDragAndDropBridge functionality - virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id); + virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const; virtual BOOL dragOrDrop(MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data); @@ -543,7 +543,7 @@ void LLTaskInvFVBridge::pasteFromClipboard() { } -BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) +BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const { //llinfos << "LLTaskInvFVBridge::startDrag()" << llendl; if(mPanel) @@ -659,9 +659,10 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) for (itor = list->begin(); itor != list->end(); ++itor) { LLString name = (*itor)->getName(); - if (name == "Task Buy" && (*itor)->getWidgetTag() == LL_MENU_ITEM_CALL_GL_TAG) + LLMenuItemCallGL* menu_itemp = dynamic_cast(*itor); + if (name == "Task Buy" && menu_itemp) { - ((LLMenuItemCallGL*)(*itor))->setLabel(label); + menu_itemp->setLabel(label); } } } @@ -1017,9 +1018,10 @@ void LLTaskSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) for (itor = list->begin(); itor != list->end(); ++itor) { LLString name = (*itor)->getName(); - if (name == "Task Buy" && (*itor)->getWidgetTag() == LL_MENU_ITEM_CALL_GL_TAG) + LLMenuItemCallGL* menu_itemp = dynamic_cast(*itor); + if (name == "Task Buy" && menu_itemp) { - ((LLMenuItemCallGL*)(*itor))->setLabel(label); + menu_itemp->setLabel(label); } } } @@ -1645,7 +1647,7 @@ void LLPanelInventory::reset() // this ensures that we never say "searching..." or "no items found" mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); - LLRect scroller_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect scroller_rect(0, getRect().getHeight(), getRect().getWidth(), 0); mScroller = new LLScrollableContainerView( "task inventory scroller", scroller_rect, mFolders ); mScroller->setFollowsAll(); @@ -1795,8 +1797,7 @@ void LLPanelInventory::createFolderViews(LLInventoryObject* inventory_root, Inve typedef std::pair obj_folder_pair; -// Replace LLLinkedList with std:: equivalant. -void LLPanelInventory::createViewsForCategory(InventoryObjectList* inventory, //LLLinkedList* inventory, +void LLPanelInventory::createViewsForCategory(InventoryObjectList* inventory, LLInventoryObject* parent, LLFolderViewFolder* folder) { @@ -1933,7 +1934,7 @@ void LLPanelInventory::draw() if((LLUUID::null != mTaskUUID) && (!mHaveInventory)) { LLFontGL::sSansSerif->renderUTF8("Loading contents...", 0, - (S32)(mRect.getWidth() * 0.5f), + (S32)(getRect().getWidth() * 0.5f), 10, LLColor4( 1, 1, 1, 1 ), LLFontGL::HCENTER, @@ -1942,7 +1943,7 @@ void LLPanelInventory::draw() else if(mHaveInventory) { LLFontGL::sSansSerif->renderUTF8("No contents", 0, - (S32)(mRect.getWidth() * 0.5f), + (S32)(getRect().getWidth() * 0.5f), 10, LLColor4( 1, 1, 1, 1 ), LLFontGL::HCENTER, diff --git a/linden/indra/newview/llpanelinventory.h b/linden/indra/newview/llpanelinventory.h index ddd9c5d..9315ccd 100644 --- a/linden/indra/newview/llpanelinventory.h +++ b/linden/indra/newview/llpanelinventory.h @@ -68,7 +68,6 @@ class LLPanelInventory : public LLPanel, public LLVOInventoryListener protected: LLScrollableContainerView* mScroller; LLFolderView* mFolders; - LLLinkedList mBridge; LLUUID mTaskUUID; BOOL mHaveInventory; diff --git a/linden/indra/newview/llpanelland.cpp b/linden/indra/newview/llpanelland.cpp index 2dfc911..5edd304 100644 --- a/linden/indra/newview/llpanelland.cpp +++ b/linden/indra/newview/llpanelland.cpp @@ -253,5 +253,5 @@ void LLPanelLandInfo::onClickAbout(void*) gParcelMgr->selectParcelInRectangle(); } - LLFloaterLand::show(); + LLFloaterLand::showInstance(); } diff --git a/linden/indra/newview/llpanellandmedia.cpp b/linden/indra/newview/llpanellandmedia.cpp new file mode 100644 index 0000000..c8f79b5 --- /dev/null +++ b/linden/indra/newview/llpanellandmedia.cpp @@ -0,0 +1,401 @@ +/** + * @file llpanellandmedia.cpp + * @brief Allows configuration of "media" for a land parcel, + * for example movies, web pages, and audio. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanellandmedia.h" + +// viewer includes +#include "llmimetypes.h" +#include "llviewerparcelmgr.h" +#include "llvieweruictrlfactory.h" + +// library includes +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llfloaterurlentry.h" +#include "llfocusmgr.h" +#include "lllineeditor.h" +#include "llparcel.h" +#include "lltextbox.h" +#include "llradiogroup.h" +#include "llspinctrl.h" +#include "llsdutil.h" +#include "lltexturectrl.h" +#include "roles_constants.h" + +// Values for the parcel voice settings radio group +enum +{ + kRadioVoiceChatEstate = 0, + kRadioVoiceChatPrivate = 1, + kRadioVoiceChatDisable = 2 +}; + +//--------------------------------------------------------------------------- +// LLPanelLandMedia +//--------------------------------------------------------------------------- + +LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel) +: LLPanel("land_media_panel"), mParcel(parcel) +{ +} + + +// virtual +LLPanelLandMedia::~LLPanelLandMedia() +{ + // close LLFloaterURLEntry? +} + + +BOOL LLPanelLandMedia::postBuild() +{ + mCheckSoundLocal = LLUICtrlFactory::getCheckBoxByName(this, "check sound local"); + childSetCommitCallback("check sound local", onCommitAny, this); + + mRadioVoiceChat = LLUICtrlFactory::getRadioGroupByName(this, "parcel_voice_channel"); + childSetCommitCallback("parcel_voice_channel", onCommitAny, this); + + mMusicURLEdit = LLUICtrlFactory::getLineEditorByName(this, "music_url"); + childSetCommitCallback("music_url", onCommitAny, this); + + mMediaTextureCtrl = LLViewerUICtrlFactory::getTexturePickerByName(this, "media texture"); + if (mMediaTextureCtrl) + { + mMediaTextureCtrl->setCommitCallback( onCommitAny ); + mMediaTextureCtrl->setCallbackUserData( this ); + mMediaTextureCtrl->setAllowNoTexture ( TRUE ); + mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + else + { + llwarns << "LLViewerUICtrlFactory::getTexturePickerByName() returned NULL for 'media texure'" << llendl; + } + + mMediaAutoScaleCheck = LLUICtrlFactory::getCheckBoxByName(this, "media_auto_scale"); + childSetCommitCallback("media_auto_scale", onCommitAny, this); + + mMediaLoopCheck = LLUICtrlFactory::getCheckBoxByName(this, "media_loop"); + childSetCommitCallback("media_loop", onCommitAny, this); + + mMediaUrlCheck = LLUICtrlFactory::getCheckBoxByName(this, "hide_media_url"); + childSetCommitCallback("hide_media_url", onCommitAny, this); + + mMusicUrlCheck = LLUICtrlFactory::getCheckBoxByName(this, "hide_music_url"); + childSetCommitCallback("hide_music_url", onCommitAny, this); + + mMediaURLEdit = LLUICtrlFactory::getLineEditorByName(this, "media_url"); + childSetCommitCallback("media_url", onCommitAny, this); + + mMediaDescEdit = LLUICtrlFactory::getLineEditorByName(this, "url_description"); + childSetCommitCallback("url_description", onCommitAny, this); + + mMediaTypeCombo = LLUICtrlFactory::getComboBoxByName(this, "media type"); + childSetCommitCallback("media type", onCommitType, this); + populateMIMECombo(); + mMediaTypeCombo->sortByName(); + + mMediaWidthCtrl = LLUICtrlFactory::getSpinnerByName(this, "media_size_width"); + childSetCommitCallback("media_size_width", onCommitAny, this); + mMediaHeightCtrl = LLUICtrlFactory::getSpinnerByName(this, "media_size_height"); + childSetCommitCallback("media_size_height", onCommitAny, this); + mMediaSizeCtrlLabel = LLUICtrlFactory::getTextBoxByName(this, "media_size"); + + mSetURLButton = LLUICtrlFactory::getButtonByName(this, "set_media_url"); + childSetAction("set_media_url", onSetBtn, this); + + return TRUE; +} + + +// public +void LLPanelLandMedia::refresh() +{ + LLParcel *parcel = mParcel->getParcel(); + + if (!parcel) + { + clearCtrls(); + } + else + { + // something selected, hooray! + + // Display options + BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA); + + mCheckSoundLocal->set( parcel->getSoundLocal() ); + mCheckSoundLocal->setEnabled( can_change_media ); + + if(parcel->getVoiceEnabled()) + { + if(parcel->getVoiceUseEstateChannel()) + mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate); + else + mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatPrivate); + } + else + { + mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable); + } + + mRadioVoiceChat->setEnabled( can_change_media ); + + mMusicURLEdit->setText(parcel->getMusicURL()); + mMusicURLEdit->setEnabled( can_change_media ); + + mMediaURLEdit->setText(parcel->getMediaURL()); + mMediaURLEdit->setEnabled( FALSE ); + + mMediaDescEdit->setText(LLString(parcel->getMediaDesc())); + mMediaDescEdit->setEnabled( can_change_media ); + + std::string mime_type = parcel->getMediaType(); + if (mime_type.empty()) + { + mime_type = "none/none"; + } + setMediaType(mime_type); + mMediaTypeCombo->setEnabled( can_change_media ); + childSetText("mime_type", mime_type); + + mMediaUrlCheck->set( parcel->getObscureMedia() ); + mMediaUrlCheck->setEnabled( can_change_media ); + + mMusicUrlCheck->set( parcel->getObscureMusic() ); + mMusicUrlCheck->setEnabled( can_change_media ); + + // don't display urls if you're not able to change it + // much requested change in forums so people can't 'steal' urls + // NOTE: bug#2009 means this is still vunerable - however, bug + // should be closed since this bug opens up major security issues elsewhere. + bool obscure_media = ! can_change_media && parcel->getObscureMedia(); + bool obscure_music = ! can_change_media && parcel->getObscureMusic(); + + // Special code to disable asterixes for html type + if(mime_type == "text/html") + { + obscure_media = false; + mMediaUrlCheck->set( 0 ); + mMediaUrlCheck->setEnabled( false ); + } + + mMusicURLEdit->setDrawAsterixes( obscure_music ); + mMediaURLEdit->setDrawAsterixes( obscure_media ); + + mMediaAutoScaleCheck->set( parcel->getMediaAutoScale () ); + mMediaAutoScaleCheck->setEnabled ( can_change_media ); + + // Special code to disable looping checkbox for HTML MIME type + // (DEV-10042 -- Parcel Media: "Loop Media" should be disabled for static media types) + bool allow_looping = LLMIMETypes::findAllowLooping( mime_type ); + if ( allow_looping ) + mMediaLoopCheck->set( parcel->getMediaLoop () ); + else + mMediaLoopCheck->set( false ); + mMediaLoopCheck->setEnabled ( can_change_media && allow_looping ); + + // disallow media size change for mime types that don't allow it + bool allow_resize = LLMIMETypes::findAllowResize( mime_type ); + if ( allow_resize ) + mMediaWidthCtrl->setValue( parcel->getMediaWidth() ); + else + mMediaWidthCtrl->setValue( 0 ); + mMediaWidthCtrl->setEnabled ( can_change_media && allow_resize ); + + if ( allow_resize ) + mMediaHeightCtrl->setValue( parcel->getMediaHeight() ); + else + mMediaHeightCtrl->setValue( 0 ); + mMediaHeightCtrl->setEnabled ( can_change_media && allow_resize ); + + // enable/disable for text label for completeness + mMediaSizeCtrlLabel->setEnabled( can_change_media && allow_resize ); + + LLUUID tmp = parcel->getMediaID(); + mMediaTextureCtrl->setImageAssetID ( parcel->getMediaID() ); + mMediaTextureCtrl->setEnabled( can_change_media ); + + mSetURLButton->setEnabled( can_change_media ); + + #if 0 + // there is a media url and a media texture selected + if ( ( ! ( std::string ( parcel->getMediaURL() ).empty () ) ) && ( ! ( parcel->getMediaID ().isNull () ) ) ) + { + // turn on transport controls if allowed for this parcel + mMediaStopButton->setEnabled ( editable ); + mMediaStartButton->setEnabled ( editable ); + } + else + { + // no media url or no media texture + mMediaStopButton->setEnabled ( FALSE ); + mMediaStartButton->setEnabled ( FALSE ); + }; + #endif + + LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mURLEntryFloater.get(); + if (floater_url_entry) + { + floater_url_entry->updateFromLandMediaPanel(); + } + } +} + +void LLPanelLandMedia::populateMIMECombo() +{ + LLMIMETypes::mime_widget_set_map_t::const_iterator it; + for (it = LLMIMETypes::sWidgetMap.begin(); it != LLMIMETypes::sWidgetMap.end(); ++it) + { + const LLString& mime_type = it->first; + const LLMIMETypes::LLMIMEWidgetSet& info = it->second; + mMediaTypeCombo->add(info.mLabel, mime_type); + } +} +void LLPanelLandMedia::setMediaType(const LLString& mime_type) +{ + LLParcel *parcel = mParcel->getParcel(); + if(parcel) + parcel->setMediaType(mime_type.c_str()); + + LLString media_key = LLMIMETypes::widgetType(mime_type); + mMediaTypeCombo->setValue(media_key); + childSetText("mime_type", mime_type); +} + +void LLPanelLandMedia::setMediaURL(const LLString& media_url) +{ + mMediaURLEdit->setText(media_url); + mMediaURLEdit->onCommit(); + +} + +// static +void LLPanelLandMedia::onCommitType(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; + std::string current_type = LLMIMETypes::widgetType(self->childGetText("mime_type")); + std::string new_type = self->mMediaTypeCombo->getValue(); + if(current_type != new_type) + { + self->childSetText("mime_type", LLMIMETypes::findDefaultMimeType(new_type)); + } + onCommitAny(ctrl, userdata); + +} +// static +void LLPanelLandMedia::onCommitAny(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; + + LLParcel* parcel = self->mParcel->getParcel(); + if (!parcel) + { + return; + } + + // Extract data from UI + BOOL sound_local = self->mCheckSoundLocal->get(); + int voice_setting = self->mRadioVoiceChat->getSelectedIndex(); + std::string music_url = self->mMusicURLEdit->getText(); + std::string media_url = self->mMediaURLEdit->getText(); + std::string media_desc = self->mMediaDescEdit->getText(); + std::string mime_type = self->childGetText("mime_type"); + U8 media_auto_scale = self->mMediaAutoScaleCheck->get(); + U8 media_loop = self->mMediaLoopCheck->get(); + U8 obscure_media = self->mMediaUrlCheck->get(); + U8 obscure_music = self->mMusicUrlCheck->get(); + S32 media_width = (S32)self->mMediaWidthCtrl->get(); + S32 media_height = (S32)self->mMediaHeightCtrl->get(); + LLUUID media_id = self->mMediaTextureCtrl->getImageAssetID(); + + self->childSetText("mime_type", mime_type); + + BOOL voice_enabled; + BOOL voice_estate_chan; + + switch(voice_setting) + { + default: + case kRadioVoiceChatEstate: + voice_enabled = TRUE; + voice_estate_chan = TRUE; + break; + case kRadioVoiceChatPrivate: + voice_enabled = TRUE; + voice_estate_chan = FALSE; + break; + case kRadioVoiceChatDisable: + voice_enabled = FALSE; + voice_estate_chan = FALSE; + break; + } + + // Remove leading/trailing whitespace (common when copying/pasting) + LLString::trim(music_url); + LLString::trim(media_url); + + // Push data into current parcel + parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, voice_enabled); + parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, voice_estate_chan); + parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local); + parcel->setMusicURL(music_url.c_str()); + parcel->setMediaURL(media_url.c_str()); + parcel->setMediaType(mime_type.c_str()); + parcel->setMediaDesc(media_desc.c_str()); + parcel->setMediaWidth(media_width); + parcel->setMediaHeight(media_height); + parcel->setMediaID(media_id); + parcel->setMediaAutoScale ( media_auto_scale ); + parcel->setMediaLoop ( media_loop ); + parcel->setObscureMedia( obscure_media ); + parcel->setObscureMusic( obscure_music ); + + // Send current parcel data upstream to server + gParcelMgr->sendParcelPropertiesUpdate( parcel ); + + // Might have changed properties, so let's redraw! + self->refresh(); +} +// static +void LLPanelLandMedia::onSetBtn(void *userdata) +{ + LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; + self->mURLEntryFloater = LLFloaterURLEntry::show( self->getHandle() ); + LLFloater* parent_floater = gFloaterView->getParentFloater(self); + if (parent_floater) + { + parent_floater->addDependentFloater(self->mURLEntryFloater.get()); + } +} diff --git a/linden/indra/newview/llpanellandmedia.h b/linden/indra/newview/llpanellandmedia.h new file mode 100644 index 0000000..8efa0f5 --- /dev/null +++ b/linden/indra/newview/llpanellandmedia.h @@ -0,0 +1,80 @@ +/** + * @file llpanellandmedia.h + * @brief Allows configuration of "media" for a land parcel, + * for example movies, web pages, and audio. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLPANELLANDMEDIA_H +#define LLPANELLANDMEDIA_H + +#include "lllineeditor.h" +#include "llpanel.h" +#include "llparcelselection.h" +#include "lluifwd.h" // widget pointer types + +class LLPanelLandMedia +: public LLPanel +{ +public: + LLPanelLandMedia(LLSafeHandle& parcelp); + /*virtual*/ ~LLPanelLandMedia(); + /*virtual*/ BOOL postBuild(); + void refresh(); + void setMediaType(const LLString& media_type); + void setMediaURL(const LLString& media_type); + const LLString& getMediaURL() { return mMediaURLEdit->getText(); } + +private: + void populateMIMECombo(); + static void onCommitAny(LLUICtrl* ctrl, void *userdata); + static void onCommitType(LLUICtrl* ctrl, void *userdata); + static void onSetBtn(void* userdata); + +private: + LLCheckBoxCtrl* mCheckSoundLocal; + LLRadioGroup* mRadioVoiceChat; + LLLineEditor* mMusicURLEdit; + LLLineEditor* mMediaURLEdit; + LLLineEditor* mMediaDescEdit; + LLComboBox* mMediaTypeCombo; + LLButton* mSetURLButton; + LLSpinCtrl* mMediaHeightCtrl; + LLSpinCtrl* mMediaWidthCtrl; + LLTextBox* mMediaSizeCtrlLabel; + LLTextureCtrl* mMediaTextureCtrl; + LLCheckBoxCtrl* mMediaAutoScaleCheck; + LLCheckBoxCtrl* mMediaLoopCheck; + LLCheckBoxCtrl* mMediaUrlCheck; + LLCheckBoxCtrl* mMusicUrlCheck; + LLHandle mURLEntryFloater; + + LLSafeHandle& mParcel; +}; + +#endif diff --git a/linden/indra/newview/llpanellogin.cpp b/linden/indra/newview/llpanellogin.cpp index 24d235e..26075a1 100644 --- a/linden/indra/newview/llpanellogin.cpp +++ b/linden/indra/newview/llpanellogin.cpp @@ -71,7 +71,8 @@ #include "llwebbrowserctrl.h" #include "llfloaterhtml.h" -//#include "llfloaterhtmlhelp.h" + +#include "llfloaterhtmlhelp.h" #include "llfloatertos.h" #include "llglheaders.h" @@ -95,12 +96,10 @@ public: LLLoginRefreshHandler() : LLCommandHandler("login_refresh", false) { } bool handle(const LLSD& tokens, const LLSD& queryMap) { -#if LL_LIBXUL_ENABLED if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) { LLPanelLogin::loadLoginPage(); } -#endif return true; } }; @@ -329,7 +328,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, mCallbackData(cb_data), mHtmlAvailable( TRUE ) { - mIsFocusRoot = TRUE; + setFocusRoot(TRUE); setBackgroundVisible(FALSE); setBackgroundOpaque(TRUE); @@ -443,8 +442,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, #endif // get the web browser control - #if LL_LIBXUL_ENABLED - LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "login_html"); + LLWebBrowserCtrl* web_browser = getChild("login_html"); if ( web_browser ) { // Need to handle login secondlife:///app/ URLs @@ -461,28 +459,25 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, web_browser->setOpenInExternalBrowser( true ); // force the size to be correct (XML doesn't seem to be sufficient to do this) (with some padding so the other login screen doesn't show through) - LLRect htmlRect = mRect; + LLRect htmlRect = getRect(); #if USE_VIEWER_AUTH - htmlRect.setCenterAndSize( mRect.getCenterX() - 2, mRect.getCenterY(), mRect.getWidth() + 6, mRect.getHeight()); + htmlRect.setCenterAndSize( getRect().getCenterX() - 2, getRect().getCenterY(), getRect().getWidth() + 6, getRect().getHeight()); #else - htmlRect.setCenterAndSize( mRect.getCenterX() - 2, mRect.getCenterY() + 40, mRect.getWidth() + 6, mRect.getHeight() - 78 ); + htmlRect.setCenterAndSize( getRect().getCenterX() - 2, getRect().getCenterY() + 40, getRect().getWidth() + 6, getRect().getHeight() - 78 ); #endif web_browser->setRect( htmlRect ); web_browser->reshape( htmlRect.getWidth(), htmlRect.getHeight(), TRUE ); - reshape( mRect.getWidth(), mRect.getHeight(), 1 ); + reshape( getRect().getWidth(), getRect().getHeight(), 1 ); // kick off a request to grab the url manually gResponsePtr = LLIamHereLogin::build( this ); std::string login_page = LLAppViewer::instance()->getLoginPage(); if (login_page.empty()) { - login_page = childGetValue( "real_url" ).asString(); + login_page = getString( "real_url" ); } LLHTTPClient::head( login_page, gResponsePtr ); }; - #else - mHtmlAvailable = FALSE; - #endif #if !USE_VIEWER_AUTH // Initialize visibility (and don't force visibility - use prefs) @@ -493,8 +488,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, void LLPanelLogin::setSiteIsAlive( bool alive ) { -#if LL_LIBXUL_ENABLED - LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "login_html"); + LLWebBrowserCtrl* web_browser = getChild("login_html"); // if the contents of the site was retrieved if ( alive ) { @@ -529,10 +523,6 @@ void LLPanelLogin::setSiteIsAlive( bool alive ) } #endif } - -#else - mHtmlAvailable = FALSE; -#endif } void LLPanelLogin::mungePassword(LLUICtrl* caller, void* user_data) @@ -571,16 +561,16 @@ void LLPanelLogin::draw() glPushMatrix(); { F32 image_aspect = 1.333333f; - F32 view_aspect = (F32)mRect.getWidth() / (F32)mRect.getHeight(); + F32 view_aspect = (F32)getRect().getWidth() / (F32)getRect().getHeight(); // stretch image to maintain aspect ratio if (image_aspect > view_aspect) { - glTranslatef(-0.5f * (image_aspect / view_aspect - 1.f) * mRect.getWidth(), 0.f, 0.f); + glTranslatef(-0.5f * (image_aspect / view_aspect - 1.f) * getRect().getWidth(), 0.f, 0.f); glScalef(image_aspect / view_aspect, 1.f, 1.f); } - S32 width = mRect.getWidth(); - S32 height = mRect.getHeight(); + S32 width = getRect().getWidth(); + S32 height = getRect().getHeight(); if ( mHtmlAvailable ) { @@ -626,7 +616,6 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) return TRUE; } -#if LL_LIBXUL_ENABLED if ( KEY_F1 == key ) { llinfos << "Spawning HTML help window" << llendl; @@ -642,7 +631,6 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) tos_dialog->startModal(); return TRUE; } -# endif #endif if (!called_from_parent) @@ -923,14 +911,12 @@ void LLPanelLogin::setAlwaysRefresh(bool refresh) { if (LLStartUp::getStartupState() >= STATE_LOGIN_CLEANUP) return; -#if LL_LIBXUL_ENABLED - LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html"); + LLWebBrowserCtrl* web_browser = sInstance->getChild("login_html"); if (web_browser) { web_browser->setAlwaysRefresh(refresh); } -#endif } @@ -944,7 +930,7 @@ void LLPanelLogin::loadLoginPage() std::string login_page = LLAppViewer::instance()->getLoginPage(); if (login_page.empty()) { - login_page = sInstance->childGetValue( "real_url" ).asString(); + login_page = sInstance->getString( "real_url" ); } oStr << login_page; @@ -1056,18 +1042,15 @@ void LLPanelLogin::loadLoginPage() #endif #endif -#if LL_LIBXUL_ENABLED - LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html"); + LLWebBrowserCtrl* web_browser = sInstance->getChild("login_html"); // navigate to the "real" page web_browser->navigateTo( oStr.str() ); -#endif } -#if LL_LIBXUL_ENABLED void LLPanelLogin::onNavigateComplete( const EventType& eventIn ) { - LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html"); + LLWebBrowserCtrl* web_browser = sInstance->getChild("login_html"); if (web_browser) { // *HACK HACK HACK HACK! @@ -1080,7 +1063,6 @@ void LLPanelLogin::onNavigateComplete( const EventType& eventIn ) //web_browser->handleKey(KEY_TAB, MASK_NONE, false); } } -#endif //--------------------------------------------------------------------------- // Protected methods @@ -1181,7 +1163,7 @@ void LLPanelLogin::onClickForgotPassword(void*) { if (sInstance ) { - LLWeb::loadURL(sInstance->childGetValue( "forgot_password_url" ).asString()); + LLWeb::loadURL(sInstance->getString( "forgot_password_url" )); } } diff --git a/linden/indra/newview/llpanellogin.h b/linden/indra/newview/llpanellogin.h index 206e700..a754224 100644 --- a/linden/indra/newview/llpanellogin.h +++ b/linden/indra/newview/llpanellogin.h @@ -64,11 +64,9 @@ class LLLoginHandler : public LLCommandHandler extern LLLoginHandler gLoginHandler; -class LLPanelLogin -: public LLPanel -#if LL_LIBXUL_ENABLED - , public LLWebBrowserCtrlObserver -#endif +class LLPanelLogin: + public LLPanel, + public LLWebBrowserCtrlObserver { public: LLPanelLogin(const LLRect &rect, BOOL show_server, @@ -111,11 +109,7 @@ private: static void newAccountAlertCallback(S32 option, void*); static void onClickQuit(void*); static void onClickVersion(void*); - -#if LL_LIBXUL_ENABLED - // browser observer impls virtual void onNavigateComplete( const EventType& eventIn ); -#endif static void onClickForgotPassword(void*); static void onPassKey(LLLineEditor* caller, void* user_data); diff --git a/linden/indra/newview/llpanelobject.cpp b/linden/indra/newview/llpanelobject.cpp index e4e28b8..a395d09 100644 --- a/linden/indra/newview/llpanelobject.cpp +++ b/linden/indra/newview/llpanelobject.cpp @@ -164,11 +164,10 @@ BOOL LLPanelObject::postBuild() childSetCommitCallback("material",onCommitMaterial,this); mComboMaterial->removeall(); // *TODO:translate - LLMaterialInfo *minfop; - for (minfop = LLMaterialTable::basic.mMaterialInfoList.getFirstData(); - minfop != NULL; - minfop = LLMaterialTable::basic.mMaterialInfoList.getNextData()) + for (LLMaterialTable::info_list_t::iterator iter = LLMaterialTable::basic.mMaterialInfoList.begin(); + iter != LLMaterialTable::basic.mMaterialInfoList.end(); ++iter) { + LLMaterialInfo* minfop = *iter; if (minfop->mMCode != LL_MCODE_LIGHT) { mComboMaterial->add(minfop->mName); @@ -259,7 +258,7 @@ BOOL LLPanelObject::postBuild() mSpinRevolutions->setValidateBeforeCommit( &precommitValidate ); // Sculpt - mCtrlSculptTexture = LLUICtrlFactory::getTexturePickerByName(this,"sculpt texture control"); + mCtrlSculptTexture = getChild("sculpt texture control"); if (mCtrlSculptTexture) { mCtrlSculptTexture->setDefaultImageAssetID(LLUUID(SCULPT_DEFAULT_TEXTURE)); @@ -913,12 +912,15 @@ void LLPanelObject::getState( ) mSpinScaleY->setMaxValue(OBJECT_MAX_HOLE_SIZE_Y); break; default: - mSpinScaleX->set( 1.f - scale_x ); - mSpinScaleY->set( 1.f - scale_y ); - mSpinScaleX->setMinValue(-1.f); - mSpinScaleX->setMaxValue(1.f); - mSpinScaleY->setMinValue(-1.f); - mSpinScaleY->setMaxValue(1.f); + if (editable) + { + mSpinScaleX->set( 1.f - scale_x ); + mSpinScaleY->set( 1.f - scale_y ); + mSpinScaleX->setMinValue(-1.f); + mSpinScaleX->setMaxValue(1.f); + mSpinScaleY->setMinValue(-1.f); + mSpinScaleY->setMaxValue(1.f); + } break; } @@ -1903,7 +1905,7 @@ void LLPanelObject::onSelectSculpt(LLUICtrl* ctrl, void* userdata) { LLPanelObject* self = (LLPanelObject*) userdata; - LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(self, "sculpt texture control"); + LLTextureCtrl* mTextureCtrl = self->getChild("sculpt texture control"); if (mTextureCtrl) { @@ -1926,7 +1928,7 @@ BOOL LLPanelObject::onDropSculpt(LLUICtrl*, LLInventoryItem* item, void* userdat { LLPanelObject* self = (LLPanelObject*) userdata; - LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(self, "sculpt texture control"); + LLTextureCtrl* mTextureCtrl = self->getChild("sculpt texture control"); if (mTextureCtrl) { @@ -1945,7 +1947,7 @@ void LLPanelObject::onCancelSculpt(LLUICtrl* ctrl, void* userdata) { LLPanelObject* self = (LLPanelObject*) userdata; - LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(self,"sculpt texture control"); + LLTextureCtrl* mTextureCtrl = self->getChild("sculpt texture control"); if(!mTextureCtrl) return; diff --git a/linden/indra/newview/llpanelpermissions.cpp b/linden/indra/newview/llpanelpermissions.cpp index c1899ee..cd97d0c 100644 --- a/linden/indra/newview/llpanelpermissions.cpp +++ b/linden/indra/newview/llpanelpermissions.cpp @@ -138,11 +138,11 @@ void LLPanelPermissions::refresh() LLString deedText; if (gSavedSettings.getWarning("DeedObject")) { - deedText = this->childGetText("text deed continued"); + deedText = getString("text deed continued"); } else { - deedText = this->childGetText("text deed"); + deedText = getString("text deed"); } BtnDeedToGroup->setLabelSelected(deedText); BtnDeedToGroup->setLabelUnselected(deedText); @@ -261,10 +261,10 @@ void LLPanelPermissions::refresh() S32 string_index = 0; LLString MODIFY_INFO_STRINGS[] = { - childGetText("text modify info 1"), - childGetText("text modify info 2"), - childGetText("text modify info 3"), - childGetText("text modify info 4") + getString("text modify info 1"), + getString("text modify info 2"), + getString("text modify info 3"), + getString("text modify info 4") }; if(!is_perm_modify) { @@ -572,7 +572,7 @@ void LLPanelPermissions::refresh() if (!has_change_perm_ability && !has_change_sale_ability && !root_selected) { // ...must select root to choose permissions - childSetValue("perm_modify", childGetText("text modify warning")); + childSetValue("perm_modify", getString("text modify warning")); } if (has_change_perm_ability) diff --git a/linden/indra/newview/llpanelpick.cpp b/linden/indra/newview/llpanelpick.cpp index 533702a..eddbc45 100644 --- a/linden/indra/newview/llpanelpick.cpp +++ b/linden/indra/newview/llpanelpick.cpp @@ -134,7 +134,7 @@ BOOL LLPanelPick::postBuild() mDescEditor->setCommitOnFocusLost(TRUE); mDescEditor->setCommitCallback(onCommitAny); mDescEditor->setCallbackUserData(this); - mDescEditor->setTabToNextField(TRUE); + mDescEditor->setTabsToNextField(TRUE); mLocationEditor = LLViewerUICtrlFactory::getLineEditorByName(this, "location_editor"); @@ -507,7 +507,7 @@ void LLPanelPick::onCommitAny(LLUICtrl* ctrl, void* data) } else {*/ - LLTabContainerVertical* tab = (LLTabContainerVertical*)self->getParent(); + LLTabContainer* tab = (LLTabContainer*)self->getParent(); if (tab) { if(tab) tab->setCurrentTabName(self->mNameEditor->getText()); diff --git a/linden/indra/newview/llpanelplace.cpp b/linden/indra/newview/llpanelplace.cpp index 54f011f..2b50a9d 100644 --- a/linden/indra/newview/llpanelplace.cpp +++ b/linden/indra/newview/llpanelplace.cpp @@ -190,11 +190,11 @@ void LLPanelPlace::setErrorStatus(U32 status, const std::string& reason) LLString error_text; if(status == 404) { - error_text = childGetText("server_error_text"); + error_text = getString("server_error_text"); } else if(status == 499) { - error_text = childGetText("server_forbidden_text"); + error_text = getString("server_forbidden_text"); } mDescEditor->setText(error_text); } @@ -260,13 +260,13 @@ void LLPanelPlace::processParcelInfoReply(LLMessageSystem *msg, void **) std::string desc_str(desc); if( !name_str.empty() - && self->mNameEditor->getText().empty()) + && self->mNameEditor && self->mNameEditor->getText().empty()) { self->mNameEditor->setText(name_str); } if( !desc_str.empty() - && self->mDescEditor->getText().empty()) + && self->mDescEditor && self->mDescEditor->getText().empty()) { self->mDescEditor->setText(desc_str); } @@ -290,8 +290,10 @@ void LLPanelPlace::processParcelInfoReply(LLMessageSystem *msg, void **) auction.setArg("[ID]", llformat("%010d ", auction_id)); info_text += auction; } - self->mInfoEditor->setText(info_text); - + if (self->mInfoEditor) + { + self->mInfoEditor->setText(info_text); + } // HACK: Flag 0x1 == mature region, otherwise assume PG const char* rating = LLViewerRegion::accessToString(SIM_ACCESS_PG); @@ -320,7 +322,10 @@ void LLPanelPlace::processParcelInfoReply(LLMessageSystem *msg, void **) LLString location = llformat("%s %d, %d, %d (%s)", sim_name, region_x, region_y, region_z, rating); - self->mLocationEditor->setText(location); + if (self->mLocationEditor) + { + self->mLocationEditor->setText(location); + } BOOL show_auction = (auction_id > 0); self->mAuctionBtn->setVisible(show_auction); @@ -354,7 +359,7 @@ void LLPanelPlace::displayParcelInfo(const LLVector3& pos_region, } else { - mDescEditor->setText(childGetText("server_update_text")); + mDescEditor->setText(getString("server_update_text")); } mSnapshotCtrl->setImageAssetID(LLUUID::null); } diff --git a/linden/indra/newview/llpanelvolume.cpp b/linden/indra/newview/llpanelvolume.cpp index cad038c..285750a 100644 --- a/linden/indra/newview/llpanelvolume.cpp +++ b/linden/indra/newview/llpanelvolume.cpp @@ -104,7 +104,7 @@ BOOL LLPanelVolume::postBuild() // LIGHT Parameters { childSetCommitCallback("Light Checkbox Ctrl",onCommitIsLight,this); - LLColorSwatchCtrl* LightColorSwatch = gUICtrlFactory->getColorSwatchByName(this,"colorswatch"); + LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch){ LightColorSwatch->setOnCancelCallback(onLightCancelColor); LightColorSwatch->setOnSelectCallback(onLightSelectColor); @@ -213,7 +213,7 @@ void LLPanelVolume::getState( ) { childSetEnabled("label color",true); //mLabelColor ->setEnabled( TRUE ); - LLColorSwatchCtrl* LightColorSwatch = gUICtrlFactory->getColorSwatchByName(this,"colorswatch"); + LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) { LightColorSwatch->setEnabled( TRUE ); @@ -232,8 +232,12 @@ void LLPanelVolume::getState( ) } else { + ((LLPanel *) getChildByName ("Light Intensity", true))->clear(); + ((LLPanel *) getChildByName ("Light Radius", true))->clear(); + ((LLPanel *) getChildByName ("Light Falloff", true))->clear(); + childSetEnabled("label color",false); - LLColorSwatchCtrl* LightColorSwatch = gUICtrlFactory->getColorSwatchByName(this,"colorswatch"); + LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) { LightColorSwatch->setEnabled( FALSE ); @@ -288,6 +292,15 @@ void LLPanelVolume::getState( ) } else { + ((LLPanel *) getChildByName ("FlexNumSections", true))->clear(); + ((LLPanel *) getChildByName ("FlexGravity", true))->clear(); + ((LLPanel *) getChildByName ("FlexTension", true))->clear(); + ((LLPanel *) getChildByName ("FlexFriction", true))->clear(); + ((LLPanel *) getChildByName ("FlexWind", true))->clear(); + ((LLPanel *) getChildByName ("FlexForceX", true))->clear(); + ((LLPanel *) getChildByName ("FlexForceY", true))->clear(); + ((LLPanel *) getChildByName ("FlexForceZ", true))->clear(); + childSetEnabled("FlexNumSections",false); childSetEnabled("FlexGravity",false); childSetEnabled("FlexTension",false); @@ -342,7 +355,7 @@ void LLPanelVolume::clearCtrls() childSetEnabled("Light Checkbox Ctrl",false); childSetEnabled("label color",false); childSetEnabled("label color",false); - LLColorSwatchCtrl* LightColorSwatch = gUICtrlFactory->getColorSwatchByName(this,"colorswatch"); + LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) { LightColorSwatch->setEnabled( FALSE ); @@ -416,7 +429,7 @@ void LLPanelVolume::sendIsFlexible() void LLPanelVolume::onLightCancelColor(LLUICtrl* ctrl, void* userdata) { LLPanelVolume* self = (LLPanelVolume*) userdata; - LLColorSwatchCtrl* LightColorSwatch = gUICtrlFactory->getColorSwatchByName(self,"colorswatch"); + LLColorSwatchCtrl* LightColorSwatch = self->getChild("colorswatch"); if(LightColorSwatch) { LightColorSwatch->setColor(self->mLightSavedColor); @@ -435,7 +448,7 @@ void LLPanelVolume::onLightSelectColor(LLUICtrl* ctrl, void* userdata) LLVOVolume *volobjp = (LLVOVolume *)objectp; - LLColorSwatchCtrl* LightColorSwatch = gUICtrlFactory->getColorSwatchByName(self,"colorswatch"); + LLColorSwatchCtrl* LightColorSwatch = self->getChild("colorswatch"); if(LightColorSwatch) { LLColor4 clr = LightColorSwatch->get(); @@ -460,7 +473,7 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) volobjp->setLightIntensity((F32)self->childGetValue("Light Intensity").asReal()); volobjp->setLightRadius((F32)self->childGetValue("Light Radius").asReal()); volobjp->setLightFalloff((F32)self->childGetValue("Light Falloff").asReal()); - LLColorSwatchCtrl* LightColorSwatch = gUICtrlFactory->getColorSwatchByName(self,"colorswatch"); + LLColorSwatchCtrl* LightColorSwatch = self->getChild("colorswatch"); if(LightColorSwatch) { LLColor4 clr = LightColorSwatch->get(); diff --git a/linden/indra/newview/llpanelweb.cpp b/linden/indra/newview/llpanelweb.cpp index 9083e3d..0de828a 100644 --- a/linden/indra/newview/llpanelweb.cpp +++ b/linden/indra/newview/llpanelweb.cpp @@ -43,16 +43,52 @@ #include "llbutton.h" #include "llcheckboxctrl.h" #include "lllineeditor.h" -#include "llmozlib.h" #include "llui.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" #include "llvieweruictrlfactory.h" #include "llviewerwindow.h" +#include "llmediamanager.h" -#if LL_LIBXUL_ENABLED -#include "llmozlib.h" -#endif // LL_LIBXUL_ENABLED + +// helper functions for getting/freeing the web browser media +// if creating/destroying these is too slow, we'll need to create +// a static member and update all our static callbacks +LLMediaBase *get_web_media() +{ + LLMediaBase *media_source; + LLMediaManager *mgr = LLMediaManager::getInstance(); + + if (!mgr) + { + llwarns << "cannot get media manager" << llendl; + return NULL; + } + + media_source = mgr->createSourceFromMimeType("http", "text/html" ); + if ( !media_source ) + { + llwarns << "media source create failed " << llendl; + return NULL; + } + + return media_source; +} + +void free_web_media(LLMediaBase *media_source) +{ + if (!media_source) + return; + + LLMediaManager *mgr = LLMediaManager::getInstance(); + if (!mgr) + { + llwarns << "cannot get media manager" << llendl; + return; + } + + mgr->destroySource(media_source); +} LLPanelWeb::LLPanelWeb() { @@ -63,6 +99,8 @@ BOOL LLPanelWeb::postBuild() { childSetAction( "clear_cache", onClickClearCache, this ); childSetAction( "clear_cookies", onClickClearCookies, this ); + childSetCommitCallback("use_external_browser", onSelectBrowser, this ); +// childSetEnabled( "connection_port", gSavedSettings.getBOOL( "CookiesEnabled" ) ); childSetCommitCallback( "cookies_enabled", onCommitCookies, this ); childSetCommitCallback( "web_proxy_editor", onCommitWebProxyAddress, this); childSetCommitCallback( "web_proxy_port", onCommitWebProxyPort, this); @@ -105,67 +143,70 @@ void LLPanelWeb::refresh() { web_proxy_editor->setText( gSavedSettings.getString("BrowserProxyAddress") ); } + mExternalBrowser = gSavedSettings.getBOOL("UseExternalBrowser"); -#if LL_LIBXUL_ENABLED - llinfos << "setting cookies enabled to " << mCookiesEnabled << llendl; - LLMozLib::getInstance()->enableCookies( mCookiesEnabled ); -#endif // LL_LIBXUL_ENABLED + childSetValue("use_external_browser", mExternalBrowser ? "external" : "internal"); + + LLMediaBase *media_source = get_web_media(); + if (media_source) + media_source->enableCookies(mCookiesEnabled); + free_web_media(media_source); } void LLPanelWeb::cancel() { -#if LL_LIBXUL_ENABLED - llinfos << "setting cookies enabled to " << mCookiesEnabled << llendl; - LLMozLib::getInstance()->enableCookies( mCookiesEnabled ); -#endif // LL_LIBXUL_ENABLED - + gSavedSettings.setBOOL( "CookiesEnabled", mCookiesEnabled ); gSavedSettings.setBOOL( "BrowserProxyEnabled", mWebProxyEnabled ); gSavedSettings.setString( "BrowserProxyAddress", mWebProxyAddress ); gSavedSettings.setS32( "BrowserProxyPort", mWebProxyPort ); - LLMozLib::getInstance()->enableProxy( mWebProxyEnabled, mWebProxyAddress, mWebProxyPort ); + gSavedSettings.setBOOL("UseExternalBrowser", mExternalBrowser); + LLMediaBase *media_source = get_web_media(); + if (media_source) + { + media_source->enableCookies(mCookiesEnabled); + media_source->enableProxy( mWebProxyEnabled, mWebProxyAddress, mWebProxyPort ); + } + free_web_media(media_source); + } // static void LLPanelWeb::onClickClearCache(void*) { -#if LL_LIBXUL_ENABLED gViewerWindow->alertXml("ConfirmClearBrowserCache", callback_clear_browser_cache, 0); -#endif // LL_LIBXUL_ENABLED } //static void LLPanelWeb::callback_clear_browser_cache(S32 option, void* userdata) { -#if LL_LIBXUL_ENABLED if ( option == 0 ) // YES { - llinfos << "clearing browser cache" << llendl; - LLMozLib::getInstance()->clearCache(); + LLMediaBase *media_source = get_web_media(); + if (media_source) + media_source->clearCache(); + free_web_media(media_source); } -#endif // LL_LIBXUL_ENABLED } // static void LLPanelWeb::onClickClearCookies(void*) { -#if LL_LIBXUL_ENABLED gViewerWindow->alertXml("ConfirmClearCookies", callback_clear_cookies, 0); -#endif // LL_LIBXUL_ENABLED } //static void LLPanelWeb::callback_clear_cookies(S32 option, void* userdata) { -#if LL_LIBXUL_ENABLED if ( option == 0 ) // YES { - llinfos << "clearing browser cookies" << llendl; - LLMozLib::getInstance()->clearAllCookies(); + LLMediaBase *media_source = get_web_media(); + if (media_source) + media_source->clearCookies(); + free_web_media(media_source); } -#endif // LL_LIBXUL_ENABLED } // static @@ -176,29 +217,34 @@ void LLPanelWeb::onCommitCookies(LLUICtrl* ctrl, void* data) if (!self || !check) return; -#if LL_LIBXUL_ENABLED - llinfos << "setting cookies enabled to " << check->get() << llendl; - LLMozLib::getInstance()->enableCookies( check->get() ); -#endif // LL_LIBXUL_ENABLED - + LLMediaBase *media_source = get_web_media(); + if (media_source) + media_source->enableCookies(check->get()); + free_web_media(media_source); } // static void LLPanelWeb::onCommitWebProxyEnabled(LLUICtrl* ctrl, void* data) { - LLPanelWeb* self = (LLPanelWeb*)data; - LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)ctrl; + LLPanelWeb* self = (LLPanelWeb*)data; + LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)ctrl; + + if (!self || !check) return; + self->childSetEnabled("web_proxy_editor", + check->get()); + self->childSetEnabled("web_proxy_port", + check->get()); + self->childSetEnabled("proxy_text_label", + check->get()); + + LLMediaBase *media_source = get_web_media(); + if (media_source) + { + media_source->enableProxy( gSavedSettings.getBOOL("BrowserProxyEnabled"), + gSavedSettings.getString("BrowserProxyAddress"), + gSavedSettings.getS32("BrowserProxyPort") ); + } + free_web_media(media_source); - if (!self || !check) return; - self->childSetEnabled("web_proxy_editor", - check->get()); - self->childSetEnabled("web_proxy_port", - check->get()); - self->childSetEnabled("proxy_text_label", - check->get()); - - LLMozLib::getInstance()->enableProxy( gSavedSettings.getBOOL("BrowserProxyEnabled"), - gSavedSettings.getString("BrowserProxyAddress"), - gSavedSettings.getS32("BrowserProxyPort") ); } void LLPanelWeb::onCommitWebProxyAddress(LLUICtrl *ctrl, void *userdata) @@ -209,16 +255,31 @@ void LLPanelWeb::onCommitWebProxyAddress(LLUICtrl *ctrl, void *userdata) { gSavedSettings.setString("BrowserProxyAddress", web_proxy->getText()); } - - LLMozLib::getInstance()->enableProxy( gSavedSettings.getBOOL("BrowserProxyEnabled"), - gSavedSettings.getString("BrowserProxyAddress"), - gSavedSettings.getS32("BrowserProxyPort") ); + LLMediaBase *media_source = get_web_media(); + if (media_source) + { + media_source->enableProxy( gSavedSettings.getBOOL("BrowserProxyEnabled"), + gSavedSettings.getString("BrowserProxyAddress"), + gSavedSettings.getS32("BrowserProxyPort") ); + } + free_web_media(media_source); } void LLPanelWeb::onCommitWebProxyPort(LLUICtrl *ctrl, void *userdata) { - LLMozLib::getInstance()->enableProxy( gSavedSettings.getBOOL("BrowserProxyEnabled"), - gSavedSettings.getString("BrowserProxyAddress"), - gSavedSettings.getS32("BrowserProxyPort") ); + LLMediaBase *media_source = get_web_media(); + if (media_source) + { + media_source->enableProxy( gSavedSettings.getBOOL("BrowserProxyEnabled"), + gSavedSettings.getString("BrowserProxyAddress"), + gSavedSettings.getS32("BrowserProxyPort") ); + } + free_web_media(media_source); +} +// static +void LLPanelWeb::onSelectBrowser(LLUICtrl* ctrl, void* data) +{ + // "external" or "internal" + gSavedSettings.setBOOL("UseExternalBrowser", ctrl->getValue().asString() == "external"); } diff --git a/linden/indra/newview/llpanelweb.h b/linden/indra/newview/llpanelweb.h index 37cc1f3..25dceaa 100644 --- a/linden/indra/newview/llpanelweb.h +++ b/linden/indra/newview/llpanelweb.h @@ -58,12 +58,14 @@ private: static void onCommitWebProxyEnabled(LLUICtrl* ctrl, void* data); static void onCommitWebProxyAddress(LLUICtrl *ctrl, void *userdata); static void onCommitWebProxyPort(LLUICtrl *ctrl, void *userdata); + static void onSelectBrowser(LLUICtrl* ctrl, void* data); private: BOOL mCookiesEnabled; BOOL mWebProxyEnabled; LLString mWebProxyAddress; S32 mWebProxyPort; + BOOL mExternalBrowser; }; #endif diff --git a/linden/indra/newview/llparcelselection.cpp b/linden/indra/newview/llparcelselection.cpp new file mode 100644 index 0000000..cec2c48 --- /dev/null +++ b/linden/indra/newview/llparcelselection.cpp @@ -0,0 +1,105 @@ +/** + * @file llparcelselection.cpp + * @brief Information about the currently selected parcel + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llparcelselection.h" + +#include "llparcel.h" + + +// static +LLPointer LLParcelSelection::sNullSelection; + +template<> + const LLSafeHandle::NullFunc + LLSafeHandle::sNullFunc = LLParcelSelection::getNullParcelSelection; + +// +// LLParcelSelection +// +LLParcelSelection::LLParcelSelection() : + mParcel(NULL), + mSelectedMultipleOwners(FALSE), + mWholeParcelSelected(FALSE), + mSelectedSelfCount(0), + mSelectedOtherCount(0), + mSelectedPublicCount(0) +{ +} + +LLParcelSelection::LLParcelSelection(LLParcel* parcel) : + mParcel(parcel), + mSelectedMultipleOwners(FALSE), + mWholeParcelSelected(FALSE), + mSelectedSelfCount(0), + mSelectedOtherCount(0), + mSelectedPublicCount(0) +{ +} + +LLParcelSelection::~LLParcelSelection() +{ +} + +BOOL LLParcelSelection::getMultipleOwners() const +{ + return mSelectedMultipleOwners; +} + + +BOOL LLParcelSelection::getWholeParcelSelected() const +{ + return mWholeParcelSelected; +} + + +S32 LLParcelSelection::getClaimableArea() const +{ + const S32 UNIT_AREA = S32( PARCEL_GRID_STEP_METERS * PARCEL_GRID_STEP_METERS ); + return mSelectedPublicCount * UNIT_AREA; +} + +bool LLParcelSelection::hasOthersSelected() const +{ + return mSelectedOtherCount != 0; +} + +// static +LLParcelSelection* LLParcelSelection::getNullParcelSelection() +{ + if (sNullSelection.isNull()) + { + sNullSelection = new LLParcelSelection; + } + + return sNullSelection; +} diff --git a/linden/indra/newview/llparcelselection.h b/linden/indra/newview/llparcelselection.h new file mode 100644 index 0000000..1a41bcf --- /dev/null +++ b/linden/indra/newview/llparcelselection.h @@ -0,0 +1,86 @@ +/** + * @file llparcelselection.h + * @brief Information about the currently selected parcel + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLPARCELSELECTION_H +#define LLPARCELSELECTION_H + +#include "llmemory.h" + +class LLParcel; + +class LLParcelSelection : public LLRefCount +{ + friend class LLViewerParcelMgr; + +protected: + ~LLParcelSelection(); + +public: + LLParcelSelection(LLParcel* parcel); + LLParcelSelection(); + + // this can return NULL at any time, as parcel selection + // might have been invalidated. + LLParcel* getParcel() { return mParcel; } + + // Return the number of grid units that are owned by you within + // the selection (computed by server). + S32 getSelfCount() const { return mSelectedSelfCount; } + + // Returns area that will actually be claimed in meters squared. + S32 getClaimableArea() const; + bool hasOthersSelected() const; + + // Does the selection have multiple land owners in it? + BOOL getMultipleOwners() const; + + // Is the entire parcel selected, or just a part? + BOOL getWholeParcelSelected() const; + + static LLParcelSelection* getNullParcelSelection(); + +private: + void setParcel(LLParcel* parcel) { mParcel = parcel; } + +private: + LLParcel* mParcel; + BOOL mSelectedMultipleOwners; + BOOL mWholeParcelSelected; + S32 mSelectedSelfCount; + S32 mSelectedOtherCount; + S32 mSelectedPublicCount; + + static LLPointer sNullSelection; +}; + +typedef LLSafeHandle LLParcelSelectionHandle; + +#endif diff --git a/linden/indra/newview/llpolymesh.cpp b/linden/indra/newview/llpolymesh.cpp index d703129..d74beeb 100644 --- a/linden/indra/newview/llpolymesh.cpp +++ b/linden/indra/newview/llpolymesh.cpp @@ -90,7 +90,8 @@ LLPolyMeshSharedData::LLPolyMeshSharedData() LLPolyMeshSharedData::~LLPolyMeshSharedData() { freeMeshData(); - mMorphData.deleteAllData(); + for_each(mMorphData.begin(), mMorphData.end(), DeletePointer()); + mMorphData.clear(); } //----------------------------------------------------------------------------- @@ -604,7 +605,7 @@ BOOL LLPolyMeshSharedData::loadMesh( const char *fileName ) continue; } - mMorphData.addData(morph_data); + mMorphData.insert(morph_data); } S32 numRemaps; @@ -759,11 +760,11 @@ LLPolyMesh *LLPolyMesh::getMesh(const LLString &name, LLPolyMesh* reference_mesh //------------------------------------------------------------------------- // search for an existing mesh by this name //------------------------------------------------------------------------- - LLPolyMeshSharedData **meshSharedData = sGlobalSharedMeshList.getValue(name); + LLPolyMeshSharedData* meshSharedData = get_if_there(sGlobalSharedMeshList, name, (LLPolyMeshSharedData*)NULL); if (meshSharedData) { // llinfos << "Polymesh " << name << " found in global mesh table." << llendl; - LLPolyMesh *poly_mesh = new LLPolyMesh(*meshSharedData, reference_mesh); + LLPolyMesh *poly_mesh = new LLPolyMesh(meshSharedData, reference_mesh); return poly_mesh; } @@ -787,7 +788,7 @@ LLPolyMesh *LLPolyMesh::getMesh(const LLString &name, LLPolyMesh* reference_mesh LLPolyMesh *poly_mesh = new LLPolyMesh(mesh_data, reference_mesh); // llinfos << "Polymesh " << name << " added to global mesh table." << llendl; - sGlobalSharedMeshList.addToTail(name, poly_mesh->mSharedData); + sGlobalSharedMeshList[name] = poly_mesh->mSharedData; return poly_mesh; } @@ -797,21 +798,9 @@ LLPolyMesh *LLPolyMesh::getMesh(const LLString &name, LLPolyMesh* reference_mesh //----------------------------------------------------------------------------- void LLPolyMesh::freeAllMeshes() { - U32 i; - // delete each item in the global lists - for (i=0; ifirst; + LLPolyMeshSharedData* mesh = iter->second; - S32 num_verts = mesh.mNumVertices; - S32 num_faces = mesh.mNumFaces; - U32 num_kb = mesh.getNumKB(); + S32 num_verts = mesh->mNumVertices; + S32 num_faces = mesh->mNumFaces; + U32 num_kb = mesh->getNumKB(); - snprintf(buf, sizeof(buf), "%8d %8d %8d %s", num_verts, num_faces, num_kb, mesh_name_p->c_str()); /* Flawfinder: ignore */ + buf = llformat("%8d %8d %8d %s", num_verts, num_faces, num_kb, mesh_name.c_str()); llinfos << buf << llendl; total_verts += num_verts; @@ -858,7 +846,7 @@ void LLPolyMesh::dumpDiagInfo() } llinfos << "-----------------------------------------------------" << llendl; - snprintf(buf, sizeof(buf), "%8d %8d %8d TOTAL", total_verts, total_faces, total_kb ); /* Flawfinder: ignore */ + buf = llformat("%8d %8d %8d TOTAL", total_verts, total_faces, total_kb ); llinfos << buf << llendl; llinfos << "-----------------------------------------------------" << llendl; } @@ -943,11 +931,12 @@ void LLPolyMesh::initializeForMorph() //----------------------------------------------------------------------------- LLPolyMorphData* LLPolyMesh::getMorphData(const char *morph_name) { - if (!mSharedData) return NULL; - for (LLPolyMorphData *morph_data = mSharedData->mMorphData.getFirstData(); - morph_data; - morph_data = mSharedData->mMorphData.getNextData()) + if (!mSharedData) + return NULL; + for (LLPolyMeshSharedData::morphdata_list_t::iterator iter = mSharedData->mMorphData.begin(); + iter != mSharedData->mMorphData.end(); ++iter) { + LLPolyMorphData *morph_data = *iter; if (!strcmp(morph_data->getName(), morph_name)) { return morph_data; @@ -959,22 +948,25 @@ LLPolyMorphData* LLPolyMesh::getMorphData(const char *morph_name) //----------------------------------------------------------------------------- // removeMorphData() //----------------------------------------------------------------------------- -void LLPolyMesh::removeMorphData(LLPolyMorphData *morph_target) -{ - if (!mSharedData) return; - - mSharedData->mMorphData.removeData(morph_target); -} +// // erasing but not deleting seems bad, but fortunately we don't actually use this... +// void LLPolyMesh::removeMorphData(LLPolyMorphData *morph_target) +// { +// if (!mSharedData) +// return; +// mSharedData->mMorphData.erase(morph_target); +// } //----------------------------------------------------------------------------- // deleteAllMorphData() //----------------------------------------------------------------------------- -void LLPolyMesh::deleteAllMorphData() -{ - if (!mSharedData) return; +// void LLPolyMesh::deleteAllMorphData() +// { +// if (!mSharedData) +// return; - mSharedData->mMorphData.deleteAllData(); -} +// for_each(mSharedData->mMorphData.begin(), mSharedData->mMorphData.end(), DeletePointer()); +// mSharedData->mMorphData.clear(); +// } //----------------------------------------------------------------------------- // getWritableWeights() diff --git a/linden/indra/newview/llpolymesh.h b/linden/indra/newview/llpolymesh.h index c7c8054..8b6affe 100644 --- a/linden/indra/newview/llpolymesh.h +++ b/linden/indra/newview/llpolymesh.h @@ -39,10 +39,7 @@ #include "v3math.h" #include "v2math.h" #include "llquaternion.h" -#include "llskipmap.h" -#include "llassoclist.h" #include "llpolymorph.h" -#include "llptrskipmap.h" #include "lljoint.h" //#include "lldarray.h" @@ -99,8 +96,8 @@ private: std::string* mJointNames; // morph targets - typedef LLLinkedList LLPolyMorphDataList; - LLPolyMorphDataList mMorphData; + typedef std::set morphdata_list_t; + morphdata_list_t mMorphData; std::map mSharedVerts; @@ -113,11 +110,11 @@ public: U32 mNumTriangleIndices; U32 *mTriangleIndices; -private: +public: LLPolyMeshSharedData(); - ~LLPolyMeshSharedData(); +private: void setupLOD(LLPolyMeshSharedData* reference_data); // Frees all mesh memory resources @@ -315,8 +312,8 @@ public: } LLPolyMorphData* getMorphData(const char *morph_name); - void removeMorphData(LLPolyMorphData *morph_target); - void deleteAllMorphData(); +// void removeMorphData(LLPolyMorphData *morph_target); +// void deleteAllMorphData(); LLPolyMeshSharedData *getSharedData() const; LLPolyMesh *getReferenceMesh() { return mReferenceMesh ? mReferenceMesh : this; } @@ -365,7 +362,7 @@ protected: LLPolyMesh *mReferenceMesh; // global mesh list - typedef LLAssocList LLPolyMeshSharedDataTable; + typedef std::map LLPolyMeshSharedDataTable; static LLPolyMeshSharedDataTable sGlobalSharedMeshList; // Backlink only; don't make this an LLPointer. diff --git a/linden/indra/newview/llpolymorph.cpp b/linden/indra/newview/llpolymorph.cpp index 0a9479f..a83f5ab 100644 --- a/linden/indra/newview/llpolymorph.cpp +++ b/linden/indra/newview/llpolymorph.cpp @@ -35,7 +35,6 @@ #include "llviewerprecompiledheaders.h" #include "llpolymorph.h" -#include "linked_lists.h" #include "llvoavatar.h" #include "llxmltree.h" #include "llendianswizzle.h" @@ -44,8 +43,6 @@ const F32 NORMAL_SOFTEN_FACTOR = 0.65f; -LLLinkedList gLoadedMorphs; - //----------------------------------------------------------------------------- // LLPolyMorphData() //----------------------------------------------------------------------------- @@ -184,8 +181,6 @@ BOOL LLPolyMorphData::loadBinary(FILE *fp, LLPolyMeshSharedData *mesh) mAvgDistortion = mAvgDistortion * (1.f/(F32)mNumIndices); mAvgDistortion.normVec(); - gLoadedMorphs.addData(this); - return TRUE; } diff --git a/linden/indra/newview/llpolymorph.h b/linden/indra/newview/llpolymorph.h index 8dd3bd4..5f7a034 100644 --- a/linden/indra/newview/llpolymorph.h +++ b/linden/indra/newview/llpolymorph.h @@ -36,8 +36,6 @@ #include #include "llviewervisualparam.h" -#include "llskiplist.h" -#include "linked_lists.h" class LLPolyMeshSharedData; class LLVOAvatar; diff --git a/linden/indra/newview/llpostprocess.cpp b/linden/indra/newview/llpostprocess.cpp new file mode 100644 index 0000000..11a211a --- /dev/null +++ b/linden/indra/newview/llpostprocess.cpp @@ -0,0 +1,641 @@ +/** + * @file llpostprocess.cpp + * @brief LLPostProcess class implementation + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "pipeline.h" +#include "llpostprocess.h" +#include "llglslshader.h" +#include "llsdserialize.h" +#include "llglimmediate.h" + + +LLPostProcess * gPostProcess = NULL; + + +static const unsigned int NOISE_SIZE = 512; + +/// CALCULATING LUMINANCE (Using NTSC lum weights) +/// http://en.wikipedia.org/wiki/Luma_%28video%29 +static const float LUMINANCE_R = 0.299f; +static const float LUMINANCE_G = 0.587f; +static const float LUMINANCE_B = 0.114f; + +static const char * const XML_FILENAME = "postprocesseffects.xml"; + +LLPostProcess::LLPostProcess(void) : + sceneRenderTexture(0), noiseTexture(0), + tempBloomTexture(0), + initialized(false), + mAllEffects(LLSD::emptyMap()), + screenW(1), screenH(1) +{ + LLString pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME)); + llinfos << "Loading PostProcess Effects settings from " << pathName << llendl; + + llifstream effectsXML(pathName.c_str()); + + if (effectsXML) + { + LLPointer parser = new LLSDXMLParser(); + + parser->parse(effectsXML, mAllEffects, LLSDSerialize::SIZE_UNLIMITED); + } + + if (!mAllEffects.has("default")) + { + LLSD & defaultEffect = (mAllEffects["default"] = LLSD::emptyMap()); + + defaultEffect["enable_night_vision"] = LLSD::Boolean(false); + defaultEffect["enable_bloom"] = LLSD::Boolean(false); + defaultEffect["enable_color_filter"] = LLSD::Boolean(false); + + /// NVG Defaults + defaultEffect["brightness_multiplier"] = 3.0; + defaultEffect["noise_size"] = 25.0; + defaultEffect["noise_strength"] = 0.4; + + // TODO BTest potentially add this to tweaks? + noiseTextureScale = 1.0f; + + /// Bloom Defaults + defaultEffect["extract_low"] = 0.95; + defaultEffect["extract_high"] = 1.0; + defaultEffect["bloom_width"] = 2.25; + defaultEffect["bloom_strength"] = 1.5; + + /// Color Filter Defaults + defaultEffect["brightness"] = 1.0; + defaultEffect["contrast"] = 1.0; + defaultEffect["saturation"] = 1.0; + + LLSD& contrastBase = (defaultEffect["contrast_base"] = LLSD::emptyArray()); + contrastBase.append(1.0); + contrastBase.append(1.0); + contrastBase.append(1.0); + contrastBase.append(0.5); + } + + setSelectedEffect("default"); +} + +LLPostProcess::~LLPostProcess(void) +{ + glDeleteTextures(1, &sceneRenderTexture); + glDeleteTextures(1, &noiseTexture); + glDeleteTextures(1, &tempBloomTexture); +} + +// static +void LLPostProcess::initClass(void) +{ + //this will cause system to crash at second time login + //if first time login fails due to network connection --- bao + //***llassert_always(gPostProcess == NULL); + //replaced by the following line: + if(gPostProcess) + return ; + + + gPostProcess = new LLPostProcess(); +} + +// static +void LLPostProcess::cleanupClass() +{ + delete gPostProcess; + gPostProcess = NULL; +} + +void LLPostProcess::setSelectedEffect(std::string const & effectName) +{ + mSelectedEffectName = effectName; + static_cast(tweaks) = mAllEffects[effectName]; +} + +void LLPostProcess::saveEffect(std::string const & effectName) +{ + mAllEffects[effectName] = tweaks; + + LLString pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME)); + //llinfos << "Saving PostProcess Effects settings to " << pathName << llendl; + + llofstream effectsXML(pathName.c_str()); + + LLPointer formatter = new LLSDXMLFormatter(); + + formatter->format(mAllEffects, effectsXML); +} + +void LLPostProcess::apply(unsigned int width, unsigned int height) +{ + if (!initialized || width != screenW || height != screenH){ + initialize(width, height); + } + if (shadersEnabled()){ + doEffects(); + } +} + +void LLPostProcess::initialize(unsigned int width, unsigned int height) +{ + screenW = width; + screenH = height; + createTexture(sceneRenderTexture, screenW, screenH); + initialized = true; + + checkError(); + createNightVisionShader(); + createBloomShader(); + createColorFilterShader(); + checkError(); +} + +inline bool LLPostProcess::shadersEnabled(void) +{ + return (tweaks.useColorFilter().asBoolean() || + tweaks.useNightVisionShader().asBoolean() || + tweaks.useBloomShader().asBoolean() ); + +} + +void LLPostProcess::applyShaders(void) +{ + if (tweaks.useColorFilter()){ + applyColorFilterShader(); + checkError(); + } + if (tweaks.useNightVisionShader()){ + /// If any of the above shaders have been called update the frame buffer; + if (tweaks.useColorFilter()){ + copyFrameBuffer(sceneRenderTexture, screenW, screenH); + } + applyNightVisionShader(); + checkError(); + } + if (tweaks.useBloomShader()){ + /// If any of the above shaders have been called update the frame buffer; + if (tweaks.useColorFilter().asBoolean() || tweaks.useNightVisionShader().asBoolean()){ + copyFrameBuffer(sceneRenderTexture, screenW, screenH); + } + applyBloomShader(); + checkError(); + } +} + +void LLPostProcess::applyColorFilterShader(void) +{ + gPostColorFilterProgram.bind(); + + glClientActiveTextureARB(GL_TEXTURE0_ARB); + glActiveTextureARB(GL_TEXTURE0_ARB); + glEnable(GL_TEXTURE_RECTANGLE_ARB); + + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, sceneRenderTexture); + + getShaderUniforms(colorFilterUniforms, gPostColorFilterProgram.mProgramObject); + glUniform1iARB(colorFilterUniforms["RenderTexture"], 0); + glUniform1fARB(colorFilterUniforms["brightness"], tweaks.getBrightness()); + glUniform1fARB(colorFilterUniforms["contrast"], tweaks.getContrast()); + float baseI = (tweaks.getContrastBaseR() + tweaks.getContrastBaseG() + tweaks.getContrastBaseB()) / 3.0f; + baseI = tweaks.getContrastBaseIntensity() / ((baseI < 0.001f) ? 0.001f : baseI); + float baseR = tweaks.getContrastBaseR() * baseI; + float baseG = tweaks.getContrastBaseG() * baseI; + float baseB = tweaks.getContrastBaseB() * baseI; + glUniform3fARB(colorFilterUniforms["contrastBase"], baseR, baseG, baseB); + glUniform1fARB(colorFilterUniforms["saturation"], tweaks.getSaturation()); + glUniform3fARB(colorFilterUniforms["lumWeights"], LUMINANCE_R, LUMINANCE_G, LUMINANCE_B); + + LLGLEnable blend(GL_BLEND); + gGL.blendFunc(GL_ONE,GL_ZERO); + LLGLDepthTest depth(GL_FALSE); + + /// Draw a screen space quad + drawOrthoQuad(screenW, screenH, QUAD_NORMAL); + gPostColorFilterProgram.unbind(); +} + +void LLPostProcess::createColorFilterShader(void) +{ + /// Define uniform names + colorFilterUniforms["RenderTexture"] = 0; + colorFilterUniforms["brightness"] = 0; + colorFilterUniforms["contrast"] = 0; + colorFilterUniforms["contrastBase"] = 0; + colorFilterUniforms["saturation"] = 0; + colorFilterUniforms["lumWeights"] = 0; +} + +void LLPostProcess::applyNightVisionShader(void) +{ + gPostNightVisionProgram.bind(); + + glClientActiveTextureARB(GL_TEXTURE0_ARB); + glActiveTextureARB(GL_TEXTURE0_ARB); + glEnable(GL_TEXTURE_RECTANGLE_ARB); + + getShaderUniforms(nightVisionUniforms, gPostNightVisionProgram.mProgramObject); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, sceneRenderTexture); + glUniform1iARB(nightVisionUniforms["RenderTexture"], 0); + + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glActiveTextureARB(GL_TEXTURE1_ARB); + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, noiseTexture); + glUniform1iARB(nightVisionUniforms["NoiseTexture"], 1); + + + glUniform1fARB(nightVisionUniforms["brightMult"], tweaks.getBrightMult()); + glUniform1fARB(nightVisionUniforms["noiseStrength"], tweaks.getNoiseStrength()); + noiseTextureScale = 0.01f + ((101.f - tweaks.getNoiseSize()) / 100.f); + noiseTextureScale *= (screenH / NOISE_SIZE); + + + glUniform3fARB(nightVisionUniforms["lumWeights"], LUMINANCE_R, LUMINANCE_G, LUMINANCE_B); + + LLGLEnable blend(GL_BLEND); + gGL.blendFunc(GL_ONE,GL_ZERO); + LLGLDepthTest depth(GL_FALSE); + + /// Draw a screen space quad + drawOrthoQuad(screenW, screenH, QUAD_NOISE); + gPostNightVisionProgram.unbind(); + glActiveTextureARB(GL_TEXTURE0_ARB); +} + +void LLPostProcess::createNightVisionShader(void) +{ + /// Define uniform names + nightVisionUniforms["RenderTexture"] = 0; + nightVisionUniforms["NoiseTexture"] = 0; + nightVisionUniforms["brightMult"] = 0; + nightVisionUniforms["noiseStrength"] = 0; + nightVisionUniforms["lumWeights"] = 0; + + createNoiseTexture(noiseTexture); +} + +void LLPostProcess::applyBloomShader(void) +{ + +} + +void LLPostProcess::createBloomShader(void) +{ + createTexture(tempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5)); + + /// Create Bloom Extract Shader + bloomExtractUniforms["RenderTexture"] = 0; + bloomExtractUniforms["extractLow"] = 0; + bloomExtractUniforms["extractHigh"] = 0; + bloomExtractUniforms["lumWeights"] = 0; + + /// Create Bloom Blur Shader + bloomBlurUniforms["RenderTexture"] = 0; + bloomBlurUniforms["bloomStrength"] = 0; + bloomBlurUniforms["texelSize"] = 0; + bloomBlurUniforms["blurDirection"] = 0; + bloomBlurUniforms["blurWidth"] = 0; +} + +void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog) +{ + /// Find uniform locations and insert into map + std::map::iterator i; + for (i = uniforms.begin(); i != uniforms.end(); ++i){ + i->second = glGetUniformLocationARB(prog, i->first); + } +} + +void LLPostProcess::doEffects(void) +{ + /// Save GL State + glPushAttrib(GL_ALL_ATTRIB_BITS); + glPushClientAttrib(GL_ALL_ATTRIB_BITS); + + /// Copy the screen buffer to the render texture + copyFrameBuffer(sceneRenderTexture, screenW, screenH); + + /// Clear the frame buffer. + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + /// Change to an orthogonal view + viewOrthogonal(screenW, screenH); + + checkError(); + applyShaders(); + + glUseProgramObjectARB(0); + checkError(); + + /// Change to a perspective view + viewPerspective(); + + /// Reset GL State + glPopClientAttrib(); + glPopAttrib(); + checkError(); +} + +void LLPostProcess::copyFrameBuffer(GLuint & texture, unsigned int width, unsigned int height) +{ + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); + glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, width, height, 0); +} + +void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadType type) +{ +#if 0 + float noiseX = 0.f; + float noiseY = 0.f; + float screenRatio = 1.0f; + + if (type == QUAD_NOISE){ + noiseX = ((float) rand() / (float) RAND_MAX); + noiseY = ((float) rand() / (float) RAND_MAX); + screenRatio = (float) width / (float) height; + } + + + glBegin(GL_QUADS); + if (type != QUAD_BLOOM_EXTRACT){ + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, (GLfloat) height); + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, (GLfloat) height * 2.0f); + } + if (type == QUAD_NOISE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, + noiseX, + noiseTextureScale + noiseY); + } else if (type == QUAD_BLOOM_COMBINE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.f, (GLfloat) height * 0.5f); + } + glVertex2f(0.f, (GLfloat) screenH - height); + + if (type != QUAD_BLOOM_EXTRACT){ + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, 0.f); + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, 0.f); + } + if (type == QUAD_NOISE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, + noiseX, + noiseY); + } else if (type == QUAD_BLOOM_COMBINE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.f, 0.f); + } + glVertex2f(0.f, (GLfloat) height + (screenH - height)); + + + if (type != QUAD_BLOOM_EXTRACT){ + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width, 0.f); + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width * 2.0f, 0.f); + } + if (type == QUAD_NOISE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, + screenRatio * noiseTextureScale + noiseX, + noiseY); + } else if (type == QUAD_BLOOM_COMBINE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (GLfloat) width * 0.5f, 0.f); + } + glVertex2f((GLfloat) width, (GLfloat) height + (screenH - height)); + + + if (type != QUAD_BLOOM_EXTRACT){ + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width, (GLfloat) height); + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width * 2.0f, (GLfloat) height * 2.0f); + } + if (type == QUAD_NOISE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, + screenRatio * noiseTextureScale + noiseX, + noiseTextureScale + noiseY); + } else if (type == QUAD_BLOOM_COMBINE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (GLfloat) width * 0.5f, (GLfloat) height * 0.5f); + } + glVertex2f((GLfloat) width, (GLfloat) screenH - height); + glEnd(); +#endif +} + +void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height) +{ + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f ); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); +} + +void LLPostProcess::viewPerspective(void) +{ + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + glPopMatrix(); +} + +void LLPostProcess::changeOrthogonal(unsigned int width, unsigned int height) +{ + viewPerspective(); + viewOrthogonal(width, height); +} + +void LLPostProcess::createTexture(GLuint & texture, unsigned int width, unsigned int height) +{ + if (texture != 0){ + glDeleteTextures(1, &texture); + } + + std::vector data(width * height * 4, 0); + + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +} + +void LLPostProcess::createNoiseTexture(GLuint & texture) +{ + if (texture != 0){ + glDeleteTextures(1, &texture); + } + glGenTextures(1, &texture); + + std::vector buffer(NOISE_SIZE * NOISE_SIZE); + for (unsigned int i = 0; i < NOISE_SIZE; i++){ + for (unsigned int k = 0; k < NOISE_SIZE; k++){ + buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f); + } + } + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +} + +bool LLPostProcess::checkError(void) +{ + GLenum glErr; + bool retCode = false; + + glErr = glGetError(); + while (glErr != GL_NO_ERROR) + { + // shaderErrorLog << (const char *) gluErrorString(glErr) << std::endl; + char const * err_str_raw = (const char *) gluErrorString(glErr); + + if(err_str_raw == NULL) + { + std::ostringstream err_builder; + err_builder << "unknown error number " << glErr; + mShaderErrorString = err_builder.str(); + } + else + { + mShaderErrorString = err_str_raw; + } + + retCode = true; + glErr = glGetError(); + } + return retCode; +} + +void LLPostProcess::checkShaderError(GLhandleARB shader) +{ + GLint infologLength = 0; + GLint charsWritten = 0; + GLchar *infoLog; + + checkError(); // Check for OpenGL errors + + glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength); + + checkError(); // Check for OpenGL errors + + if (infologLength > 0) + { + infoLog = (GLchar *)malloc(infologLength); + if (infoLog == NULL) + { + /// Could not allocate infolog buffer + return; + } + glGetInfoLogARB(shader, infologLength, &charsWritten, infoLog); + // shaderErrorLog << (char *) infoLog << std::endl; + mShaderErrorString = (char *) infoLog; + free(infoLog); + } + checkError(); // Check for OpenGL errors +} + +void LLPostProcess::textureBlendReplace(void) +{ + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); + glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); +} + +void LLPostProcess::textureBlendAdd(void) +{ + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); + glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); +} + +void LLPostProcess::textureBlendAddSigned(void) +{ + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); + glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD_SIGNED ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); +} + +void LLPostProcess::textureBlendSubtract(void) +{ + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); + glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_SUBTRACT ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); +} + +void LLPostProcess::textureBlendAlpha(void) +{ + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); + glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA ); +} + +void LLPostProcess::textureBlendMultiply(void) +{ + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); + glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); +} + +void LLPostProcess::textureBlendMultiplyX2(void) +{ + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); + glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); + glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, 2 ); +} diff --git a/linden/indra/newview/llpostprocess.h b/linden/indra/newview/llpostprocess.h new file mode 100644 index 0000000..2e98fb3 --- /dev/null +++ b/linden/indra/newview/llpostprocess.h @@ -0,0 +1,275 @@ +/** + * @file llpostprocess.h + * @brief LLPostProcess class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_POSTPROCESS_H +#define LL_POSTPROCESS_H + +#include +#include +#include "llgl.h" +#include "llglheaders.h" + +class LLPostProcess +{ +public: + + typedef enum _QuadType { + QUAD_NORMAL, + QUAD_NOISE, + QUAD_BLOOM_EXTRACT, + QUAD_BLOOM_COMBINE + } QuadType; + + /// GLSL Shader Encapsulation Struct + typedef std::map glslUniforms; + + struct PostProcessTweaks : public LLSD { + inline PostProcessTweaks() : LLSD(LLSD::emptyMap()) + { + } + + inline LLSD & brightMult() { + return (*this)["brightness_multiplier"]; + } + + inline LLSD & noiseStrength() { + return (*this)["noise_strength"]; + } + + inline LLSD & noiseSize() { + return (*this)["noise_size"]; + } + + inline LLSD & extractLow() { + return (*this)["extract_low"]; + } + + inline LLSD & extractHigh() { + return (*this)["extract_high"]; + } + + inline LLSD & bloomWidth() { + return (*this)["bloom_width"]; + } + + inline LLSD & bloomStrength() { + return (*this)["bloom_strength"]; + } + + inline LLSD & brightness() { + return (*this)["brightness"]; + } + + inline LLSD & contrast() { + return (*this)["contrast"]; + } + + inline LLSD & contrastBaseR() { + return (*this)["contrast_base"][0]; + } + + inline LLSD & contrastBaseG() { + return (*this)["contrast_base"][1]; + } + + inline LLSD & contrastBaseB() { + return (*this)["contrast_base"][2]; + } + + inline LLSD & contrastBaseIntensity() { + return (*this)["contrast_base"][3]; + } + + inline LLSD & saturation() { + return (*this)["saturation"]; + } + + inline LLSD & useNightVisionShader() { + return (*this)["enable_night_vision"]; + } + + inline LLSD & useBloomShader() { + return (*this)["enable_bloom"]; + } + + inline LLSD & useColorFilter() { + return (*this)["enable_color_filter"]; + } + + + inline F32 getBrightMult() const { + return F32((*this)["brightness_multiplier"].asReal()); + } + + inline F32 getNoiseStrength() const { + return F32((*this)["noise_strength"].asReal()); + } + + inline F32 getNoiseSize() const { + return F32((*this)["noise_size"].asReal()); + } + + inline F32 getExtractLow() const { + return F32((*this)["extract_low"].asReal()); + } + + inline F32 getExtractHigh() const { + return F32((*this)["extract_high"].asReal()); + } + + inline F32 getBloomWidth() const { + return F32((*this)["bloom_width"].asReal()); + } + + inline F32 getBloomStrength() const { + return F32((*this)["bloom_strength"].asReal()); + } + + inline F32 getBrightness() const { + return F32((*this)["brightness"].asReal()); + } + + inline F32 getContrast() const { + return F32((*this)["contrast"].asReal()); + } + + inline F32 getContrastBaseR() const { + return F32((*this)["contrast_base"][0].asReal()); + } + + inline F32 getContrastBaseG() const { + return F32((*this)["contrast_base"][1].asReal()); + } + + inline F32 getContrastBaseB() const { + return F32((*this)["contrast_base"][2].asReal()); + } + + inline F32 getContrastBaseIntensity() const { + return F32((*this)["contrast_base"][3].asReal()); + } + + inline F32 getSaturation() const { + return F32((*this)["saturation"].asReal()); + } + + }; + + GLuint sceneRenderTexture; + GLuint noiseTexture; + GLuint tempBloomTexture; + bool initialized; + PostProcessTweaks tweaks; + + // the map of all availible effects + LLSD mAllEffects; + +public: + LLPostProcess(void); + + ~LLPostProcess(void); + + void apply(unsigned int width, unsigned int height); + + /// Perform global initialization for this class. + static void initClass(void); + + // Cleanup of global data that's only inited once per class. + static void cleanupClass(); + + void setSelectedEffect(std::string const & effectName); + + inline LLString const & getSelectedEffect(void) const { + return mSelectedEffectName; + } + + void saveEffect(std::string const & effectName); + +private: + /// read in from file + std::string mShaderErrorString; + unsigned int screenW; + unsigned int screenH; + + float noiseTextureScale; + + /// Shader Uniforms + glslUniforms nightVisionUniforms; + glslUniforms bloomExtractUniforms; + glslUniforms bloomBlurUniforms; + glslUniforms colorFilterUniforms; + + // the name of currently selected effect in mAllEffects + // invariant: tweaks == mAllEffects[mSelectedEffectName] + LLString mSelectedEffectName; + + /// General functions + void initialize(unsigned int width, unsigned int height); + void doEffects(void); + void applyShaders(void); + bool shadersEnabled(void); + + /// Night Vision Functions + void createNightVisionShader(void); + void applyNightVisionShader(void); + + /// Bloom Functions + void createBloomShader(void); + void applyBloomShader(void); + + /// Color Filter Functions + void createColorFilterShader(void); + void applyColorFilterShader(void); + + /// OpenGL Helper Functions + void getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog); + void createTexture(GLuint & texture, unsigned int width, unsigned int height); + void copyFrameBuffer(GLuint & texture, unsigned int width, unsigned int height); + void createNoiseTexture(GLuint & texture); + bool checkError(void); + void checkShaderError(GLhandleARB shader); + void drawOrthoQuad(unsigned int width, unsigned int height, QuadType type); + void viewOrthogonal(unsigned int width, unsigned int height); + void changeOrthogonal(unsigned int width, unsigned int height); + void viewPerspective(void); + void textureBlendReplace(void); + void textureBlendAdd(void); + void textureBlendSubtract(void); + void textureBlendAddSigned(void); + void textureBlendAlpha(void); + void textureBlendMultiply(void); + void textureBlendMultiplyX2(void); +}; + +extern LLPostProcess * gPostProcess; + + +#endif // LL_POSTPROCESS_H diff --git a/linden/indra/newview/llprefsim.cpp b/linden/indra/newview/llprefsim.cpp index 40263fc..168d218 100644 --- a/linden/indra/newview/llprefsim.cpp +++ b/linden/indra/newview/llprefsim.cpp @@ -136,7 +136,7 @@ BOOL LLPrefsIMImpl::postBuild() mGotPersonalInfo = false; mOriginalIMViaEmail = false; mOriginalHideOnlineStatus = true; - childSetLabelArg("send_im_to_email", "[EMAIL]", childGetText("log_in_to_change")); + childSetLabelArg("send_im_to_email", "[EMAIL]", getString("log_in_to_change")); // Don't enable this until we get personal data childDisable("online_visibility"); @@ -151,7 +151,7 @@ BOOL LLPrefsIMImpl::postBuild() childDisable("log_chat_IM"); childDisable("log_date_timestamp"); - childSetText("busy_response", childGetText("log_in_to_change")); + childSetText("busy_response", getString("log_in_to_change")); refresh(); diff --git a/linden/indra/newview/llprefsvoice.cpp b/linden/indra/newview/llprefsvoice.cpp index 33a3cec..9751ea7 100644 --- a/linden/indra/newview/llprefsvoice.cpp +++ b/linden/indra/newview/llprefsvoice.cpp @@ -118,6 +118,7 @@ void LLPrefsVoiceLogic::refresh() bool enable = !gDisableVoice && gSavedSettings.getBOOL("EnableVoiceChat"); + mPanel->childSetEnabled("friends_only_check", enable); mPanel->childSetEnabled("push_to_talk_check", enable); mPanel->childSetEnabled("push_to_talk_label", enable); mPanel->childSetEnabled("voice_call_friends_only_check", enable); diff --git a/linden/indra/newview/llpreview.cpp b/linden/indra/newview/llpreview.cpp index 0549b16..8827598 100644 --- a/linden/indra/newview/llpreview.cpp +++ b/linden/indra/newview/llpreview.cpp @@ -56,7 +56,7 @@ // Globals and statics LLPreview::preview_multimap_t LLPreview::sPreviewsBySource; LLPreview::preview_map_t LLPreview::sInstances; -std::map LLMultiPreview::sAutoOpenPreviewHandles; +std::map > LLMultiPreview::sAutoOpenPreviewHandles; // Functions LLPreview::LLPreview(const std::string& name) : @@ -72,7 +72,7 @@ LLPreview::LLPreview(const std::string& name) : // don't add to instance list, since ItemID is null mAuxItem = new LLInventoryItem; // (LLPointer is auto-deleted) // don't necessarily steal focus on creation -- sometimes these guys pop up without user action - mAutoFocus = FALSE; + setAutoFocus(FALSE); gInventory.addObserver(this); } @@ -91,7 +91,7 @@ LLPreview::LLPreview(const std::string& name, const LLRect& rect, const std::str { mAuxItem = new LLInventoryItem; // don't necessarily steal focus on creation -- sometimes these guys pop up without user action - mAutoFocus = FALSE; + setAutoFocus(FALSE); if (mItemUUID.notNull()) { @@ -114,7 +114,7 @@ LLPreview::~LLPreview() preview_multimap_t::iterator found_it = sPreviewsBySource.find(mSourceID); for (; found_it != sPreviewsBySource.end(); ++found_it) { - if (found_it->second == mViewHandle) + if (found_it->second == getHandle()) { sPreviewsBySource.erase(found_it); break; @@ -152,7 +152,7 @@ void LLPreview::setSourceID(const LLUUID& source_id) preview_multimap_t::iterator found_it = sPreviewsBySource.find(mSourceID); for (; found_it != sPreviewsBySource.end(); ++found_it) { - if (found_it->second == mViewHandle) + if (found_it->second == getHandle()) { sPreviewsBySource.erase(found_it); break; @@ -160,7 +160,7 @@ void LLPreview::setSourceID(const LLUUID& source_id) } } mSourceID = source_id; - sPreviewsBySource.insert(preview_multimap_t::value_type(mSourceID, mViewHandle)); + sPreviewsBySource.insert(preview_multimap_t::value_type(mSourceID, getHandle())); } const LLViewerInventoryItem *LLPreview::getItem() const @@ -427,8 +427,7 @@ BOOL LLPreview::handleHover(S32 x, S32 y, MASK mask) void LLPreview::open() /*Flawfinder: ignore*/ { - LLMultiFloater* hostp = getHost(); - if (!sHostp && !hostp && getAssetStatus() == PREVIEW_ASSET_UNLOADED) + if (!getFloaterHost() && !getHost() && getAssetStatus() == PREVIEW_ASSET_UNLOADED) { loadAsset(); } @@ -468,6 +467,7 @@ void LLPreview::onBtnCopyToInv(void* userdata) cb); } } + self->close(); } // static @@ -523,14 +523,14 @@ LLPreview* LLPreview::getFirstPreviewForSource(const LLUUID& source_id) if (found_it != sPreviewsBySource.end()) { // just return first one - return (LLPreview*)LLFloater::getFloaterByHandle(found_it->second); + return (LLPreview*)found_it->second.get(); } return NULL; } void LLPreview::userSetShape(const LLRect& new_rect) { - if(new_rect.getWidth() != mRect.getWidth() || new_rect.getHeight() != mRect.getHeight()) + if(new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight()) { userResized(); } @@ -559,7 +559,7 @@ void LLMultiPreview::open() /*Flawfinder: ignore*/ void LLMultiPreview::userSetShape(const LLRect& new_rect) { - if(new_rect.getWidth() != mRect.getWidth() || new_rect.getHeight() != mRect.getHeight()) + if(new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight()) { LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel(); if (frontmost_preview) frontmost_preview->userResized(); @@ -583,7 +583,7 @@ LLMultiPreview* LLMultiPreview::getAutoOpenInstance(const LLUUID& id) handle_map_t::iterator found_it = sAutoOpenPreviewHandles.find(id); if (found_it != sAutoOpenPreviewHandles.end()) { - return (LLMultiPreview*)gFloaterView->getFloaterByHandle(found_it->second); + return (LLMultiPreview*)found_it->second.get(); } return NULL; } diff --git a/linden/indra/newview/llpreview.h b/linden/indra/newview/llpreview.h index 8a4a434..6265943 100644 --- a/linden/indra/newview/llpreview.h +++ b/linden/indra/newview/llpreview.h @@ -58,10 +58,12 @@ public: static void setAutoOpenInstance(LLMultiPreview* previewp, const LLUUID& id); protected: - typedef std::map handle_map_t; - static std::map sAutoOpenPreviewHandles; + typedef std::map > handle_map_t; + static handle_map_t sAutoOpenPreviewHandles; }; +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLPreview&oldid=81373 + class LLPreview : public LLFloater, LLInventoryObserver { public: @@ -160,7 +162,7 @@ protected: EAssetStatus mAssetStatus; typedef std::map preview_map_t; - typedef std::multimap preview_multimap_t; + typedef std::multimap > preview_multimap_t; static preview_multimap_t sPreviewsBySource; static preview_map_t sInstances; diff --git a/linden/indra/newview/llpreviewanim.cpp b/linden/indra/newview/llpreviewanim.cpp index 58478c8..ff8b3b5 100644 --- a/linden/indra/newview/llpreviewanim.cpp +++ b/linden/indra/newview/llpreviewanim.cpp @@ -96,8 +96,8 @@ LLPreviewAnim::LLPreviewAnim(const std::string& name, const LLRect& rect, const // static void LLPreviewAnim::endAnimCallback( void *userdata ) { - LLViewHandle* handlep = ((LLViewHandle*)userdata); - LLFloater* self = getFloaterByHandle(*handlep); + LLHandle* handlep = ((LLHandle*)userdata); + LLFloater* self = handlep->get(); delete handlep; // done with the handle if (self) { @@ -132,7 +132,7 @@ void LLPreviewAnim::playAnim( void *userdata ) if (motion) { - motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLViewHandle(self->getHandle()))); + motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLHandle(self->getHandle()))); } } else @@ -169,7 +169,7 @@ void LLPreviewAnim::auditionAnim( void *userdata ) if (motion) { - motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLViewHandle(self->getHandle()))); + motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLHandle(self->getHandle()))); } } else @@ -180,33 +180,6 @@ void LLPreviewAnim::auditionAnim( void *userdata ) } } -void LLPreviewAnim::saveAnim( void *userdata ) -{ - LLPreviewAnim* self = (LLPreviewAnim*) userdata; - const LLInventoryItem *item = self->getItem(); - - if(item) - { - LLKeyframeMotion* motionp = (LLKeyframeMotion*)gAgent.getAvatarObject()->createMotion( item->getAssetUUID() ); - if (motionp && motionp->isLoaded()) - { - LLFilePicker& picker = LLFilePicker::instance(); - LLString proposed_name = item->getName() + LLString(".xaf"); - if (picker.getSaveFile(LLFilePicker::FFSAVE_ANIM, proposed_name.c_str())) - { - apr_file_t* fp = ll_apr_file_open(picker.getFirstFile(), LL_APR_W); - if (!fp) - { - llwarns << "Unable to open file " << picker.getFirstFile() << llendl; - return; - } - motionp->writeCAL3D(fp); - apr_file_close(fp); - } - } - } -} - void LLPreviewAnim::onClose(bool app_quitting) { const LLInventoryItem *item = getItem(); diff --git a/linden/indra/newview/llpreviewanim.h b/linden/indra/newview/llpreviewanim.h index 430bc62..74408ed 100644 --- a/linden/indra/newview/llpreviewanim.h +++ b/linden/indra/newview/llpreviewanim.h @@ -45,7 +45,6 @@ public: static void playAnim( void* userdata ); static void auditionAnim( void* userdata ); - static void saveAnim( void* userdata ); static void endAnimCallback( void *userdata ); protected: diff --git a/linden/indra/newview/llpreviewgesture.cpp b/linden/indra/newview/llpreviewgesture.cpp index 1bd86fc..3594642 100644 --- a/linden/indra/newview/llpreviewgesture.cpp +++ b/linden/indra/newview/llpreviewgesture.cpp @@ -585,7 +585,7 @@ void LLPreviewGesture::addAnimations() combo->removeall(); - LLString none_text = childGetText("none_text"); + LLString none_text = getString("none_text"); combo->add(none_text, LLUUID::null); @@ -640,7 +640,7 @@ void LLPreviewGesture::addSounds() LLComboBox* combo = mSoundCombo; combo->removeall(); - LLString none_text = childGetText("none_text"); + LLString none_text = getString("none_text"); combo->add(none_text, LLUUID::null); @@ -789,7 +789,7 @@ void LLPreviewGesture::refresh() case STEP_ANIMATION: { LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; - optionstext = childGetText("step_anim"); + optionstext = getString("step_anim"); mAnimationCombo->setVisible(TRUE); mAnimationRadio->setVisible(TRUE); mAnimationRadio->setSelectedIndex((anim_step->mFlags & ANIM_FLAG_STOP) ? 1 : 0); @@ -799,7 +799,7 @@ void LLPreviewGesture::refresh() case STEP_SOUND: { LLGestureStepSound* sound_step = (LLGestureStepSound*)step; - optionstext = childGetText("step_sound"); + optionstext = getString("step_sound"); mSoundCombo->setVisible(TRUE); mSoundCombo->setCurrentByID(sound_step->mSoundAssetID); break; @@ -807,7 +807,7 @@ void LLPreviewGesture::refresh() case STEP_CHAT: { LLGestureStepChat* chat_step = (LLGestureStepChat*)step; - optionstext = childGetText("step_chat"); + optionstext = getString("step_chat"); mChatEditor->setVisible(TRUE); mChatEditor->setText(chat_step->mChatText); break; @@ -815,7 +815,7 @@ void LLPreviewGesture::refresh() case STEP_WAIT: { LLGestureStepWait* wait_step = (LLGestureStepWait*)step; - optionstext = childGetText("step_wait"); + optionstext = getString("step_wait"); mWaitAnimCheck->setVisible(TRUE); mWaitAnimCheck->set(wait_step->mFlags & WAIT_FLAG_ALL_ANIM); mWaitTimeCheck->setVisible(TRUE); @@ -1753,7 +1753,7 @@ void LLPreviewGesture::onClickPreview(void* data) self->mPreviewGesture->mCallbackData = self; // set the button title - self->mPreviewBtn->setLabel(self->childGetText("stop_txt")); + self->mPreviewBtn->setLabel(self->getString("stop_txt")); // play it, and delete when done gGestureManager.playGesture(self->mPreviewGesture); @@ -1775,7 +1775,7 @@ void LLPreviewGesture::onDonePreview(LLMultiGesture* gesture, void* data) { LLPreviewGesture* self = (LLPreviewGesture*)data; - self->mPreviewBtn->setLabel(self->childGetText("preview_txt")); + self->mPreviewBtn->setLabel(self->getString("preview_txt")); delete self->mPreviewGesture; self->mPreviewGesture = NULL; diff --git a/linden/indra/newview/llpreviewlandmark.cpp b/linden/indra/newview/llpreviewlandmark.cpp index 0d9a298..af49aee 100644 --- a/linden/indra/newview/llpreviewlandmark.cpp +++ b/linden/indra/newview/llpreviewlandmark.cpp @@ -65,7 +65,6 @@ // LLPreviewLandmark // static -//LLDoubleLinkedList LLPreviewLandmark::sOrderedInstances; LLPreviewLandmarkList LLPreviewLandmark::sOrderedInstances; diff --git a/linden/indra/newview/llpreviewlandmark.h b/linden/indra/newview/llpreviewlandmark.h index 5ec2b5a..2204d2d 100644 --- a/linden/indra/newview/llpreviewlandmark.h +++ b/linden/indra/newview/llpreviewlandmark.h @@ -97,7 +97,6 @@ private: LLLandmark* mLandmark; LLColor4 mMarkerColor; - //static LLDoubleLinkedList< LLPreviewLandmark > sOrderedInstances; static LLPreviewLandmarkList sOrderedInstances; }; diff --git a/linden/indra/newview/llpreviewnotecard.cpp b/linden/indra/newview/llpreviewnotecard.cpp index 1f0c9dc..6d7884b 100644 --- a/linden/indra/newview/llpreviewnotecard.cpp +++ b/linden/indra/newview/llpreviewnotecard.cpp @@ -307,7 +307,7 @@ void LLPreviewNotecard::loadAsset() // The object that we're trying to look at disappeared, bail. llwarns << "Can't find object " << mObjectUUID << " associated with notecard." << llendl; mAssetID.setNull(); - editor->setText(childGetText("no_object")); + editor->setText(getString("no_object")); editor->makePristine(); editor->setEnabled(FALSE); mAssetStatus = PREVIEW_ASSET_LOADED; @@ -332,7 +332,7 @@ void LLPreviewNotecard::loadAsset() else { mAssetID.setNull(); - editor->setText(childGetText("not_allowed")); + editor->setText(getString("not_allowed")); editor->makePristine(); editor->setEnabled(FALSE); mAssetStatus = PREVIEW_ASSET_LOADED; @@ -654,7 +654,7 @@ void LLPreviewNotecard::reshape(S32 width, S32 height, BOOL called_from_parent) { // So that next time you open a script it will have the same height and width // (although not the same position). - gSavedSettings.setRect("NotecardEditorRect", mRect); + gSavedSettings.setRect("NotecardEditorRect", getRect()); } } diff --git a/linden/indra/newview/llpreviewscript.cpp b/linden/indra/newview/llpreviewscript.cpp index 3e2a476..e9a0b4a 100644 --- a/linden/indra/newview/llpreviewscript.cpp +++ b/linden/indra/newview/llpreviewscript.cpp @@ -288,7 +288,7 @@ LLScriptEdCore::LLScriptEdCore( const LLRect& rect, const std::string& sample, const std::string& help, - const LLViewHandle& floater_handle, + const LLHandle& floater_handle, void (*load_callback)(void*), void (*save_callback)(void*, BOOL), void (*search_replace_callback) (void* userdata), @@ -343,19 +343,19 @@ LLScriptEdCore::LLScriptEdCore( LLKeywordToken *token; - LLKeywords::word_token_map_t::iterator token_it; - for (token_it = mEditor->mKeywords.mWordTokenMap.begin(); token_it != mEditor->mKeywords.mWordTokenMap.end(); ++token_it) + LLKeywords::keyword_iterator_t token_it; + for (token_it = mEditor->keywordsBegin(); token_it != mEditor->keywordsEnd(); ++token_it) { token = token_it->second; - if (token->mColor == color) - mFunctions->add(wstring_to_utf8str(token->mToken)); + if (token->getColor() == color) + mFunctions->add(wstring_to_utf8str(token->getToken())); } - for (token_it = mEditor->mKeywords.mWordTokenMap.begin(); token_it != mEditor->mKeywords.mWordTokenMap.end(); ++token_it) + for (token_it = mEditor->keywordsBegin(); token_it != mEditor->keywordsEnd(); ++token_it) { token = token_it->second; - if (token->mColor != color) - mFunctions->add(wstring_to_utf8str(token->mToken)); + if (token->getColor() != color) + mFunctions->add(wstring_to_utf8str(token->getToken())); } @@ -365,7 +365,7 @@ LLScriptEdCore::LLScriptEdCore( initMenu(); // Do the work that addTabPanel() normally does. - //LLRect tab_panel_rect( 0, mRect.getHeight(), mRect.getWidth(), 0 ); + //LLRect tab_panel_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 ); //tab_panel_rect.stretch( -LLPANEL_BORDER_WIDTH ); //mCodePanel->setFollowsAll(); //mCodePanel->translate( tab_panel_rect.mLeft - mCodePanel->getRect().mLeft, tab_panel_rect.mBottom - mCodePanel->getRect().mBottom); @@ -468,29 +468,27 @@ void LLScriptEdCore::draw() void LLScriptEdCore::updateDynamicHelp(BOOL immediate) { - LLFloater* help_floater = LLFloater::getFloaterByHandle(mLiveHelpHandle); + LLFloater* help_floater = mLiveHelpHandle.get(); if (!help_floater) return; -#if LL_LIBXUL_ENABLED // update back and forward buttons LLButton* fwd_button = LLUICtrlFactory::getButtonByName(help_floater, "fwd_btn"); LLButton* back_button = LLUICtrlFactory::getButtonByName(help_floater, "back_btn"); - LLWebBrowserCtrl* browser = LLUICtrlFactory::getWebBrowserCtrlByName(help_floater, "lsl_guide_html"); + LLWebBrowserCtrl* browser = help_floater->getChild("lsl_guide_html"); back_button->setEnabled(browser->canNavigateBack()); fwd_button->setEnabled(browser->canNavigateForward()); -#endif // LL_LIBXUL_ENABLED if (!immediate && !gSavedSettings.getBOOL("ScriptHelpFollowsCursor")) { return; } - LLTextSegment* segment = NULL; - std::vector selected_segments; + const LLTextSegment* segment = NULL; + std::vector selected_segments; mEditor->getSelectedSegments(selected_segments); // try segments in selection range first - std::vector::iterator segment_iter; + std::vector::iterator segment_iter; for (segment_iter = selected_segments.begin(); segment_iter != selected_segments.end(); ++segment_iter) { if((*segment_iter)->getToken() && (*segment_iter)->getToken()->getType() == LLKeywordToken::WORD) @@ -503,7 +501,7 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) // then try previous segment in case we just typed it if (!segment) { - LLTextSegment* test_segment = mEditor->getPreviousSegment(); + const LLTextSegment* test_segment = mEditor->getPreviousSegment(); if(test_segment->getToken() && test_segment->getToken()->getType() == LLKeywordToken::WORD) { segment = test_segment; @@ -532,10 +530,10 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) void LLScriptEdCore::setHelpPage(const LLString& help_string) { - LLFloater* help_floater = LLFloater::getFloaterByHandle(mLiveHelpHandle); + LLFloater* help_floater = mLiveHelpHandle.get(); if (!help_floater) return; - LLWebBrowserCtrl* web_browser = gUICtrlFactory->getWebBrowserCtrlByName(help_floater, "lsl_guide_html"); + LLWebBrowserCtrl* web_browser = help_floater->getChild("lsl_guide_html"); if (!web_browser) return; LLComboBox* history_combo = gUICtrlFactory->getComboBoxByName(help_floater, "history_combo"); @@ -546,16 +544,16 @@ void LLScriptEdCore::setHelpPage(const LLString& help_string) url_string.setArg("[LSL_STRING]", help_string); addHelpItemToHistory(help_string); -#if LL_LIBXUL_ENABLED + web_browser->navigateTo(url_string); -#endif // LL_LIBXUL_ENABLED + } void LLScriptEdCore::addHelpItemToHistory(const LLString& help_string) { if (help_string.empty()) return; - LLFloater* help_floater = LLFloater::getFloaterByHandle(mLiveHelpHandle); + LLFloater* help_floater = mLiveHelpHandle.get(); if (!help_floater) return; LLComboBox* history_combo = gUICtrlFactory->getComboBoxByName(help_floater, "history_combo"); @@ -662,7 +660,7 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata) { LLScriptEdCore* corep = (LLScriptEdCore*)userdata; - LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle); + LLFloater* live_help_floater = corep->mLiveHelpHandle.get(); if (live_help_floater) { live_help_floater->setFocus(TRUE); @@ -680,20 +678,18 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata) live_help_floater->childSetAction("back_btn", onClickBack, userdata); live_help_floater->childSetAction("fwd_btn", onClickForward, userdata); -#if LL_LIBXUL_ENABLED - LLWebBrowserCtrl* browser = LLUICtrlFactory::getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html"); + LLWebBrowserCtrl* browser = live_help_floater->getChild("lsl_guide_html"); browser->setAlwaysRefresh(TRUE); -#endif // LL_LIBXUL_ENABLED LLComboBox* help_combo = LLUICtrlFactory::getComboBoxByName(live_help_floater, "history_combo"); LLKeywordToken *token; - LLKeywords::word_token_map_t::iterator token_it; - for (token_it = corep->mEditor->mKeywords.mWordTokenMap.begin(); - token_it != corep->mEditor->mKeywords.mWordTokenMap.end(); + LLKeywords::keyword_iterator_t token_it; + for (token_it = corep->mEditor->keywordsBegin(); + token_it != corep->mEditor->keywordsEnd(); ++token_it) { token = token_it->second; - help_combo->add(wstring_to_utf8str(token->mToken)); + help_combo->add(wstring_to_utf8str(token->getToken())); } help_combo->sortByName(); @@ -707,35 +703,31 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata) //static void LLScriptEdCore::onClickBack(void* userdata) { -#if LL_LIBXUL_ENABLED LLScriptEdCore* corep = (LLScriptEdCore*)userdata; - LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle); + LLFloater* live_help_floater = corep->mLiveHelpHandle.get(); if (live_help_floater) { - LLWebBrowserCtrl* browserp = LLUICtrlFactory::getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html"); + LLWebBrowserCtrl* browserp = live_help_floater->getChild("lsl_guide_html"); if (browserp) { browserp->navigateBack(); } } -#endif // LL_LIBXUL_ENABLED } //static void LLScriptEdCore::onClickForward(void* userdata) { -#if LL_LIBXUL_ENABLED LLScriptEdCore* corep = (LLScriptEdCore*)userdata; - LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle); + LLFloater* live_help_floater = corep->mLiveHelpHandle.get(); if (live_help_floater) { - LLWebBrowserCtrl* browserp = LLUICtrlFactory::getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html"); + LLWebBrowserCtrl* browserp = live_help_floater->getChild("lsl_guide_html"); if (browserp) { browserp->navigateForward(); } } -#endif // LL_LIBXUL_ENABLED } // static @@ -765,20 +757,18 @@ void LLScriptEdCore::onHelpComboCommit(LLUICtrl* ctrl, void* userdata) { LLScriptEdCore* corep = (LLScriptEdCore*)userdata; - LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle); + LLFloater* live_help_floater = corep->mLiveHelpHandle.get(); if (live_help_floater) { LLString help_string = ctrl->getValue().asString(); corep->addHelpItemToHistory(help_string); -#if LL_LIBXUL_ENABLED - LLWebBrowserCtrl* web_browser = gUICtrlFactory->getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html"); + LLWebBrowserCtrl* web_browser = live_help_floater->getChild("lsl_guide_html"); LLUIString url_string = gSavedSettings.getString("LSLHelpURL"); url_string.setArg("[APP_DIRECTORY]", gDirUtilp->getWorkingDir()); url_string.setArg("[LSL_STRING]", help_string); web_browser->navigateTo(url_string); -#endif // LL_LIBXUL_ENABLED } } @@ -981,7 +971,7 @@ void LLScriptEdCore::handleReloadFromServerDialog( S32 option, void* userdata ) case 0: // "Yes" if( self->mLoadCallback ) { - self->mEditor->setText( self->childGetText("loading") ); + self->mEditor->setText( self->getString("loading") ); self->mLoadCallback( self->mUserdata ); } break; @@ -1081,7 +1071,7 @@ void* LLPreviewLSL::createScriptEdPanel(void* userdata) LLRect(), HELLO_LSL, HELP_LSL, - self->mViewHandle, + self->getHandle(), LLPreviewLSL::onLoad, LLPreviewLSL::onSave, LLPreviewLSL::onSearchReplace, @@ -1114,9 +1104,7 @@ LLPreviewLSL::LLPreviewLSL(const std::string& name, const LLRect& rect, childSetText("desc", item->getDescription()); childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe); - LLMultiFloater* hostp = getHost(); - - if (!sHostp && !hostp && getAssetStatus() == PREVIEW_ASSET_UNLOADED) + if (!getFloaterHost() && !getHost() && getAssetStatus() == PREVIEW_ASSET_UNLOADED) { loadAsset(); } @@ -1195,7 +1183,7 @@ void LLPreviewLSL::loadAsset() } else { - mScriptEd->mEditor->setText(mScriptEd->childGetText("can_not_view")); + mScriptEd->mEditor->setText(mScriptEd->getString("can_not_view")); mScriptEd->mEditor->makePristine(); mScriptEd->mEditor->setEnabled(FALSE); mScriptEd->mFunctions->setEnabled(FALSE); @@ -1575,7 +1563,7 @@ void LLPreviewLSL::reshape(S32 width, S32 height, BOOL called_from_parent) { // So that next time you open a script it will have the same height and width // (although not the same position). - gSavedSettings.setRect("PreviewScriptRect", mRect); + gSavedSettings.setRect("PreviewScriptRect", getRect()); } } @@ -1597,7 +1585,7 @@ void* LLLiveLSLEditor::createScriptEdPanel(void* userdata) LLRect(), HELLO_LSL, HELP_LSL, - self->mViewHandle, + self->getHandle(), &LLLiveLSLEditor::onLoad, &LLLiveLSLEditor::onSave, &LLLiveLSLEditor::onSearchReplace, @@ -1727,7 +1715,7 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new) || !gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)))) { mItem = new LLViewerInventoryItem(item); - mScriptEd->mEditor->setText(childGetText("not_allowed")); + mScriptEd->mEditor->setText(getString("not_allowed")); mScriptEd->mEditor->makePristine(); mScriptEd->mEditor->setEnabled(FALSE); mAssetStatus = PREVIEW_ASSET_LOADED; @@ -1981,12 +1969,12 @@ void LLLiveLSLEditor::draw() { if(object->permAnyOwner()) { - runningCheckbox->setLabel(childGetText("script_running")); + runningCheckbox->setLabel(getString("script_running")); runningCheckbox->setEnabled(TRUE); } else { - runningCheckbox->setLabel(childGetText("public_objects_can_not_run")); + runningCheckbox->setLabel(getString("public_objects_can_not_run")); runningCheckbox->setEnabled(FALSE); // *FIX: Set it to false so that the ui is correct for // a box that is released to public. It could be @@ -2234,7 +2222,7 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename, // If we successfully saved it, then we should be able to check/uncheck the running box! LLCheckBoxCtrl* runningCheckbox = LLUICtrlFactory::getCheckBoxByName(this, "running"); - runningCheckbox->setLabel(childGetText("script_running")); + runningCheckbox->setLabel(getString("script_running")); runningCheckbox->setEnabled(TRUE); } @@ -2414,6 +2402,6 @@ void LLLiveLSLEditor::reshape(S32 width, S32 height, BOOL called_from_parent) { // So that next time you open a script it will have the same height and width // (although not the same position). - gSavedSettings.setRect("PreviewScriptRect", mRect); + gSavedSettings.setRect("PreviewScriptRect", getRect()); } } diff --git a/linden/indra/newview/llpreviewscript.h b/linden/indra/newview/llpreviewscript.h index 92d56f8..21b8844 100644 --- a/linden/indra/newview/llpreviewscript.h +++ b/linden/indra/newview/llpreviewscript.h @@ -67,7 +67,7 @@ public: const LLRect& rect, const std::string& sample, const std::string& help, - const LLViewHandle& floater_handle, + const LLHandle& floater_handle, void (*load_callback)(void* userdata), void (*save_callback)(void* userdata, BOOL close_after_save), void (*search_replace_callback)(void* userdata), @@ -144,7 +144,7 @@ private: LLPanel* mCodePanel; LLScrollListCtrl* mErrorList; LLDynamicArray mBridges; - LLViewHandle mLiveHelpHandle; + LLHandle mLiveHelpHandle; LLKeywordToken* mLastHelpToken; LLFrameTimer mLiveHelpTimer; S32 mLiveHelpHistorySize; diff --git a/linden/indra/newview/llpreviewtexture.cpp b/linden/indra/newview/llpreviewtexture.cpp index d309d4a..b054db5 100644 --- a/linden/indra/newview/llpreviewtexture.cpp +++ b/linden/indra/newview/llpreviewtexture.cpp @@ -199,7 +199,7 @@ void LLPreviewTexture::draw() LLPreview::draw(); - if (!mMinimized) + if (!isMinimized()) { LLGLSUIDefault gls_ui; LLGLSNoTexture gls_notex; @@ -214,7 +214,6 @@ void LLPreviewTexture::draw() if ( mImage.notNull() ) { - LLGLSTexture gls_no_texture; // Draw the texture glColor3f( 1.f, 1.f, 1.f ); gl_draw_scaled_image(interior.mLeft, @@ -255,7 +254,7 @@ void LLPreviewTexture::draw() const S32 BAR_HEIGHT = 12; const S32 BAR_LEFT_PAD = 80; S32 left = interior.mLeft + 4 + BAR_LEFT_PAD; - S32 bar_width = mRect.getWidth() - left - RESIZE_HANDLE_WIDTH - 2; + S32 bar_width = getRect().getWidth() - left - RESIZE_HANDLE_WIDTH - 2; S32 top = interior.mBottom + 4 + BAR_HEIGHT; S32 right = left + bar_width; S32 bottom = top - BAR_HEIGHT; @@ -434,8 +433,8 @@ void LLPreviewTexture::updateAspectRatio() mLastWidth = client_width; mLastHeight = client_height; - S32 old_top = mRect.mTop; - S32 old_left = mRect.mLeft; + S32 old_top = getRect().mTop; + S32 old_left = getRect().mLeft; if (getHost()) { getHost()->growToFit(view_width, view_height); @@ -443,7 +442,7 @@ void LLPreviewTexture::updateAspectRatio() else { reshape( view_width, view_height ); - S32 new_bottom = old_top - mRect.getHeight(); + S32 new_bottom = old_top - getRect().getHeight(); setOrigin( old_left, new_bottom ); // Try to keep whole view onscreen, don't allow partial offscreen. gFloaterView->adjustToFitScreen(this, FALSE); @@ -454,20 +453,20 @@ void LLPreviewTexture::updateAspectRatio() if (!mUserResized) { // clamp texture size to fit within actual size of floater after attempting resize - client_width = llmin(client_width, mRect.getWidth() - horiz_pad); - client_height = llmin(client_height, mRect.getHeight() - PREVIEW_HEADER_SIZE + client_width = llmin(client_width, getRect().getWidth() - horiz_pad); + client_height = llmin(client_height, getRect().getHeight() - PREVIEW_HEADER_SIZE - (2 * CLIENT_RECT_VPAD) - LLPANEL_BORDER_WIDTH - info_height); } else { - client_width = mRect.getWidth() - horiz_pad; + client_width = getRect().getWidth() - horiz_pad; client_height = llround(client_width * inv_aspect_ratio); } - S32 max_height = mRect.getHeight() - PREVIEW_BORDER - button_height + S32 max_height = getRect().getHeight() - PREVIEW_BORDER - button_height - CLIENT_RECT_VPAD - info_height - CLIENT_RECT_VPAD - PREVIEW_HEADER_SIZE; max_height = llmax(max_height, 1); @@ -478,7 +477,7 @@ void LLPreviewTexture::updateAspectRatio() client_width = llround(client_height * aspect_ratio); } - LLRect window_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect window_rect(0, getRect().getHeight(), getRect().getWidth(), 0); window_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD); window_rect.mBottom += PREVIEW_BORDER + button_height + CLIENT_RECT_VPAD + info_height + CLIENT_RECT_VPAD; diff --git a/linden/indra/newview/llprogressview.cpp b/linden/indra/newview/llprogressview.cpp index c319e59..10b3115 100644 --- a/linden/indra/newview/llprogressview.cpp +++ b/linden/indra/newview/llprogressview.cpp @@ -36,6 +36,7 @@ #include "indra_constants.h" #include "llmath.h" #include "llgl.h" +#include "llglimmediate.h" #include "llui.h" #include "llfontgl.h" #include "llimagegl.h" @@ -74,7 +75,7 @@ LLProgressView::LLProgressView(const std::string& name, const LLRect &rect) const S32 CANCEL_BTN_OFFSET = 16; LLRect r; r.setOriginAndSize( - mRect.getWidth() - CANCEL_BTN_OFFSET - CANCEL_BTN_WIDTH, CANCEL_BTN_OFFSET, + getRect().getWidth() - CANCEL_BTN_OFFSET - CANCEL_BTN_WIDTH, CANCEL_BTN_OFFSET, CANCEL_BTN_WIDTH, BTN_HEIGHT ); mCancelBtn = new LLButton( @@ -162,7 +163,7 @@ void LLProgressView::draw() // Make sure the progress view always fills the entire window. S32 width = gViewerWindow->getWindowWidth(); S32 height = gViewerWindow->getWindowHeight(); - if( (width != mRect.getWidth()) || (height != mRect.getHeight()) ) + if( (width != getRect().getWidth()) || (height != getRect().getHeight()) ) { reshape( width, height ); } @@ -175,7 +176,7 @@ void LLProgressView::draw() { LLGLSUIDefault gls_ui; LLViewerImage::bindTexture(gStartImageGL); - glColor4f(1.f, 1.f, 1.f, mFadeTimer.getStarted() ? clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, FADE_IN_TIME, 1.f, 0.f) : 1.f); + gGL.color4f(1.f, 1.f, 1.f, mFadeTimer.getStarted() ? clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, FADE_IN_TIME, 1.f, 0.f) : 1.f); F32 image_aspect = (F32)gStartImageWidth / (F32)gStartImageHeight; F32 view_aspect = (F32)width / (F32)height; // stretch image to maintain aspect ratio @@ -189,14 +190,14 @@ void LLProgressView::draw() glTranslatef(0.f, -0.5f * (view_aspect / image_aspect - 1.f) * height, 0.f); glScalef(1.f, view_aspect / image_aspect, 1.f); } - gl_rect_2d_simple_tex( mRect.getWidth(), mRect.getHeight() ); + gl_rect_2d_simple_tex( getRect().getWidth(), getRect().getHeight() ); gStartImageGL->unbindTexture(0, GL_TEXTURE_2D); } else { LLGLSNoTexture gls_no_texture; - glColor4f(0.f, 0.f, 0.f, 1.f); - gl_rect_2d(mRect); + gGL.color4f(0.f, 0.f, 0.f, 1.f); + gl_rect_2d(getRect()); } glPopMatrix(); } @@ -213,8 +214,8 @@ void LLProgressView::draw() return; } - S32 line_x = mRect.getWidth() / 2; - S32 line_one_y = mRect.getHeight() / 2 + 64; + S32 line_x = getRect().getWidth() / 2; + S32 line_one_y = getRect().getHeight() / 2 + 64; const S32 LINE_SPACING = 25; S32 line_two_y = line_one_y - LINE_SPACING; const LLFontGL* font = LLFontGL::sSansSerif; @@ -243,8 +244,8 @@ void LLProgressView::draw() S32 bar_bottom = line_two_y - 30; S32 bar_height = 18; - S32 bar_width = mRect.getWidth() * 2 / 3; - S32 bar_left = (mRect.getWidth() / 2) - (bar_width / 2); + S32 bar_width = getRect().getWidth() * 2 / 3; + S32 bar_left = (getRect().getWidth() / 2) - (bar_width / 2); gl_draw_scaled_image_with_border( bar_left + 2, diff --git a/linden/indra/newview/llremoteparcelrequest.cpp b/linden/indra/newview/llremoteparcelrequest.cpp index abc6569..e0a6ada 100644 --- a/linden/indra/newview/llremoteparcelrequest.cpp +++ b/linden/indra/newview/llremoteparcelrequest.cpp @@ -44,7 +44,7 @@ #include "llview.h" #include "message.h" -LLRemoteParcelRequestResponder::LLRemoteParcelRequestResponder(LLViewHandle place_panel_handle) +LLRemoteParcelRequestResponder::LLRemoteParcelRequestResponder(LLHandle place_panel_handle) { mPlacePanelHandle = place_panel_handle; } @@ -53,7 +53,7 @@ void LLRemoteParcelRequestResponder::result(const LLSD& content) { LLUUID parcel_id = content["parcel_id"]; - LLPanelPlace* place_panelp = (LLPanelPlace*)LLPanel::getPanelByHandle(mPlacePanelHandle); + LLPanelPlace* place_panelp = (LLPanelPlace*)mPlacePanelHandle.get(); if(place_panelp) { @@ -67,7 +67,7 @@ void LLRemoteParcelRequestResponder::error(U32 status, const std::string& reason { llinfos << "LLRemoteParcelRequest::error(" << status << ": " << reason << ")" << llendl; - LLPanelPlace* place_panelp = (LLPanelPlace*)LLPanel::getPanelByHandle(mPlacePanelHandle); + LLPanelPlace* place_panelp = (LLPanelPlace*)mPlacePanelHandle.get(); if(place_panelp) { diff --git a/linden/indra/newview/llremoteparcelrequest.h b/linden/indra/newview/llremoteparcelrequest.h index fe48021..b80dd5b 100644 --- a/linden/indra/newview/llremoteparcelrequest.h +++ b/linden/indra/newview/llremoteparcelrequest.h @@ -35,19 +35,19 @@ #define LL_LLREMOTEPARCELREQUEST_H #include "llhttpclient.h" -#include "llview.h" +#include "llpanel.h" class LLRemoteParcelRequestResponder : public LLHTTPClient::Responder { public: - LLRemoteParcelRequestResponder(LLViewHandle place_panel_handle); + LLRemoteParcelRequestResponder(LLHandle place_panel_handle); //If we get back a normal response, handle it here virtual void result(const LLSD& content); //If we get back an error (not found, etc...), handle it here virtual void error(U32 status, const std::string& reason); protected: - LLViewHandle mPlacePanelHandle; + LLHandle mPlacePanelHandle; }; #endif // LL_LLREMOTEPARCELREQUEST_H diff --git a/linden/indra/newview/llroam.cpp b/linden/indra/newview/llroam.cpp deleted file mode 100644 index 90c92d0..0000000 --- a/linden/indra/newview/llroam.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/** - * @file llroam.cpp - * @brief LLRoam and related class implementations - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llroam.h" - -LLRoam* LLRoamTriNode::sQueues;// = new LLRoam(); - -void LLRoamTriNode::updateLink(LLRoamTriNode* old_link, LLRoamTriNode* new_link) -{ - if (old_link == mLeft) - mLeft = new_link; - else if (old_link == mRight) - mRight = new_link; - else if (old_link == mBase) - mBase = new_link; -} - -BOOL LLRoamTriNode::split(BOOL forceful) -{ - //U32 c1 = patch()->checkCount(); - if (forceful) - { - initForcefulRefine(); - } /*else { - if (!refine()) - return FALSE; - }*/ - - if (!leaf()) - return TRUE; - - if (mLchild == NULL) - { - mLchild = newLChild(); - mRchild = newRChild(); - - //mLchild->setPatch(patch()); - //mRchild->setPatch(patch()); - - mLchild->setLeft(mRchild); - mRchild->setRight(mLchild); - } - - mLchild->setBase(mLeft); - mRchild->setBase(mRight); - - if (mLeft) - mLeft->updateLink(this, mLchild); - if (mRight) - mRight->updateLink(this, mRchild); - - mLeaf = FALSE; - - patch()->numTrisInc(); - - //U32 c2 = patch()->checkCount(); - sQueues->numOfProcessedTrisInc(); - if (mBase == NULL) - return TRUE; - - if (mBase->base() != this) // not Diamond shape - mBase->split(TRUE); - - if (mBase->leaf()) - mBase->split(TRUE); - - mLchild->setRight(mBase->Rchild()); - mRchild->setLeft(mBase->Lchild()); - //U32 c3 = patch()->checkCount(); - return TRUE; -} - -BOOL LLRoamTriNode::merge() -{ - //U32 c1 = patch()->checkCount(); - if (leaf()) - return TRUE; - - if (mBase && mBase->refine()) - return FALSE; - - if (!mLchild->merge() || !mRchild->merge()) - return FALSE; - - //U32 c2 = patch()->checkCount(); - mLeft = mLchild->base(); - mRight = mRchild->base(); - - if (mLeft) - mLeft->updateLink(mLchild, this); - if (mRight) - mRight->updateLink(mRchild, this); - - //U32 c4 = patch()->checkCount(); - mLeaf = TRUE; - - patch()->numTrisDec(); - - //U32 c5 = patch()->checkCount(); - if (mBase != NULL) - { - if (!mBase->merge()) - { - mLeaf = FALSE; - patch()->numTrisInc(); - return FALSE; - } - } - - //U32 c6 = patch()->checkCount(); - return TRUE; -} - -void LLRoamTriNode::mergeSimple() -{ - mLeft = mLchild->base(); - mRight = mRchild->base(); - - if (mLeft) - mLeft->updateLink(mLchild, this); - if (mRight) - mRight->updateLink(mRchild, this); - - mLeaf = TRUE; - patch()->numTrisDec(); - sQueues->numOfProcessedTrisInc(); -} - -void LLRoamTriNode::update() -{ - if (refine()) - sQueues->queueForSplit(this); - else if (!leaf()) - sQueues->queueForMerge(this); -} - -/* -void LLRoamTriNode::update() -{ - //U32 c1 = patch()->checkCount(); - if (split()) - { - mLchild->update(); - mRchild->update(); - //U32 c2 = patch()->checkCount(); - } - else if (!leaf()) - { - merge(); - } -} -*/ - -LLRoamTriNode::~LLRoamTriNode() -{ - delete mLchild; - mLchild = 0; - delete mRchild; - mRchild = 0; - //delete sQueues; - //sQueues = 0; -} - - - -const LLRoamTriNode* LLRoamTriNode::getFirstLeaf() const -{ - const LLRoamTriNode* node = this; - while (!node->leaf()) - node = node->Lchild(); - return node; -} -const LLRoamTriNode* LLRoamTriNode::getNextLeaf() const -{ - const LLRoamTriNode* child = this; - const LLRoamTriNode* prev = parent(); - while (prev) { - if (prev->Lchild() == child) - return prev->Rchild()->getFirstLeaf(); - child = prev; - prev = prev->parent(); - }; - return NULL; -} - -void LLRoam::queueForSplit(LLRoamTriNode* t, BOOL process_base) -{ - //if (splitQueueTooLong()) - // processSplit(); - //if (t->base() && process_base) - // queueForSplit(t->base(), FALSE) - pushSplit(t); -} - -void LLRoam::queueForMerge(LLRoamTriNode* t, BOOL process_base) -{ - //if (mergeQueueTooLong()) - // processMerge(); - if (t->leaf()) - return; - queueForMerge(t->Lchild()); - queueForMerge(t->Rchild()); - if (t->base() && process_base) - queueForMerge(t->base(), FALSE); - pushMerge(t); -} - - -void LLRoam::processSplit() -{ - while(!mSplitQ.isEmpty()) - { - LLRoamTriNode* tri = popSplit(); - if (tri->split()) - { - tri->Lchild()->update(); - tri->Rchild()->update(); - } - //checkTiming(); - } -} - -void LLRoam::processMerge() -{ - while(!mMergeQ.isEmpty()) - { - LLRoamTriNode* tri = popMerge(); - if (tri->refine()) - continue; - if (tri->leaf()) - continue; - if (!tri->Lchild()->leaf() || !tri->Rchild()->leaf()) - continue; - if (LLRoamTriNode* b = tri->base()) - { - if (b->leaf() || (b->Lchild()->leaf() && b->Rchild()->leaf())) - { - tri->mergeSimple(); - } - } - //checkTiming(); - } -} - -void LLRoam::process() -{ - while(!mSplitQ.isEmpty() || !mMergeQ.isEmpty()) - { - processMerge(); - processSplit(); - } -} - - -void LLRoam::flushSplit() -{ - while(!mSplitQ.isEmpty()) - { - LLRoamTriNode* tri = popSplit(); - tri->flushFromQueue(); - } -} - -void LLRoam::flushMerge() -{ - while(!mMergeQ.isEmpty()) - { - LLRoamTriNode* tri = popMerge(); - if (tri->leaf()) - continue; - if (tri->base()->leaf()) - { - tri->mergeSimple(); - } - tri->flushFromQueue(); - } -} diff --git a/linden/indra/newview/llroam.h b/linden/indra/newview/llroam.h deleted file mode 100644 index 32eedb8..0000000 --- a/linden/indra/newview/llroam.h +++ /dev/null @@ -1,308 +0,0 @@ -/** - * @file llroam.h - * @brief LLRoam and related class definitions - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -/****************************************/ -/* Implementation of ROAM algorithm */ -/****************************************/ - -#ifndef LL_ROAM_H -#define LL_ROAM_H - -#include "stdtypes.h" -#include "doublelinkedlist.h" - -class LLRoamPatch; -class LLRoam; - -class LLRoamTriNode -{ -protected: - U8 mLevel; - S8 mType; // -1 - left child, 1 - righ child, 0 - top vertex - LLRoamTriNode* mParent; - LLRoamTriNode* mLchild; - LLRoamTriNode* mRchild; - LLRoamTriNode* mLeft; - LLRoamTriNode* mRight; - LLRoamTriNode* mBase; - LLRoamPatch* mPatch; - BOOL mLeaf; - BOOL mInQueue; - -public: - static LLRoam* sQueues; - - //LLRoamTriNode(S8 level = 0, const LLRoamTriNode* left = 0 - // const LLRoamTriNode* right = 0, const LLRoamTriNode* base = 0): - // mLevel(level), mLeft(left), mRight(right), mBase(base), mLchild(0), mRchild(0) {} - LLRoamTriNode(U8 level = 0, S8 type = 0, LLRoamTriNode* par = 0): - mLevel(level), mType(type), mParent(par), mLchild(0), mRchild(0), - mLeft(0), mRight(0), mBase(0), mPatch(0), - mLeaf(TRUE), mInQueue(FALSE) {} - - virtual LLRoamTriNode* newLChild() - { - return new LLRoamTriNode(mLevel+1, -1, this); - } - virtual LLRoamTriNode* newRChild() - { - return new LLRoamTriNode(mLevel+1, 1, this); - } - - virtual ~LLRoamTriNode(); - LLRoamTriNode* Lchild() const { return mLchild; } - LLRoamTriNode* Rchild() const { return mRchild; } - LLRoamTriNode* left() const { return mLeft; } - LLRoamTriNode* right() const { return mRight; } - LLRoamTriNode* base() const { return mBase; } - LLRoamTriNode* parent() const { return mParent; } - void setLeft(LLRoamTriNode* left) { mLeft = left; } - void setRight(LLRoamTriNode* right) { mRight = right; } - void setBase(LLRoamTriNode* base) { mBase = base; } - void setParent(LLRoamTriNode* parent) { mParent = parent; } - U8 level() const { return mLevel; } - BOOL leaf() const { return mLeaf; } - - void updateLink(LLRoamTriNode* old_link, LLRoamTriNode* new_link); - BOOL split(BOOL forceful = FALSE); - BOOL merge(); - void mergeSimple(); - //void refine(); - void update(); - virtual void updatePassive() {} - - virtual BOOL refine();// { return patch()->refine(this); } - virtual void initForcefulRefine() {} - virtual void flushFromQueue() {} - LLRoamPatch* patch() const { return mPatch; } - void setPatch(LLRoamPatch* p) { mPatch = p; } - - const LLRoamTriNode* getFirstLeaf() const; - const LLRoamTriNode* getNextLeaf() const; - - BOOL inQueue() const { return mInQueue; } - void enqueue() { mInQueue = TRUE; } - void dequeue() { mInQueue = FALSE; } - - BOOL checkConsistensy() const - { - BOOL ok = TRUE; - if (leaf()) - { - if (base() && !base()->leaf()) - ok = FALSE; - if (Lchild() && !Lchild()->leaf()) - ok = FALSE; - if (Rchild() && !Rchild()->leaf()) - ok = FALSE; - } else { - if (base() && base()->leaf()) - ok = FALSE; - } - return ok; - } - -}; - - -class LLRoamPatch -{ -protected: - BOOL mBackSlash; - LLRoamTriNode* mTri[2]; - U8 mMaxLevel; - U32 mNumTris; -public: - LLRoamPatch(U8 max_level, BOOL back_slash) : mBackSlash(back_slash), mMaxLevel(max_level), mNumTris(0) - { - mTri[0] = 0; - mTri[1] = 0; - } - - virtual ~LLRoamPatch() { deleteTris(); } - void deleteTris() - { - delete mTri[0]; - mTri[0] = 0; - delete mTri[1]; - mTri[1] = 0; - } - - void updatePassive() - { - mTri[0]->updatePassive(); - mTri[1]->updatePassive(); - } - - void update() - { - mTri[0]->update(); - mTri[1]->update(); - - //checkCount(); - } - - U32 checkCount() - { - BOOL ok = TRUE; - U32 ntri = 0; - for (U8 h = 0; h < 2; h++) - { - for (const LLRoamTriNode* tri = mTri[h]->getFirstLeaf(); - tri != NULL; - tri = tri->getNextLeaf()) - ntri++; - } - if (ntri != mNumTris) - ok = FALSE; - return mNumTris; - } - - LLRoamTriNode* left() const { return mTri[0]; } - LLRoamTriNode* right() const { return mTri[1]; } - LLRoamTriNode* half(U8 h) const { return mTri[h]; } - - U8 maxLevel() const { return mMaxLevel; } - BOOL refine(const LLRoamTriNode* tri) const { return tri->level() < mMaxLevel; } - U32 numTris() const { return mNumTris; } - U32 numTrisInc() { mNumTris++; return mNumTris; } - U32 numTrisDec() { mNumTris--; return mNumTris; } - void setTris(LLRoamTriNode* left, LLRoamTriNode* right) - { - mTri[0] = left; - mTri[1] = right; - setTris(); - } - - void setTris() - { - mTri[0]->setBase(mTri[1]); - mTri[1]->setBase(mTri[0]); - mTri[0]->setPatch(this); - mTri[1]->setPatch(this); - mNumTris = 2; - } - void checkConsistensy() const - { - for (U8 h = 0; h < 2; h++) - { - left()->checkConsistensy(); - right()->checkConsistensy(); - /* - for (const LLWaterTri* tri = (LLWaterTri*)mTri[h]->getFirstLeaf(); - tri != NULL; - tri = (LLWaterTri*)tri->getNextLeaf()) - { - if (!tri->upToDate()) - return FALSE; - } */ - } - } -}; - -inline BOOL LLRoamTriNode::refine() { return patch()->refine(this); } - -class LLRoam -{ -protected: - LLDoubleLinkedList mSplitQ; - LLDoubleLinkedList mMergeQ; - U32 mNum; -public: - LLRoam() {} - ~LLRoam() { mSplitQ.removeAllNodes(); mMergeQ.removeAllNodes(); } - - void pushSplit(LLRoamTriNode* t) - { - if (!t->inQueue()) - { - mSplitQ.addDataAtEnd(t); - t->enqueue(); - } - } - LLRoamTriNode* popSplit() - { - LLRoamTriNode* t = mSplitQ.getFirstData(); - t->dequeue(); - mSplitQ.removeCurrentData(); - return t; - } - void pushMerge(LLRoamTriNode* t) - { - if (!t->inQueue()) - { - mMergeQ.addDataAtEnd(t); - t->enqueue(); - } - } - LLRoamTriNode* popMerge() - { - LLRoamTriNode* t = mMergeQ.getFirstData(); - t->dequeue(); - mMergeQ.removeCurrentData(); - return t; - } - - void queueForSplit(LLRoamTriNode* t, BOOL process_base = TRUE); - void queueForMerge(LLRoamTriNode* t, BOOL process_base = TRUE); - - void processSplit(); - void processMerge(); - void process(); - - U32 numOfProcessedTris() const { return mNum; } - void numOfProcessedTrisInc() { mNum++; } - void resetCount() { mNum = 0; } -// BOOL processTooLong() const { return mNum > 10000; } - void flushSplit(); - void flushMerge(); - /* - void cutProcessing() - { - flushMerge(); - flushSplit(); - resetCount(); - } */ - void checkTiming() - { - if (mNum > 1000) - { - flushMerge(); - flushSplit(); - resetCount(); - } - } - - BOOL mergeQueueTooLong() const { return mMergeQ.getLength() > 1000; } - BOOL splitQueueTooLong() const { return mSplitQ.getLength() > 1000; } -}; - -#endif diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index bb0ccde..45a4ff5 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp @@ -39,9 +39,9 @@ #include "lldbstrings.h" #include "lleconomy.h" #include "llgl.h" +#include "llglimmediate.h" #include "llpermissions.h" #include "llpermissionsflags.h" -#include "llptrskiplist.h" #include "llundo.h" #include "lluuid.h" #include "llvolume.h" @@ -126,8 +126,8 @@ LLColor4 LLSelectMgr::sContextSilhouetteColor; static LLObjectSelection *get_null_object_selection(); template<> - const LLHandle::NullFunc - LLHandle::sNullFunc = get_null_object_selection; + const LLSafeHandle::NullFunc + LLSafeHandle::sNullFunc = get_null_object_selection; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // struct LLDeRezInfo @@ -612,6 +612,10 @@ void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_s msg->addU32Fast(_PREHASH_ObjectLocalID, (objects[i])->getLocalID()); select_count++; + // Zap the angular velocity, as the sim will set it to zero + objects[i]->setAngularVelocity( 0,0,0 ); + objects[i]->setVelocity( 0,0,0 ); + if(msg->isSendFull(NULL) || select_count >= MAX_OBJECTS_PER_PACKET) { msg->sendReliable(regionp->getHost() ); @@ -635,6 +639,10 @@ void LLSelectMgr::deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim) if (!object) return; if (!object->isSelected() ) return; + // Zap the angular velocity, as the sim will set it to zero + object->setAngularVelocity( 0,0,0 ); + object->setVelocity( 0,0,0 ); + if (send_to_sim) { LLViewerRegion* region = object->getRegion(); @@ -1722,6 +1730,37 @@ void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& getSelection()->applyToObjects(&sendfunc); } +void LLSelectMgr::selectionSetGlow(F32 glow) +{ + struct f1 : public LLSelectedTEFunctor + { + F32 mGlow; + f1(F32 glow) : mGlow(glow) {}; + bool apply(LLViewerObject* object, S32 face) + { + if (object->permModify()) + { + // update viewer side color in anticipation of update from simulator + object->setTEGlow(face, mGlow); + } + return true; + } + } func1(glow); + mSelectedObjects->applyToTEs( &func1 ); + + struct f2 : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->sendTEUpdate(); + } + return true; + } + } func2; + mSelectedObjects->applyToObjects( &func2 ); +} //----------------------------------------------------------------------------- @@ -1744,6 +1783,26 @@ LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object) //----------------------------------------------------------------------------- +// selectionGetGlow() +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectionGetGlow(F32 *glow) +{ + BOOL identical; + F32 lglow = 0.f; + struct f1 : public LLSelectedTEGetFunctor + { + F32 get(LLViewerObject* object, S32 face) + { + return object->getTE(face)->getGlow(); + } + } func; + identical = mSelectedObjects->getSelectedTEValue( &func, lglow ); + + *glow = lglow; + return identical; +} + +//----------------------------------------------------------------------------- // selectionSetMaterial() //----------------------------------------------------------------------------- void LLSelectMgr::selectionSetMaterial(U8 material) @@ -2264,12 +2323,7 @@ BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, LLString& name) if (identical) { - char firstname[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - char lastname[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - gCacheName->getName(first_id, firstname, lastname); - name.assign( firstname ); - name.append( " " ); - name.append( lastname ); + gCacheName->getFullName(first_id, name); } else { @@ -2332,12 +2386,7 @@ BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, LLString& name) } else if(!public_owner) { - char firstname[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - char lastname[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - gCacheName->getName(first_id, firstname, lastname); - name.assign( firstname ); - name.append( " " ); - name.append( lastname ); + gCacheName->getFullName(first_id, name); } else { @@ -2397,12 +2446,7 @@ BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, LLString& name) BOOL public_owner = (first_id.isNull()); if(!public_owner) { - char firstname[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - char lastname[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - gCacheName->getName(first_id, firstname, lastname); - name.assign( firstname ); - name.append( " " ); - name.append( lastname ); + gCacheName->getFullName(first_id, name); } else { @@ -3276,6 +3320,15 @@ void LLSelectMgr::deselectAll() return; } + // Zap the angular velocity, as the sim will set it to zero + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); iter++ ) + { + LLViewerObject *objectp = (*iter)->getObject(); + objectp->setAngularVelocity( 0,0,0 ); + objectp->setVelocity( 0,0,0 ); + } + sendListToRegions( "ObjectDeselect", packAgentAndSessionID, @@ -3429,7 +3482,7 @@ void LLSelectMgr::sendAttach(U8 attachment_point) BOOL build_mode = gToolMgr->inEdit(); // Special case: Attach to default location for this object. if (0 == attachment_point || - gAgent.getAvatarObject()->mAttachmentPoints.getIfThere(attachment_point)) + get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, (S32)attachment_point, (LLViewerJointAttachment*)NULL)) { sendListToRegions( "ObjectAttach", @@ -4342,12 +4395,8 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use LLFloaterReporter *reporterp = LLFloaterReporter::getReporter(report_type); if (reporterp) { - char first_name[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - char last_name[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - gCacheName->getName(owner_id, first_name, last_name); - LLString fullname(first_name); - fullname.append(" "); - fullname.append(last_name); + std::string fullname; + gCacheName->getFullName(owner_id, fullname); reporterp->setPickedObjectProperties(name, fullname, owner_id); } } @@ -5163,7 +5212,8 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible()) { - glBlendFunc(GL_SRC_COLOR, GL_ONE); + gGL.flush(); + gGL.blendFunc(GL_SRC_COLOR, GL_ONE); LLGLEnable fog(GL_FOG); glFogi(GL_FOG_MODE, GL_LINEAR); float d = (gCamera->getPointOfInterest()-gCamera->getOrigin()).magVec(); @@ -5174,7 +5224,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL); glAlphaFunc(GL_GREATER, 0.01f); - glBegin(GL_LINES); + gGL.begin(GL_LINES); { S32 i = 0; for (S32 seg_num = 0; seg_num < (S32)mSilhouetteSegments.size(); seg_num++) @@ -5183,18 +5233,19 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) { u_coord += u_divisor * LLSelectMgr::sHighlightUScale; - glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); - glTexCoord2f( u_coord, v_coord ); - glVertex3fv( mSilhouetteVertices[i].mV ); + gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); + gGL.texCoord2f( u_coord, v_coord ); + gGL.vertex3fv( mSilhouetteVertices[i].mV ); } } } - glEnd(); + gGL.end(); u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f); } - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBegin(GL_TRIANGLES); + gGL.flush(); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.begin(GL_TRIANGLES); { S32 i = 0; for (S32 seg_num = 0; seg_num < (S32)mSilhouetteSegments.size(); seg_num++) @@ -5210,15 +5261,15 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) LLVector3 vert = (mSilhouetteNormals[i]) * silhouette_thickness; vert += mSilhouetteVertices[i]; - glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha); - glTexCoord2f( u_coord, v_coord + LLSelectMgr::sHighlightVScale ); - glVertex3fv( vert.mV ); + gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha); + gGL.texCoord2f( u_coord, v_coord + LLSelectMgr::sHighlightVScale ); + gGL.vertex3fv( vert.mV ); u_coord += u_divisor * LLSelectMgr::sHighlightUScale; - glColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2); - glTexCoord2f( u_coord, v_coord ); - glVertex3fv( mSilhouetteVertices[i].mV ); + gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2); + gGL.texCoord2f( u_coord, v_coord ); + gGL.vertex3fv( mSilhouetteVertices[i].mV ); v = mSilhouetteVertices[i]; t = LLVector2(u_coord, v_coord); @@ -5227,24 +5278,24 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) LLVector3 vert = (mSilhouetteNormals[i]) * silhouette_thickness; vert += mSilhouetteVertices[i]; - glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha); - glTexCoord2f( u_coord, v_coord + LLSelectMgr::sHighlightVScale ); - glVertex3fv( vert.mV ); - glVertex3fv( vert.mV ); + gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha); + gGL.texCoord2f( u_coord, v_coord + LLSelectMgr::sHighlightVScale ); + gGL.vertex3fv( vert.mV ); + gGL.vertex3fv( vert.mV ); - glTexCoord2fv(t.mV); + gGL.texCoord2fv(t.mV); u_coord += u_divisor * LLSelectMgr::sHighlightUScale; - glColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2); - glVertex3fv(v.mV); - glTexCoord2f( u_coord, v_coord ); - glVertex3fv( mSilhouetteVertices[i].mV ); + gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2); + gGL.vertex3fv(v.mV); + gGL.texCoord2f( u_coord, v_coord ); + gGL.vertex3fv( mSilhouetteVertices[i].mV ); } } } } - glEnd(); - + gGL.end(); + gGL.flush(); } glPopMatrix(); } @@ -5470,9 +5521,9 @@ LLBBox LLSelectMgr::getBBoxOfSelection() const //----------------------------------------------------------------------------- // canUndo() //----------------------------------------------------------------------------- -BOOL LLSelectMgr::canUndo() +BOOL LLSelectMgr::canUndo() const { - return mSelectedObjects->getFirstEditableObject() != NULL; + return const_cast(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG } //----------------------------------------------------------------------------- @@ -5488,9 +5539,9 @@ void LLSelectMgr::undo() //----------------------------------------------------------------------------- // canRedo() //----------------------------------------------------------------------------- -BOOL LLSelectMgr::canRedo() +BOOL LLSelectMgr::canRedo() const { - return mSelectedObjects->getFirstEditableObject() != NULL; + return const_cast(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG } //----------------------------------------------------------------------------- @@ -5506,10 +5557,10 @@ void LLSelectMgr::redo() //----------------------------------------------------------------------------- // canDoDelete() //----------------------------------------------------------------------------- -BOOL LLSelectMgr::canDoDelete() +BOOL LLSelectMgr::canDoDelete() const { // Note: Can only delete root objects (see getFirstDeleteableObject() for more info) - return mSelectedObjects->getFirstDeleteableObject() != NULL; + return const_cast(this)->mSelectedObjects->getFirstDeleteableObject() != NULL; // HACK: casting away constness - MG } //----------------------------------------------------------------------------- @@ -5523,7 +5574,7 @@ void LLSelectMgr::doDelete() //----------------------------------------------------------------------------- // canDeselect() //----------------------------------------------------------------------------- -BOOL LLSelectMgr::canDeselect() +BOOL LLSelectMgr::canDeselect() const { return !mSelectedObjects->isEmpty(); } @@ -5538,9 +5589,9 @@ void LLSelectMgr::deselect() //----------------------------------------------------------------------------- // canDuplicate() //----------------------------------------------------------------------------- -BOOL LLSelectMgr::canDuplicate() +BOOL LLSelectMgr::canDuplicate() const { - return mSelectedObjects->getFirstCopyableObject() != NULL; + return const_cast(this)->mSelectedObjects->getFirstCopyableObject() != NULL; // HACK: casting away constness - MG } //----------------------------------------------------------------------------- // duplicate() @@ -5738,7 +5789,7 @@ LLSelectNode* LLObjectSelection::findNode(LLViewerObject* objectp) //----------------------------------------------------------------------------- // isEmpty() //----------------------------------------------------------------------------- -BOOL LLObjectSelection::isEmpty() +BOOL LLObjectSelection::isEmpty() const { return (mList.size() == 0); } @@ -6129,3 +6180,4 @@ LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_parent) return getFirstSelectedObject(&func, get_parent); } + diff --git a/linden/indra/newview/llselectmgr.h b/linden/indra/newview/llselectmgr.h index 9cb107c..0f1ea4c 100644 --- a/linden/indra/newview/llselectmgr.h +++ b/linden/indra/newview/llselectmgr.h @@ -272,7 +272,7 @@ public: void updateEffects(); void cleanupNodes(); - BOOL isEmpty(); + BOOL isEmpty() const; S32 getOwnershipCost(S32 &cost); @@ -331,7 +331,7 @@ private: ESelectType mSelectType; }; -typedef LLHandle LLObjectSelectionHandle; +typedef LLSafeHandle LLObjectSelectionHandle; class LLSelectMgr : public LLEditMenuHandler { @@ -360,20 +360,20 @@ public: static void cleanupGlobals(); // LLEditMenuHandler interface - virtual BOOL canUndo(); + virtual BOOL canUndo() const; virtual void undo(); - virtual BOOL canRedo(); + virtual BOOL canRedo() const; virtual void redo(); - virtual BOOL canDoDelete(); + virtual BOOL canDoDelete() const; virtual void doDelete(); virtual void deselect(); - virtual BOOL canDeselect(); + virtual BOOL canDeselect() const; virtual void duplicate(); - virtual BOOL canDuplicate(); + virtual BOOL canDuplicate() const; void clearSelections(); void update(); @@ -486,6 +486,7 @@ public: BOOL selectionAllPCode(LLPCode code); // all objects have this PCode BOOL selectionGetClickAction(U8 *out_action); bool selectionGetIncludeInSearch(bool* include_in_search_out); // true if all selected objects have same + BOOL selectionGetGlow(F32 *glow); void selectionSetMaterial(U8 material); void selectionSetImage(const LLUUID& imageid); // could be item or asset id @@ -501,6 +502,7 @@ public: void selectionSetMediaTypeAndURL( U8 media_type, const std::string& media_url ); void selectionSetClickAction(U8 action); void selectionSetIncludeInSearch(bool include_in_search); + void selectionSetGlow(const F32 glow); void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE); void selectionSetObjectName(const LLString& name); diff --git a/linden/indra/newview/llsky.cpp b/linden/indra/newview/llsky.cpp index 3f4189f..8265d9d 100644 --- a/linden/indra/newview/llsky.cpp +++ b/linden/indra/newview/llsky.cpp @@ -55,11 +55,10 @@ #include "lldrawpool.h" #include "llvosky.h" -#include "llvostars.h" #include "llcubemap.h" #include "llviewercontrol.h" -extern LLPipeline gPipeline; +#include "llvowlsky.h" F32 azimuth_from_vector(const LLVector3 &v); F32 elevation_from_vector(const LLVector3 &v); @@ -92,7 +91,7 @@ LLSky::~LLSky() void LLSky::cleanup() { mVOSkyp = NULL; - mVOStarsp = NULL; + mVOWLSkyp = NULL; mVOGroundp = NULL; } @@ -102,6 +101,10 @@ void LLSky::destroyGL() { mVOSkyp->cleanupGL(); } + if (mVOWLSkyp.notNull()) + { + mVOWLSkyp->cleanupGL(); + } } void LLSky::restoreGL() @@ -110,6 +113,27 @@ void LLSky::restoreGL() { mVOSkyp->restoreGL(); } + if (mVOWLSkyp) + { + mVOWLSkyp->restoreGL(); + } +} + +void LLSky::resetVertexBuffers() +{ + if (gSky.mVOSkyp.notNull()) + { + gPipeline.resetVertexBuffers(gSky.mVOSkyp->mDrawable); + gPipeline.resetVertexBuffers(gSky.mVOGroundp->mDrawable); + gPipeline.markRebuild(gSky.mVOSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); + gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); + } + if (gSky.mVOWLSkyp.notNull()) + { + gSky.mVOWLSkyp->resetVertexBuffers(); + gPipeline.resetVertexBuffers(gSky.mVOWLSkyp->mDrawable); + gPipeline.markRebuild(gSky.mVOWLSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); + } } void LLSky::setOverrideSun(BOOL override) @@ -127,7 +151,9 @@ void LLSky::setOverrideSun(BOOL override) void LLSky::setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity) { - mVOSkyp->setSunDirection(sun_direction, sun_ang_velocity); + if(mVOSkyp.notNull()) { + mVOSkyp->setSunDirection(sun_direction, sun_ang_velocity); + } } @@ -175,6 +201,18 @@ LLColor4 LLSky::getSunDiffuseColor() const } } +LLColor4 LLSky::getSunAmbientColor() const +{ + if (mVOSkyp) + { + return LLColor4(mVOSkyp->getSunAmbientColor()); + } + else + { + return LLColor4(0.f, 0.f, 0.f, 1.f); + } +} + LLColor4 LLSky::getMoonDiffuseColor() const { @@ -188,42 +226,41 @@ LLColor4 LLSky::getMoonDiffuseColor() const } } - -LLColor4 LLSky::getTotalAmbientColor() const +LLColor4 LLSky::getMoonAmbientColor() const { if (mVOSkyp) { - return mVOSkyp->getTotalAmbientColor(); + return LLColor4(mVOSkyp->getMoonAmbientColor()); } else { - return LLColor4(1.f, 1.f, 1.f, 1.f); + return LLColor4(0.f, 0.f, 0.f, 0.f); } } -BOOL LLSky::sunUp() const +LLColor4 LLSky::getTotalAmbientColor() const { if (mVOSkyp) { - return mVOSkyp->isSunUp(); + return mVOSkyp->getTotalAmbientColor(); } else { - return TRUE; + return LLColor4(1.f, 1.f, 1.f, 1.f); } } -LLColor4 LLSky::calcInScatter(LLColor4& transp, const LLVector3 &point, F32 exag) const +BOOL LLSky::sunUp() const { if (mVOSkyp) { - return mVOSkyp->calcInScatter(transp, point, exag); + return mVOSkyp->isSunUp(); } else { - return LLColor4(1.f, 1.f, 1.f, 1.f); + return TRUE; } } @@ -245,22 +282,23 @@ LLColor4U LLSky::getFadeColor() const // Public Methods ////////////////////////////////////////////////////////////////////// - void LLSky::init(const LLVector3 &sun_direction) { + mVOWLSkyp = static_cast(gObjectList.createObjectViewer(LLViewerObject::LL_VO_WL_SKY, gAgent.getRegion())); + mVOWLSkyp->initSunDirection(sun_direction, LLVector3::zero); + gPipeline.addObject(mVOWLSkyp.get()); + mVOSkyp = (LLVOSky *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SKY, gAgent.getRegion()); mVOSkyp->initSunDirection(sun_direction, LLVector3()); gPipeline.addObject((LLViewerObject *)mVOSkyp); - mVOStarsp = (LLVOStars *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_STARS, gAgent.getRegion()); - gPipeline.addObject((LLViewerObject *)mVOStarsp); - + mVOGroundp = (LLVOGround*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_GROUND, gAgent.getRegion()); LLVOGround *groundp = mVOGroundp; gPipeline.addObject((LLViewerObject *)groundp); - gSky.setFogRatio(gSavedSettings.getF32("RenderFogRatio")); - + gSky.setFogRatio(gSavedSettings.getF32("RenderFogRatio")); + //////////////////////////// // // Legacy code, ignore @@ -279,7 +317,8 @@ void LLSky::init(const LLVector3 &sun_direction) { setSunDirection(sun_direction, LLVector3(0.f, 0.f, 0.f)); } - + + mUpdatedThisFrame = TRUE; } @@ -349,7 +388,6 @@ LLColor4 LLSky::getFogColor() const return LLColor4(1.f, 1.f, 1.f, 1.f); } - void LLSky::updateFog(const F32 distance) { if (mVOSkyp) @@ -369,19 +407,12 @@ void LLSky::updateCull() llinfos << "No sky drawable!" << llendl; }*/ - if (mVOStarsp.notNull() && mVOStarsp->mDrawable.notNull()) - { - gPipeline.markVisible(mVOStarsp->mDrawable, *gCamera); - } - else - { - llinfos << "No stars drawable!" << llendl; - } - /*if (mVOGroundp.notNull() && mVOGroundp->mDrawable.notNull()) { gPipeline.markVisible(mVOGroundp->mDrawable); }*/ + + // *TODO: do culling for wl sky properly -Brad } void LLSky::updateSky() @@ -394,13 +425,6 @@ void LLSky::updateSky() { mVOSkyp->updateSky(); } - if (mVOStarsp) - { - //if (mVOStarsp->mDrawable) - //{ - // gPipeline.markRebuild(mVOStarsp->mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); - //} - } } diff --git a/linden/indra/newview/llsky.h b/linden/indra/newview/llsky.h index dab9c09..5a2794b 100644 --- a/linden/indra/newview/llsky.h +++ b/linden/indra/newview/llsky.h @@ -39,7 +39,6 @@ #include "v4color.h" #include "v4coloru.h" #include "llvosky.h" -#include "llvostars.h" #include "llvoground.h" const F32 NIGHTTIME_ELEVATION = -8.0f; // degrees @@ -47,6 +46,9 @@ const F32 NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD); class LLViewerCamera; +class LLVOWLSky; +class LLVOWLClouds; + class LLSky { @@ -64,10 +66,8 @@ public: void setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity); void setSunTargetDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity); - LLColor4 getFogColor() const; - void setCloudDensityAtAgent(F32 cloud_density); void setWind(const LLVector3& wind); @@ -88,21 +88,24 @@ public: LLVector3 getMoonDirection() const; LLColor4 getSunDiffuseColor() const; LLColor4 getMoonDiffuseColor() const; + LLColor4 getSunAmbientColor() const; + LLColor4 getMoonAmbientColor() const; LLColor4 getTotalAmbientColor() const; BOOL sunUp() const; - LLColor4 calcInScatter(LLColor4& transp, const LLVector3 &point, F32 exag) const; F32 getSunPhase() const; void setSunPhase(const F32 phase); void destroyGL(); void restoreGL(); + void resetVertexBuffers(); public: LLPointer mVOSkyp; // Pointer to the LLVOSky object (only one, ever!) - LLPointer mVOStarsp; // Pointer to the LLVOStars object (only one, ever!) LLPointer mVOGroundp; + LLPointer mVOWLSkyp; + LLVector3 mSunTargDir; // Legacy stuff diff --git a/linden/indra/newview/llspatialpartition.cpp b/linden/indra/newview/llspatialpartition.cpp index 656b236..774bf6b 100644 --- a/linden/indra/newview/llspatialpartition.cpp +++ b/linden/indra/newview/llspatialpartition.cpp @@ -43,25 +43,47 @@ #include "llviewerregion.h" #include "llcamera.h" #include "pipeline.h" - -static GLuint sBoxList = 0; +#include "llglimmediate.h" +#include "lloctree.h" const F32 SG_OCCLUSION_FUDGE = 1.01f; -//const S32 SG_LOD_PERIOD = 16; - -#define SG_DISCARD_TOLERANCE 0.25f +#define SG_DISCARD_TOLERANCE 0.01f #if LL_OCTREE_PARANOIA_CHECK #define assert_octree_valid(x) x->validate() +#define assert_states_valid(x) ((LLSpatialGroup*) x->mSpatialPartition->mOctree->getListener(0))->checkStates() #else #define assert_octree_valid(x) +#define assert_states_valid(x) #endif + static U32 sZombieGroups = 0; +U32 LLSpatialGroup::sNodeCount = 0; static F32 sLastMaxTexPriority = 1.f; static F32 sCurMaxTexPriority = 1.f; +class LLOcclusionQueryPool : public LLGLNamePool +{ +protected: + virtual GLuint allocateName() + { + GLuint name; + glGenQueriesARB(1, &name); + return name; + } + + virtual void releaseName(GLuint name) + { + glDeleteQueriesARB(1, &name); + } +}; + +static LLOcclusionQueryPool sQueryPool; + +BOOL LLSpatialPartition::sFreezeState = FALSE; + //static counter for frame to switch LOD on void sg_assert(BOOL expr) @@ -90,6 +112,134 @@ void validate_drawable(LLDrawable* drawablep) #define validate_drawable(x) #endif + +S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) +{ + F32 d = 0.f; + F32 t; + F32 r = rad*rad; + + if ((min-origin).magVecSquared() < r && + (max-origin).magVecSquared() < r) + { + return 2; + } + + for (U32 i = 0; i < 3; i++) + { + if (origin.mV[i] < min.mV[i]) + { + t = min.mV[i] - origin.mV[i]; + d += t*t; + } + else if (origin.mV[i] > max.mV[i]) + { + t = origin.mV[i] - max.mV[i]; + d += t*t; + } + + if (d > r) + { + return 0; + } + } + + return 1; +} + + +typedef enum +{ + b000 = 0x00, + b001 = 0x01, + b010 = 0x02, + b011 = 0x03, + b100 = 0x04, + b101 = 0x05, + b110 = 0x06, + b111 = 0x07, +} eLoveTheBits; + +//contact Runitai Linden for a copy of the SL object used to write this table +//basically, you give the table a bitmask of the look-at vector to a node and it +//gives you a triangle fan index array +static U8 sOcclusionIndices[] = +{ + // 000 + b111, b110, b010, b011, b001, b101, b100, b110, + //001 + b110, b000, b010, b011, b111, b101, b100, b000, + //010 + b101, b100, b110, b111, b011, b001, b000, b100, + //011 + b100, b010, b110, b111, b101, b001, b000, b010, + //100 + b011, b010, b000, b001, b101, b111, b110, b010, + //101 + b010, b100, b000, b001, b011, b111, b110, b100, + //110 + b001, b000, b100, b101, b111, b011, b010, b000, + //111 + b000, b110, b100, b101, b001, b011, b010, b110, +}; + +U8* get_occlusion_indices(LLCamera* camera, const LLVector3& center) +{ + LLVector3 d = center - camera->getOrigin(); + + U8 cypher = 0; + if (d.mV[0] > 0) + { + cypher |= b100; + } + if (d.mV[1] > 0) + { + cypher |= b010; + } + if (d.mV[2] > 0) + { + cypher |= b001; + } + + return sOcclusionIndices+cypher*8; +} + +void LLSpatialGroup::buildOcclusion() +{ + if (!mOcclusionVerts) + { + mOcclusionVerts = new F32[8*3]; + } + + LLVector3 r = mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.1f,0.1f,0.1f); + + for (U32 k = 0; k < 3; k++) + { + r.mV[k] = llmin(mBounds[1].mV[k]+0.25f, r.mV[k]); + } + + F32* v = mOcclusionVerts; + F32* c = mBounds[0].mV; + F32* s = r.mV; + + //vertex positions are encoded so the 3 bits of their vertex index + //correspond to their axis facing, with bit position 3,2,1 matching + //axis facing x,y,z, bit set meaning positive facing, bit clear + //meaning negative facing + v[0] = c[0]-s[0]; v[1] = c[1]-s[1]; v[2] = c[2]-s[2]; // 0 - 0000 + v[3] = c[0]-s[0]; v[4] = c[1]-s[1]; v[5] = c[2]+s[2]; // 1 - 0001 + v[6] = c[0]-s[0]; v[7] = c[1]+s[1]; v[8] = c[2]-s[2]; // 2 - 0010 + v[9] = c[0]-s[0]; v[10] = c[1]+s[1]; v[11] = c[2]+s[2]; // 3 - 0011 + + v[12] = c[0]+s[0]; v[13] = c[1]-s[1]; v[14] = c[2]-s[2]; // 4 - 0100 + v[15] = c[0]+s[0]; v[16] = c[1]-s[1]; v[17] = c[2]+s[2]; // 5 - 0101 + v[18] = c[0]+s[0]; v[19] = c[1]+s[1]; v[20] = c[2]-s[2]; // 6 - 0110 + v[21] = c[0]+s[0]; v[22] = c[1]+s[1]; v[23] = c[2]+s[2]; // 7 - 0111 + + clearState(LLSpatialGroup::OCCLUSION_DIRTY); +} + + BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group); BOOL LLLineSegmentAABB(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size) @@ -150,6 +300,15 @@ LLSpatialGroup::~LLSpatialGroup() sZombieGroups--; } + sNodeCount--; + + if (gGLManager.mHasOcclusionQuery && mOcclusionQuery) + { + sQueryPool.release(mOcclusionQuery); + } + + delete [] mOcclusionVerts; + LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); clearDrawMap(); } @@ -159,55 +318,16 @@ void LLSpatialGroup::clearDrawMap() mDrawMap.clear(); } -class LLRelightPainter : public LLSpatialGroup::OctreeTraveler +BOOL LLSpatialGroup::isVisible() const { -public: - LLVector3 mOrigin, mDir; - F32 mRadius; - - LLRelightPainter(LLVector3 origin, LLVector3 dir, F32 radius) - : mOrigin(origin), mDir(dir), mRadius(radius) - { } - - virtual void traverse(const LLSpatialGroup::TreeNode* n) - { - LLSpatialGroup::OctreeNode* node = (LLSpatialGroup::OctreeNode*) n; - - LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - group->setState(LLSpatialGroup::RESHADOW); - - for (U32 i = 0; i < node->getChildCount(); i++) - { - const LLSpatialGroup::OctreeNode* child = node->getChild(i); - LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0); - - LLVector3 res; - - LLVector3 center, size; - - center = group->mBounds[0]; - size = group->mBounds[1]; - - if (child->isInside(LLVector3d(mOrigin)) || LLRayAABB(center, size, mOrigin, mDir, res, mRadius)) - { - traverse(child); - } - } - } - - virtual void visit(const LLSpatialGroup::OctreeState* branch) { } - -}; + return mVisible == LLDrawable::getCurrentFrame() ? TRUE : FALSE; +} -BOOL LLSpatialGroup::isVisible() +void LLSpatialGroup::setVisible() { - if (LLPipeline::sUseOcclusion) - { - return !isState(CULLED | OCCLUDED); - } - else + if (!LLSpatialPartition::sFreezeState) { - return !isState(CULLED); + mVisible = LLDrawable::getCurrentFrame(); } } @@ -232,7 +352,7 @@ void LLSpatialGroup::validate() sg_assert(drawable->getSpatialBridge() == mSpatialPartition->asBridge()); } - if (drawable->isSpatialBridge()) + /*if (drawable->isSpatialBridge()) { LLSpatialPartition* part = drawable->asPartition(); if (!part) @@ -241,7 +361,7 @@ void LLSpatialGroup::validate() } LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); group->validate(); - } + }*/ } for (U32 i = 0; i < mOctreeNode->getChildCount(); ++i) @@ -267,6 +387,71 @@ void LLSpatialGroup::validate() #endif } + + +class LLOctreeStateCheck : public LLOctreeTraveler +{ +public: + U32 mInheritedMask; + + LLOctreeStateCheck(): mInheritedMask(0) { } + + virtual void traverse(const LLSpatialGroup::OctreeNode* node) + { + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + + node->accept(this); + + U32 temp = mInheritedMask; + mInheritedMask |= group->getState() & + (LLSpatialGroup::OCCLUDED); + + for (U32 i = 0; i < node->getChildCount(); i++) + { + traverse(node->getChild(i)); + } + + mInheritedMask = temp; + } + + virtual void visit(const LLOctreeNode* state) + { + LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); + + if (mInheritedMask && !group->isState(mInheritedMask)) + { + llerrs << "Spatial group failed inherited mask test." << llendl; + } + + if (group->isState(LLSpatialGroup::DIRTY)) + { + assert_parent_state(group, LLSpatialGroup::DIRTY); + } + } + + void assert_parent_state(LLSpatialGroup* group, U32 state) + { + LLSpatialGroup* parent = group->getParent(); + while (parent) + { + if (!parent->isState(state)) + { + llerrs << "Spatial group failed parent state check." << llendl; + } + parent = parent->getParent(); + } + } +}; + + +void LLSpatialGroup::checkStates() +{ +#if LL_OCTREE_PARANOIA_CHECK + LLOctreeStateCheck checker; + checker.traverse(mOctreeNode); +#endif +} + void validate_draw_info(LLDrawInfo& params) { #if LL_OCTREE_PARANOIA_CHECK @@ -316,8 +501,8 @@ void LLSpatialGroup::validateDrawMap() #if LL_OCTREE_PARANOIA_CHECK for (draw_map_t::iterator i = mDrawMap.begin(); i != mDrawMap.end(); ++i) { - std::vector& draw_vec = i->second; - for (std::vector::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) + LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; + for (drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) { LLDrawInfo& params = **j; @@ -327,32 +512,6 @@ void LLSpatialGroup::validateDrawMap() #endif } -void LLSpatialGroup::makeStatic() -{ -#if !LL_DARWIN - if (isState(GEOM_DIRTY | ALPHA_DIRTY)) - { - return; - } - - if (mSpatialPartition->mRenderByGroup && mBufferUsage != GL_STATIC_DRAW_ARB) - { - mBufferUsage = GL_STATIC_DRAW_ARB; - if (mVertexBuffer.notNull()) - { - mVertexBuffer->makeStatic(); - } - - for (buffer_map_t::iterator i = mBufferMap.begin(); i != mBufferMap.end(); ++i) - { - i->second->makeStatic(); - } - - mBuilt = 1.f; - } -#endif -} - BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -369,7 +528,7 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) { unbound(); setState(OBJECT_DIRTY); - setState(GEOM_DIRTY); + //setState(GEOM_DIRTY); validate_drawable(drawablep); return TRUE; } @@ -389,8 +548,7 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc { drawablep->setSpatialGroup(this); validate_drawable(drawablep); - setState(OBJECT_DIRTY | GEOM_DIRTY); - mLastAddTime = gFrameTimeSeconds; + setState(OBJECT_DIRTY | GEOM_DIRTY | DISCARD_QUERY); if (drawablep->isSpatialBridge()) { mBridgeList.push_back((LLSpatialBridge*) drawablep); @@ -431,32 +589,27 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) group->clearDrawMap(); //get geometry count - group->mIndexCount = 0; - group->mVertexCount = 0; - - addGeometryCount(group, group->mVertexCount, group->mIndexCount); + U32 index_count = 0; + U32 vertex_count = 0; + + addGeometryCount(group, vertex_count, index_count); - if (group->mVertexCount > 0 && group->mIndexCount > 0) + if (vertex_count > 0 && index_count > 0) { //create vertex buffer containing volume geometry for this node group->mBuilt = 1.f; if (group->mVertexBuffer.isNull() || (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs)) { - //LLFastTimer ftm(LLFastTimer::FTM_REBUILD_NONE_VB); group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage); - group->mVertexBuffer->allocateBuffer(group->mVertexCount, group->mIndexCount, true); + group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true); stop_glerror(); } else { - //LLFastTimer ftm(LLFastTimer::FTM_REBUILD_NONE_VB); - group->mVertexBuffer->resizeBuffer(group->mVertexCount, group->mIndexCount); + group->mVertexBuffer->resizeBuffer(vertex_count, index_count); stop_glerror(); } - { - LLFastTimer ftm((LLFastTimer::EFastTimerType) ((U32) LLFastTimer::FTM_REBUILD_VOLUME_VB + mPartitionType)); - getGeometry(group); - } + getGeometry(group); } else { @@ -465,12 +618,12 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) } group->mLastUpdateTime = gFrameTimeSeconds; - group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MATRIX_DIRTY); + group->clearState(LLSpatialGroup::GEOM_DIRTY); } BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxOut) { - const OctreeState* node = mOctreeNode->getOctState(); + const OctreeNode* node = mOctreeNode; if (node->getData().empty()) { //don't do anything if there are no objects @@ -489,7 +642,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO clearState(OBJECT_DIRTY); //initialize bounding box to first element - OctreeState::const_element_iter i = node->getData().begin(); + OctreeNode::const_element_iter i = node->getData().begin(); LLDrawable* drawablep = *i; const LLVector3* minMax = drawablep->getSpatialExtents(); @@ -612,6 +765,11 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) } } } + + if (getElementCount() == 0) + { //delete draw map on last element removal since a rebuild might never happen + clearDrawMap(); + } } return TRUE; } @@ -629,7 +787,21 @@ void LLSpatialGroup::shift(const LLVector3 &offset) mObjectExtents[0] += offset; mObjectExtents[1] += offset; - setState(GEOM_DIRTY | MATRIX_DIRTY | OCCLUSION_DIRTY); + if (!mSpatialPartition->mRenderByGroup) + { + setState(GEOM_DIRTY); + } + + if (mOcclusionVerts) + { + for (U32 i = 0; i < 8; i++) + { + F32* v = mOcclusionVerts+i*3; + v[0] += offset.mV[0]; + v[1] += offset.mV[1]; + v[2] += offset.mV[2]; + } + } } class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler @@ -637,7 +809,7 @@ class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler public: U32 mState; LLSpatialSetState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeState* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } + virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } }; class LLSpatialSetStateDiff : public LLSpatialSetState @@ -656,9 +828,22 @@ public: } }; +void LLSpatialGroup::setState(U32 state) +{ + if (!LLSpatialPartition::sFreezeState) + { + mState |= state; + } +} + void LLSpatialGroup::setState(U32 state, S32 mode) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); + if (LLSpatialPartition::sFreezeState) + { + return; + } + if (mode > STATE_MODE_SINGLE) { if (mode == STATE_MODE_DIFF) @@ -683,7 +868,7 @@ class LLSpatialClearState : public LLSpatialGroup::OctreeTraveler public: U32 mState; LLSpatialClearState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeState* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } + virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } }; class LLSpatialClearStateDiff : public LLSpatialClearState @@ -695,17 +880,29 @@ public: { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - if (!group->isState(mState)) + if (group->isState(mState)) { LLSpatialGroup::OctreeTraveler::traverse(n); } } }; +void LLSpatialGroup::clearState(U32 state) +{ + if (!LLSpatialPartition::sFreezeState) + { + mState &= ~state; + } +} void LLSpatialGroup::clearState(U32 state, S32 mode) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); + if (LLSpatialPartition::sFreezeState) + { + return; + } + if (mode > STATE_MODE_SINGLE) { if (mode == STATE_MODE_DIFF) @@ -723,20 +920,6 @@ void LLSpatialGroup::clearState(U32 state, S32 mode) { mState &= ~state; } - -#if LL_OCTREE_PARANOIA_CHECK - if (state & LLSpatialGroup::ACTIVE_OCCLUSION) - { - LLSpatialPartition* part = mSpatialPartition; - for (U32 i = 0; i < part->mOccludedList.size(); i++) - { - if (part->mOccludedList[i] == this) - { - llerrs << "LLSpatialGroup state error: " << mState << llendl; - } - } - } -#endif } //====================================== @@ -750,15 +933,15 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mSpatialPartition(part), mVertexBuffer(NULL), mBufferUsage(GL_STATIC_DRAW_ARB), + mVisible(0), mDistance(0.f), mDepth(0.f), mLastUpdateDistance(-1.f), mLastUpdateTime(gFrameTimeSeconds), - mLastAddTime(gFrameTimeSeconds), - mLastRenderTime(gFrameTimeSeconds), mViewAngle(0.f), mLastUpdateViewAngle(-1.f) { + sNodeCount++; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); sg_assert(mOctreeNode->getListenerCount() == 0); @@ -771,6 +954,9 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; mLODHash = part->mLODSeed; + mOcclusionQuery = 0; + mOcclusionVerts = NULL; + mRadius = 1; mPixelArea = 1024.f; } @@ -783,7 +969,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) llerrs << "Spatial group dirty on distance update." << llendl; } #endif - if (!getData().empty()) + if (!getData().empty() && !LLSpatialPartition::sFreezeState) { mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].magVec() : (F32) mOctreeNode->getSize().magVec(); @@ -805,19 +991,22 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) if (!group->isState(LLSpatialGroup::ALPHA_DIRTY)) { - LLVector3 view_angle = LLVector3(eye * LLVector3(1,0,0), - eye * LLVector3(0,1,0), - eye * LLVector3(0,0,1)); - - if ((view_angle-group->mLastUpdateViewAngle).magVec() > 0.64f) + if (!group->mSpatialPartition->isBridge()) { - group->mViewAngle = view_angle; - group->mLastUpdateViewAngle = view_angle; - //for occasional alpha sorting within the group - //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order, - //not setting this node to dirty would be a very good thing - group->setState(LLSpatialGroup::ALPHA_DIRTY); - } + LLVector3 view_angle = LLVector3(eye * LLVector3(1,0,0), + eye * LLVector3(0,1,0), + eye * LLVector3(0,0,1)); + + if ((view_angle-group->mLastUpdateViewAngle).magVec() > 0.64f) + { + group->mViewAngle = view_angle; + group->mLastUpdateViewAngle = view_angle; + //for occasional alpha sorting within the group + //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order, + //not setting this node to dirty would be a very good thing + group->setState(LLSpatialGroup::ALPHA_DIRTY); + } + } } //calculate depth of node for alpha sorting @@ -831,17 +1020,6 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) } group->mDepth = v * at; - - F32 water_height = gAgent.getRegion()->getWaterHeight(); - //figure out if this node is above or below water - if (group->mObjectBounds[0].mV[2] < water_height) - { - group->setState(LLSpatialGroup::BELOW_WATER); - } - else - { - group->clearState(LLSpatialGroup::BELOW_WATER); - } } else { @@ -863,6 +1041,11 @@ F32 LLSpatialPartition::calcPixelArea(LLSpatialGroup* group, LLCamera& camera) return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera); } +BOOL LLSpatialGroup::needsUpdate() +{ + return (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; +} + BOOL LLSpatialGroup::changeLOD() { if (isState(ALPHA_DIRTY)) @@ -885,7 +1068,7 @@ BOOL LLSpatialGroup::changeLOD() } } - if (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) + if (needsUpdate()) { return TRUE; } @@ -923,7 +1106,6 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) } clearDrawMap(); - mOcclusionVerts = NULL; mVertexBuffer = NULL; mBufferMap.clear(); sZombieGroups++; @@ -954,6 +1136,8 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c } unbound(); + + assert_states_valid(this); } void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) @@ -963,17 +1147,23 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo void LLSpatialGroup::destroyGL() { - setState(LLSpatialGroup::GEOM_DIRTY | - LLSpatialGroup::OCCLUSION_DIRTY | - LLSpatialGroup::IMAGE_DIRTY); + setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); mLastUpdateTime = gFrameTimeSeconds; mVertexBuffer = NULL; mBufferMap.clear(); - mOcclusionVerts = NULL; mReflectionMap = NULL; clearDrawMap(); + if (mOcclusionQuery) + { + sQueryPool.release(mOcclusionQuery); + mOcclusionQuery = 0; + } + + delete [] mOcclusionVerts; + mOcclusionVerts = NULL; + for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) { LLDrawable* drawable = *i; @@ -993,15 +1183,6 @@ BOOL LLSpatialGroup::rebound() return TRUE; } - LLVector3 oldBounds[2]; - - if (mSpatialPartition->isVolatile() && isState(QUERY_OUT)) - { //a query has been issued, if our bounding box changes significantly - //we need to discard the issued query - oldBounds[0] = mBounds[0]; - oldBounds[1] = mBounds[1]; - } - if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0) { LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); @@ -1015,7 +1196,7 @@ BOOL LLSpatialGroup::rebound() group->setState(SKIP_FRUSTUM_CHECK); } - else if (mOctreeNode->hasLeafState()) + else if (mOctreeNode->isLeaf()) { //copy object bounding box if this is a leaf boundObjects(TRUE, mExtents[0], mExtents[1]); mBounds[0] = mObjectBounds[0]; @@ -1060,19 +1241,6 @@ BOOL LLSpatialGroup::rebound() mBounds[1] = (newMax - newMin)*0.5f; } - if (mSpatialPartition->isVolatile() && isState(QUERY_OUT)) - { - for (U32 i = 0; i < 3 && !isState(DISCARD_QUERY); i++) - { - if (fabsf(mBounds[0].mV[i]-oldBounds[0].mV[i]) > SG_DISCARD_TOLERANCE || - fabsf(mBounds[1].mV[i]-oldBounds[1].mV[i]) > SG_DISCARD_TOLERANCE) - { //bounding box changed significantly, discard last issued - //occlusion query - setState(DISCARD_QUERY); - } - } - } - setState(OCCLUSION_DIRTY); clearState(DIRTY); @@ -1080,38 +1248,117 @@ BOOL LLSpatialGroup::rebound() return TRUE; } -//============================================== - -LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL is_volatile, U32 buffer_usage) +void LLSpatialGroup::checkOcclusion() { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - mDrawableType = 0; - mPartitionType = LLPipeline::PARTITION_NONE; - mVolatile = is_volatile; - mLODSeed = 0; - mLODPeriod = 1; - mVertexDataMask = data_mask; - mBufferUsage = buffer_usage; - mDepthMask = FALSE; - mSlopRatio = 0.25f; - mRenderByGroup = TRUE; - mImageEnabled = FALSE; + if (LLPipeline::sUseOcclusion > 1) + { + LLSpatialGroup* parent = getParent(); + if (parent && parent->isState(LLSpatialGroup::OCCLUDED)) + { //if the parent has been marked as occluded, the child is implicitly occluded + clearState(QUERY_PENDING | DISCARD_QUERY); + } + else if (isState(QUERY_PENDING)) + { //otherwise, if a query is pending, read it back + LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK); + GLuint res = 1; + if (!isState(DISCARD_QUERY) && mOcclusionQuery) + { + glGetQueryObjectuivARB(mOcclusionQuery, GL_QUERY_RESULT_ARB, &res); + } - mOctree = new LLSpatialGroup::OctreeNode(LLVector3d(0,0,0), - LLVector3d(1,1,1), - new LLSpatialGroup::OctreeRoot(), NULL); - new LLSpatialGroup(mOctree, this); -} + if (res > 0) + { + assert_states_valid(this); + clearState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + else + { + assert_states_valid(this); + setState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + clearState(QUERY_PENDING | DISCARD_QUERY); + } + else if (mSpatialPartition->mOcclusionEnabled) + { + assert_states_valid(this); + clearState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + } +} -LLSpatialPartition::~LLSpatialPartition() +void LLSpatialGroup::doOcclusion(LLCamera* camera) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - - for (U32 i = 0; i < mOcclusionQueries.size(); i++) + if (mSpatialPartition->mOcclusionEnabled && LLPipeline::sUseOcclusion > 1) { - glDeleteQueriesARB(1, (GLuint*)(&(mOcclusionQueries[i]))); + if (earlyFail(camera, this)) + { + setState(LLSpatialGroup::DISCARD_QUERY); + assert_states_valid(this); + clearState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + else + { + { + LLFastTimer t(LLFastTimer::FTM_RENDER_OCCLUSION); + + if (!mOcclusionQuery) + { + mOcclusionQuery = sQueryPool.allocate(); + } + + if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY)) + { + buildOcclusion(); + } + + glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery); + glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, + GL_UNSIGNED_BYTE, get_occlusion_indices(camera, mBounds[0])); + glEndQueryARB(GL_SAMPLES_PASSED_ARB); + } + + setState(LLSpatialGroup::QUERY_PENDING); + clearState(LLSpatialGroup::DISCARD_QUERY); + } } +} + +//============================================== + +LLSpatialPartition::LLSpatialPartition(U32 data_mask, U32 buffer_usage) +{ + LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); + mOcclusionEnabled = TRUE; + mDrawableType = 0; + mPartitionType = LLViewerRegion::PARTITION_NONE; + mLODSeed = 0; + mLODPeriod = 1; + mVertexDataMask = data_mask; + mBufferUsage = buffer_usage; + mDepthMask = FALSE; + mSlopRatio = 0.25f; + mRenderByGroup = TRUE; + mImageEnabled = FALSE; + mInfiniteFarClip = FALSE; + + LLGLNamePool::registerPool(&sQueryPool); + + mOctree = new LLSpatialGroup::OctreeRoot(LLVector3d(0,0,0), + LLVector3d(1,1,1), + NULL); + new LLSpatialGroup(mOctree, this); +} + + +LLSpatialPartition::~LLSpatialPartition() +{ + LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); delete mOctree; mOctree = NULL; @@ -1121,22 +1368,6 @@ LLSpatialPartition::~LLSpatialPartition() LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million - - if (drawablep->getPositionGroup().magVecSquared() > MAX_MAG) - { -#if 0 //ndef LL_RELEASE_FOR_DOWNLOAD - llwarns << "LLSpatialPartition::put Object out of range!" << llendl; - llinfos << drawablep->getPositionGroup() << llendl; - - if (drawablep->getVObj()) - { - llwarns << "Dumping debugging info: " << llendl; - drawablep->getVObj()->dump(); - } -#endif - return NULL; - } drawablep->updateSpatialExtents(); validate_drawable(drawablep); @@ -1147,11 +1378,10 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) assert_octree_valid(mOctree); mOctree->insert(drawablep); assert_octree_valid(mOctree); - - LLSpatialGroup::OctreeNode* node = mOctree->getNodeAt(drawablep); - LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (was_visible && group->isState(LLSpatialGroup::QUERY_OUT)) + LLSpatialGroup* group = drawablep->getSpatialGroup(); + + if (group && was_visible && group->isState(LLSpatialGroup::QUERY_PENDING)) { group->setState(LLSpatialGroup::DISCARD_QUERY); } @@ -1178,11 +1408,11 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); - + // sanity check submitted by open source user bushing Spatula // who was seeing crashing here. (See VWR-424 reported by Bunny Mayne) - if (!drawablep) { + if (!drawablep) + { OCT_ERRS << "LLSpatialPartition::move was passed a bad drawable." << llendl; return; } @@ -1225,7 +1455,7 @@ class LLSpatialShift : public LLSpatialGroup::OctreeTraveler { public: LLSpatialShift(LLVector3 offset) : mOffset(offset) { } - virtual void visit(const LLSpatialGroup::OctreeState* branch) + virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset); } @@ -1234,39 +1464,27 @@ public: }; void LLSpatialPartition::shift(const LLVector3 &offset) -{ +{ //shift octree node bounding boxes by offset LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - llinfos << "Shifting octree: " << offset << llendl; LLSpatialShift shifter(offset); shifter.traverse(mOctree); } -BOOL LLSpatialPartition::checkOcclusion(LLSpatialGroup* group, LLCamera* camera) -{ - if (LLPipeline::sUseOcclusion && - !group->isState(LLSpatialGroup::ACTIVE_OCCLUSION | LLSpatialGroup::OCCLUDED) && - (!camera || !earlyFail(camera, group))) - { - group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); - mQueryQueue.push(group); - return TRUE; - } - - return FALSE; -} - class LLOctreeCull : public LLSpatialGroup::OctreeTraveler { public: LLOctreeCull(LLCamera* camera) : mCamera(camera), mRes(0) { } - virtual bool earlyFail(const LLSpatialGroup* group) + virtual bool earlyFail(LLSpatialGroup* group) { + group->checkOcclusion(); + if (group->mOctreeNode->getParent() && //never occlusion cull the root node - LLPipeline::sUseOcclusion && //never occlusion cull selection + LLPipeline::sUseOcclusion && //ignore occlusion if disabled group->isState(LLSpatialGroup::OCCLUDED)) { + gPipeline.markOccluder(group); return true; } @@ -1289,31 +1507,39 @@ public: } else { - mRes = mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]); + mRes = frustumCheck(group); if (mRes) { //at least partially in, run on down LLSpatialGroup::OctreeTraveler::traverse(n); } - else - { - lateFail(group); - } + mRes = 0; } } - virtual void lateFail(LLSpatialGroup* group) + virtual S32 frustumCheck(const LLSpatialGroup* group) { - if (!group->isState(LLSpatialGroup::CULLED)) - { //totally culled, so are all its children - group->setState(LLSpatialGroup::CULLED, LLSpatialGroup::STATE_MODE_DIFF); + S32 res = mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); + if (res != 0) + { + res = llmin(res, AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist)); } + return res; } - virtual bool checkObjects(const LLSpatialGroup::OctreeState* branch, const LLSpatialGroup* group) + virtual S32 frustumCheckObjects(const LLSpatialGroup* group) + { + S32 res = mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); + if (res != 0) + { + res = llmin(res, AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist)); + } + return res; + } + + virtual bool checkObjects(const LLSpatialGroup::OctreeNode* branch, const LLSpatialGroup* group) { - if (branch->getElementCount() == 0) //no elements { return false; @@ -1322,7 +1548,7 @@ public: { return true; } - else if (mRes == 1 && !mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1])) //no objects in frustum + else if (mRes == 1 && !frustumCheckObjects(group)) //no objects in frustum { return false; } @@ -1332,20 +1558,9 @@ public: virtual void preprocess(LLSpatialGroup* group) { - if (group->isState(LLSpatialGroup::CULLED)) - { //this is the first frame this node is visible - group->clearState(LLSpatialGroup::CULLED); - if (group->mOctreeNode->hasLeafState()) - { //if it's a leaf, force it onto the active occlusion list to prevent - //massive frame stutters - group->mSpatialPartition->checkOcclusion(group, mCamera); - } - } - if (LLPipeline::sDynamicReflections && group->mOctreeNode->getSize().mdV[0] == 16.0 && - group->mDistance < 64.f && - group->mLastAddTime < gFrameTimeSeconds - 2.f) + group->mDistance < 64.f) { group->mSpatialPartition->markReimage(group); } @@ -1353,10 +1568,15 @@ public: virtual void processGroup(LLSpatialGroup* group) { + if (group->needsUpdate() || + group->mVisible < LLDrawable::getCurrentFrame() - 1) + { + group->doOcclusion(mCamera); + } gPipeline.markNotCulled(group, *mCamera); } - virtual void visit(const LLSpatialGroup::OctreeState* branch) + virtual void visit(const LLSpatialGroup::OctreeNode* branch) { LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); @@ -1372,6 +1592,17 @@ public: S32 mRes; }; +class LLOctreeCullNoFarClip : public LLOctreeCull +{ +public: + LLOctreeCullNoFarClip(LLCamera* camera) + : LLOctreeCull(camera) { } + + virtual S32 frustumCheck(const LLSpatialGroup* group) + { + return mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); + } +}; class LLOctreeSelect : public LLOctreeCull { @@ -1379,15 +1610,14 @@ public: LLOctreeSelect(LLCamera* camera, std::vector* results) : LLOctreeCull(camera), mResults(results) { } - virtual bool earlyFail(const LLSpatialGroup* group) { return false; } - virtual void lateFail(LLSpatialGroup* group) { } + virtual bool earlyFail(LLSpatialGroup* group) { return false; } virtual void preprocess(LLSpatialGroup* group) { } virtual void processGroup(LLSpatialGroup* group) { - LLSpatialGroup::OctreeState* branch = group->mOctreeNode->getOctState(); + LLSpatialGroup::OctreeNode* branch = group->mOctreeNode; - for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) { LLDrawable* drawable = *i; @@ -1408,67 +1638,41 @@ public: std::vector* mResults; }; - -void genBoxList() +void drawBox(const LLVector3& c, const LLVector3& r) { - if (sBoxList != 0) - { - return; - } - - sBoxList = glGenLists(1); - glNewList(sBoxList, GL_COMPILE); - - LLVector3 c,r; - c = LLVector3(0,0,0); - r = LLVector3(1,1,1); - - glBegin(GL_TRIANGLE_STRIP); + gGL.begin(GL_TRIANGLE_STRIP); //left front - glVertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); - glVertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); //right front - glVertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV); - glVertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV); //right back - glVertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV); - glVertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV); //left back - glVertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV); - glVertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV); //left front - glVertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); - glVertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); - glEnd(); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); + gGL.end(); //bottom - glBegin(GL_TRIANGLE_STRIP); - glVertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV); - glVertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV); - glVertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); - glVertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV); - glEnd(); + gGL.begin(GL_TRIANGLE_STRIP); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,-1))).mV); + gGL.end(); //top - glBegin(GL_TRIANGLE_STRIP); - glVertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV); - glVertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); - glVertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV); - glVertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV); - glEnd(); - - glEndList(); -} - -void drawBox(const LLVector3& c, const LLVector3& r) -{ - genBoxList(); - - glPushMatrix(); - glTranslatef(c.mV[0], c.mV[1], c.mV[2]); - glScalef(r.mV[0], r.mV[1], r.mV[2]); - glCallList(sBoxList); - glPopMatrix(); + gGL.begin(GL_TRIANGLE_STRIP); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV); + gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,-1,1))).mV); + gGL.end(); } void drawBoxOutline(const LLVector3& pos, const LLVector3& size) @@ -1478,44 +1682,49 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size) LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1)); LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1)); - glBegin(GL_LINE_LOOP); //top - glVertex3fv((pos+v1).mV); - glVertex3fv((pos+v2).mV); - glVertex3fv((pos+v3).mV); - glVertex3fv((pos+v4).mV); - glEnd(); - - glBegin(GL_LINE_LOOP); //bottom - glVertex3fv((pos-v1).mV); - glVertex3fv((pos-v2).mV); - glVertex3fv((pos-v3).mV); - glVertex3fv((pos-v4).mV); - glEnd(); - - - glBegin(GL_LINES); - + gGL.begin(GL_LINES); + + //top + gGL.vertex3fv((pos+v1).mV); + gGL.vertex3fv((pos+v2).mV); + gGL.vertex3fv((pos+v2).mV); + gGL.vertex3fv((pos+v3).mV); + gGL.vertex3fv((pos+v3).mV); + gGL.vertex3fv((pos+v4).mV); + gGL.vertex3fv((pos+v4).mV); + gGL.vertex3fv((pos+v1).mV); + + //bottom + gGL.vertex3fv((pos-v1).mV); + gGL.vertex3fv((pos-v2).mV); + gGL.vertex3fv((pos-v2).mV); + gGL.vertex3fv((pos-v3).mV); + gGL.vertex3fv((pos-v3).mV); + gGL.vertex3fv((pos-v4).mV); + gGL.vertex3fv((pos-v4).mV); + gGL.vertex3fv((pos-v1).mV); + //right - glVertex3fv((pos+v1).mV); - glVertex3fv((pos-v3).mV); + gGL.vertex3fv((pos+v1).mV); + gGL.vertex3fv((pos-v3).mV); - glVertex3fv((pos+v4).mV); - glVertex3fv((pos-v2).mV); + gGL.vertex3fv((pos+v4).mV); + gGL.vertex3fv((pos-v2).mV); //left - glVertex3fv((pos+v2).mV); - glVertex3fv((pos-v4).mV); + gGL.vertex3fv((pos+v2).mV); + gGL.vertex3fv((pos-v4).mV); - glVertex3fv((pos+v3).mV); - glVertex3fv((pos-v1).mV); + gGL.vertex3fv((pos+v3).mV); + gGL.vertex3fv((pos-v1).mV); - glEnd(); + gGL.end(); } class LLOctreeDirty : public LLOctreeTraveler { public: - virtual void visit(const LLOctreeState* state) + virtual void visit(const LLOctreeNode* state) { LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); group->destroyGL(); @@ -1540,47 +1749,45 @@ public: void LLSpatialPartition::restoreGL() { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - mOcclusionQueries.clear(); - sBoxList = 0; - - //generate query ids - while (mOcclusionQueries.size() < mOccludedList.size()) - { - GLuint id; - glGenQueriesARB(1, &id); - mOcclusionQueries.push_back(id); - } - - for (U32 i = 0; i < mOccludedList.size(); i++) - { //previously issued queries are now invalid - mOccludedList[i]->setState(LLSpatialGroup::DISCARD_QUERY); - } - - genBoxList(); } void LLSpatialPartition::resetVertexBuffers() { LLOctreeDirty dirty; dirty.traverse(mOctree); - - mOcclusionIndices = NULL; } S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* results, BOOL for_select) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); +#if LL_OCTREE_PARANOIA_CHECK + ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); +#endif { + BOOL temp = sFreezeState; + sFreezeState = FALSE; LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND); LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); + sFreezeState = temp; } + +#if LL_OCTREE_PARANOIA_CHECK + ((LLSpatialGroup*)mOctree->getListener(0))->validate(); +#endif + if (for_select) { LLOctreeSelect selecter(&camera, results); selecter.traverse(mOctree); } + else if (mInfiniteFarClip || !LLPipeline::sUseFarClip) + { + LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL); + LLOctreeCullNoFarClip culler(&camera); + culler.traverse(mOctree); + } else { LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL); @@ -1591,61 +1798,13 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result return 0; } -class LLOctreeClearOccludedNotActive : public LLSpatialGroup::OctreeTraveler -{ -public: - LLOctreeClearOccludedNotActive() { } - - virtual void traverse(const LLSpatialGroup::TreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - if ((!group->isState(LLSpatialGroup::ACTIVE_OCCLUSION)) //|| group->isState(LLSpatialGroup::QUERY_PENDING) - || group->isState(LLSpatialGroup::DEACTIVATE_OCCLUSION)) - { //the children are all occluded or culled as well - group->clearState(LLSpatialGroup::OCCLUDED); - for (U32 i = 0; i < group->mOctreeNode->getChildCount(); i++) - { - traverse(group->mOctreeNode->getChild(i)); - } - } - } - - virtual void visit(const LLSpatialGroup::OctreeState* branch) { } -}; - -class LLQueueNonCulled : public LLSpatialGroup::OctreeTraveler -{ -public: - std::queue* mQueue; - LLQueueNonCulled(std::queue *queue) : mQueue(queue) { } - - virtual void traverse(const LLSpatialGroup::TreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - if (group->isState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED)) - { //the children are all occluded or culled as well - return; - } - - if (!group->isState(LLSpatialGroup::IN_QUEUE)) - { - group->setState(LLSpatialGroup::IN_QUEUE); - mQueue->push(group); - } - - LLSpatialGroup::OctreeTraveler::traverse(n); - } - - virtual void visit(const LLSpatialGroup::OctreeState* branch) { } -}; - BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) { + const F32 vel = (gCamera->getVelocityStat()->getCurrent()+0.2f); LLVector3 c = group->mBounds[0]; - LLVector3 r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.2f,0.2f,0.2f); + LLVector3 r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(vel,vel,vel); - //if (group->isState(LLSpatialGroup::CULLED)) // || - if (!camera->AABBInFrustum(c, r)) + if (r.magVecSquared() > 1024.0*1024.0) { return TRUE; } @@ -1687,633 +1846,63 @@ void LLSpatialPartition::processImagery(LLCamera* camera) U32 process_count = 1; - while (process_count > 0 && !mImageQueue.empty()) + S32 pull_count = (S32) mImageQueue.size(); + + while (process_count > 0 && pull_count > 0 && !mImageQueue.empty()) { + pull_count--; LLPointer group = mImageQueue.front(); mImageQueue.pop(); - - group->clearState(LLSpatialGroup::IN_IMAGE_QUEUE); - - if (group->isDead()) - { - continue; - } - - if (LLPipeline::sDynamicReflections) - { - process_count--; - LLVector3 origin = group->mBounds[0]; - - LLCamera cube_cam; - cube_cam.setOrigin(origin); - cube_cam.setFar(64.f); - - LLPointer cube_map = group->mReflectionMap; - group->mReflectionMap = NULL; - if (cube_map.isNull()) - { - cube_map = new LLCubeMap(); - cube_map->initGL(); - } - - if (gPipeline.mCubeBuffer.isNull()) - { - gPipeline.mCubeBuffer = new LLCubeMap(); - gPipeline.mCubeBuffer->initGL(); - } - - S32 res = gSavedSettings.getS32("RenderReflectionRes"); - gPipeline.generateReflectionMap(gPipeline.mCubeBuffer, cube_cam, 128); - gPipeline.blurReflectionMap(gPipeline.mCubeBuffer, cube_map, res); - group->mReflectionMap = cube_map; - group->setState(LLSpatialGroup::GEOM_DIRTY); - } - - group->clearState(LLSpatialGroup::IMAGE_DIRTY); - } -} - -void validate_occlusion_list(std::vector >& occluded_list) -{ -#if !LL_RELEASE_FOR_DOWNLOAD - for (U32 i = 0; i < occluded_list.size(); i++) - { - LLSpatialGroup* group = occluded_list[i]; - for (U32 j = i+1; j < occluded_list.size(); j++) - { - if (occluded_list[i] == occluded_list[j]) - { - llerrs << "Duplicate node in occlusion list." << llendl; - } - } - - LLSpatialGroup::OctreeNode* parent = group->mOctreeNode->getOctParent(); - while (parent) - { - LLSpatialGroup* parent_group = (LLSpatialGroup*) parent->getListener(0); - if (parent_group->isState(LLSpatialGroup::OCCLUDED)) - { - llerrs << "Child node of occluded node in occlusion list (redundant query)." << llendl; - } - parent = parent->getOctParent(); - } - } -#endif -} - -void LLSpatialPartition::processOcclusion(LLCamera* camera) -{ - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - LLSpatialGroup* rootGroup = (LLSpatialGroup*) mOctree->getListener(0); - { - LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND); - rootGroup->rebound(); - } - - //update potentials - if (!rootGroup->isState(LLSpatialGroup::IN_QUEUE)) - { - rootGroup->setState(LLSpatialGroup::IN_QUEUE); - mOcclusionQueue.push(rootGroup); - } - - const U32 MAX_PULLED = 32; - const U32 MAX_PUSHED = mOcclusionQueue.size(); - U32 count = 0; - U32 pcount = 0; - - while (pcount < MAX_PUSHED && count < MAX_PULLED && !mOcclusionQueue.empty()) - { - LLFastTimer t(LLFastTimer::FTM_OCCLUSION); - - LLPointer group = mOcclusionQueue.front(); - if (!group->isState(LLSpatialGroup::IN_QUEUE)) - { - OCT_ERRS << "Spatial Group State Error. Group in queue not tagged as such." << llendl; - } - - mOcclusionQueue.pop(); - group->clearState(LLSpatialGroup::IN_QUEUE); - - if (group->isDead()) - { - continue; - } - - if (group->isState(LLSpatialGroup::CULLED | LLSpatialGroup::OCCLUDED)) - { //already culled, skip it - continue; - } - - //before we process, enqueue this group's children - for (U32 i = 0; i < group->mOctreeNode->getChildCount(); i++) - { - LLSpatialGroup* child = (LLSpatialGroup*) group->mOctreeNode->getChild(i)->getListener(0); - - //if (!child->isState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED) - if (!child->isState(LLSpatialGroup::IN_QUEUE | LLSpatialGroup::ACTIVE_OCCLUSION)) - { - child->setState(LLSpatialGroup::IN_QUEUE); - mOcclusionQueue.push(child); - } - } - - if (earlyFail(camera, group)) - { - sg_assert(!group->isState(LLSpatialGroup::OCCLUDED)); - group->setState(LLSpatialGroup::IN_QUEUE); - mOcclusionQueue.push(group); - pcount++; - continue; - } - - //add to pending queue - if (!group->isState(LLSpatialGroup::ACTIVE_OCCLUSION)) - { -#if LL_OCTREE_PARANOIA_CHECK - for (U32 i = 0; i < mOccludedList.size(); ++i) - { - sg_assert(mOccludedList[i] != group); - } -#endif - group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); - mQueryQueue.push(group); - count++; - } - } - - //read back results from last frame - for (U32 i = 0; i < mOccludedList.size(); i++) - { - LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK); - - if (mOccludedList[i]->isDead() || mOccludedList[i]->isState(LLSpatialGroup::DEACTIVATE_OCCLUSION)) - { - continue; - } - GLuint res = 0; - - if (mOccludedList[i]->isState(LLSpatialGroup::EARLY_FAIL | LLSpatialGroup::DISCARD_QUERY) || - !mOccludedList[i]->isState(LLSpatialGroup::QUERY_OUT)) - { - mOccludedList[i]->clearState(LLSpatialGroup::EARLY_FAIL); - mOccludedList[i]->clearState(LLSpatialGroup::DISCARD_QUERY); - res = 1; - } - else - { - glGetQueryObjectuivARB(mOcclusionQueries[i], GL_QUERY_RESULT_ARB, &res); - stop_glerror(); - } - - if (res) //NOT OCCLUDED - { - if (mOccludedList[i]->isState(LLSpatialGroup::OCCLUDED)) - { //this node was occluded last frame - LLSpatialGroup::OctreeNode* node = mOccludedList[i]->mOctreeNode; - //add any immediate children to the queue that are not already there - for (U32 j = 0; j < node->getChildCount(); j++) - { - LLSpatialGroup* group = (LLSpatialGroup*) node->getChild(j)->getListener(0); - checkOcclusion(group, camera); - } - } - - //clear occlusion status for everything not on the active list - LLOctreeClearOccludedNotActive clear_occluded; - mOccludedList[i]->setState(LLSpatialGroup::DEACTIVATE_OCCLUSION); - mOccludedList[i]->clearState(LLSpatialGroup::OCCLUDED); - mOccludedList[i]->clearState(LLSpatialGroup::OCCLUDING); - clear_occluded.traverse(mOccludedList[i]->mOctreeNode); - } - else - { //OCCLUDED - if (mOccludedList[i]->isState(LLSpatialGroup::OCCLUDING)) - { - if (!mOccludedList[i]->isState(LLSpatialGroup::OCCLUDED)) - { - LLSpatialGroup::OctreeNode* oct_parent = (LLSpatialGroup::OctreeNode*) mOccludedList[i]->mOctreeNode->getParent(); - if (oct_parent) - { - LLSpatialGroup* parent = (LLSpatialGroup*) oct_parent->getListener(0); - - if (checkOcclusion(parent, camera)) - { //force a guess on the parent and siblings - for (U32 i = 0; i < parent->mOctreeNode->getChildCount(); i++) - { - LLSpatialGroup* child = (LLSpatialGroup*) parent->mOctreeNode->getChild(i)->getListener(0); - checkOcclusion(child, camera); - } - } - } - - //take children off the active list - mOccludedList[i]->setState(LLSpatialGroup::DEACTIVATE_OCCLUSION, LLSpatialGroup::STATE_MODE_BRANCH); - mOccludedList[i]->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION); - } - mOccludedList[i]->setState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - } - else - { - //take children off the active list - mOccludedList[i]->setState(LLSpatialGroup::DEACTIVATE_OCCLUSION, LLSpatialGroup::STATE_MODE_BRANCH); - - //keep this node on the active list - mOccludedList[i]->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION); - - //this node is a top level occluder - mOccludedList[i]->setState(LLSpatialGroup::OCCLUDING); - } - } - - mOccludedList[i]->clearState(LLSpatialGroup::QUERY_OUT); - } - - //remove non-occluded groups from occluded list - for (U32 i = 0; i < mOccludedList.size(); ) - { - if (mOccludedList[i]->isDead() || //needs to be deleted - !mOccludedList[i]->isState(LLSpatialGroup::OCCLUDING) || //is not occluding - mOccludedList[i]->isState(LLSpatialGroup::DEACTIVATE_OCCLUSION)) //parent is occluded - { - LLSpatialGroup* groupp = mOccludedList[i]; - if (!groupp->isDead()) - { - groupp->clearState(LLSpatialGroup::ACTIVE_OCCLUSION); - groupp->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION); - groupp->clearState(LLSpatialGroup::OCCLUDING); - } - mOccludedList.erase(mOccludedList.begin()+i); - } - else - { - i++; - } - } - - validate_occlusion_list(mOccludedList); - - //pump some non-culled items onto the occlusion list - //count = MAX_PULLED; - while (!mQueryQueue.empty()) - { - LLPointer group = mQueryQueue.front(); - mQueryQueue.pop(); - //group->clearState(LLSpatialGroup::QUERY_PENDING); - mOccludedList.push_back(group); - } - - //generate query ids - while (mOcclusionQueries.size() < mOccludedList.size()) - { - GLuint id; - glGenQueriesARB(1, &id); - mOcclusionQueries.push_back(id); - } -} - -class LLOcclusionIndexBuffer : public LLVertexBuffer -{ -public: - LLOcclusionIndexBuffer(U32 size) - : LLVertexBuffer(0, GL_STREAM_DRAW_ARB) - { - allocateBuffer(0, size, TRUE); - - LLStrider idx; - - getIndexStrider(idx); - - //12 triangles' indices - idx[0] = 1; idx[1] = 0; idx[2] = 2; //front - idx[3] = 3; idx[4] = 2; idx[5] = 0; - - idx[6] = 4; idx[7] = 5; idx[8] = 1; //top - idx[9] = 0; idx[10] = 1; idx[11] = 5; - - idx[12] = 5; idx[13] = 4; idx[14] = 6; //back - idx[15] = 7; idx[16] = 6; idx[17] = 4; - - idx[18] = 6; idx[19] = 7; idx[20] = 3; //bottom - idx[21] = 2; idx[22] = 3; idx[23] = 7; - - idx[24] = 0; idx[25] = 5; idx[26] = 3; //left - idx[27] = 6; idx[28] = 3; idx[29] = 5; - - idx[30] = 4; idx[31] = 1; idx[32] = 7; //right - idx[33] = 2; idx[34] = 7; idx[35] = 1; - } - - //virtual BOOL useVBOs() const { return FALSE; } - - void setBuffer(U32 data_mask) - { - if (useVBOs()) - { - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); - sIBOActive = TRUE; - unmapBuffer(); - } - else if (sIBOActive) - { - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - sIBOActive = FALSE; - } - sGLRenderIndices = mGLIndices; - } -}; - -class LLOcclusionVertexBuffer : public LLVertexBuffer -{ -public: - LLOcclusionVertexBuffer(S32 usage) - : LLVertexBuffer(MAP_VERTEX, usage) - { - allocateBuffer(8, 0, TRUE); - } - - //virtual BOOL useVBOs() const { return FALSE; } - - void setBuffer(U32 data_mask) - { - if (useVBOs()) - { - glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); - sVBOActive = TRUE; - unmapBuffer(); - } - else if (sVBOActive) - { - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - sVBOActive = FALSE; - } - - if (data_mask) - { - glVertexPointer(3,GL_FLOAT, 0, useVBOs() ? 0 : mMappedData); - } - - sGLRenderBuffer = mGLBuffer; - } -}; - -void LLSpatialPartition::buildOcclusion() -{ - if (mOccludedList.empty()) - { - return; - } - - BOOL reset_all = FALSE; - if (mOcclusionIndices.isNull()) - { - mOcclusionIndices = new LLOcclusionIndexBuffer(36); - reset_all = TRUE; - } - - //fill occlusion vertex buffers - for (U32 i = 0; i < mOccludedList.size(); i++) - { - LLSpatialGroup* group = mOccludedList[i]; - - if (group->isState(LLSpatialGroup::OCCLUSION_DIRTY) || reset_all) - { - LLFastTimer ftm(LLFastTimer::FTM_REBUILD_OCCLUSION_VB); - - if (group->mOcclusionVerts.isNull()) - { - group->mOcclusionVerts = new LLOcclusionVertexBuffer(GL_STREAM_DRAW_ARB); - } - - group->clearState(LLSpatialGroup::OCCLUSION_DIRTY); - - LLStrider vert; - - group->mOcclusionVerts->getVertexStrider(vert); - - LLVector3 r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.1f,0.1f,0.1f); - - for (U32 k = 0; k < 3; k++) - { - r.mV[k] = llmin(group->mBounds[1].mV[k]+0.25f, r.mV[k]); - } - - *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,1,1)); // 0 - left top front - *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,1,1)); // 1 - right top front - *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,-1,1)); // 2 - right bottom front - *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,-1,1)); // 3 - left bottom front - - *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,1,-1)); // 4 - left top back - *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,1,-1)); // 5 - right top back - *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,-1,-1)); // 6 - right bottom back - *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,-1,-1)); // 7 -left bottom back - } - } - -/* for (U32 i = 0; i < mOccludedList.size(); i++) - { - LLSpatialGroup* group = mOccludedList[i]; - if (!group->mOcclusionVerts.isNull() && group->mOcclusionVerts->isLocked()) - { - LLFastTimer ftm(LLFastTimer::FTM_REBUILD_OCCLUSION_VB); - group->mOcclusionVerts->setBuffer(0); - } - }*/ -} - -void LLSpatialPartition::doOcclusion(LLCamera* camera) -{ - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - - LLFastTimer t(LLFastTimer::FTM_RENDER_OCCLUSION); - -#if LL_OCTREE_PARANOIA_CHECK - LLSpatialGroup* check = (LLSpatialGroup*) mOctree->getListener(0); - check->validate(); -#endif - - stop_glerror(); - - U32 num_verts = mOccludedList.size() * 8; - - if (num_verts == 0) - { - return; - } - - //actually perform the occlusion queries - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - LLGLDisable(GL_TEXTURE_2D); - gPipeline.disableLights(); - LLGLEnable cull_face(GL_CULL_FACE); - LLGLDisable blend(GL_BLEND); - LLGLDisable alpha_test(GL_ALPHA_TEST); - LLGLDisable fog(GL_FOG); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glColor4f(1,1,1,1); - - mOcclusionIndices->setBuffer(0); - - U32* indicesp = (U32*) mOcclusionIndices->getIndicesPointer(); - - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); -#if !LL_RELEASE_FOR_DOWNLOAD - LLGLState::checkClientArrays(LLVertexBuffer::MAP_VERTEX); -#endif - for (U32 i = 0; i < mOccludedList.size(); i++) - { -#if LL_OCTREE_PARANOIA_CHECK - for (U32 j = i+1; j < mOccludedList.size(); j++) - { - sg_assert(mOccludedList[i] != mOccludedList[j]); - } -#endif - LLSpatialGroup* group = mOccludedList[i]; if (group->isDead()) { continue; } - if (earlyFail(camera, group)) - { - group->setState(LLSpatialGroup::EARLY_FAIL); - } - else - { //early rejection criteria passed, send some geometry to the query - group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); - glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQueries[i]); - glDrawRangeElements(GL_TRIANGLES, 0, 7, 36, - GL_UNSIGNED_INT, indicesp); - glEndQueryARB(GL_SAMPLES_PASSED_ARB); - - group->setState(LLSpatialGroup::QUERY_OUT); - group->clearState(LLSpatialGroup::DISCARD_QUERY); - } - } - stop_glerror(); - - gPipeline.mTrianglesDrawn += mOccludedList.size()*12; - - glFlush(); - - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); -} - -class LLOctreeGet : public LLSpatialGroup::OctreeTraveler -{ -public: - LLOctreeGet(LLVector3 pos, F32 rad, LLDrawable::drawable_set_t* results, BOOL lights) - : mPosition(pos), mRad(rad), mResults(results), mLights(lights), mRes(0) - { - - } - - virtual void traverse(const LLSpatialGroup::TreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (mRes == 2) - { //fully in, just add everything - LLSpatialGroup::OctreeTraveler::traverse(n); - } - else - { - LLVector3 center, size; - - center = group->mBounds[0]; - size = group->mBounds[1]; - - mRes = LLSphereAABB(center, size, mPosition, mRad); - if (mRes > 0) - { - LLSpatialGroup::OctreeTraveler::traverse(n); - } - mRes = 0; - } - } - - static BOOL skip(LLDrawable* drawable, BOOL get_lights) - { - if (get_lights != drawable->isLight()) - { - return TRUE; - } - if (get_lights && drawable->getVObj()->isHUDAttachment()) - { - return TRUE; // no lighting from HUD objects - } - if (get_lights && drawable->isState(LLDrawable::ACTIVE)) - { - return TRUE; // ignore active lights + if (group->isState(LLSpatialGroup::GEOM_DIRTY)) + { //put it back + mImageQueue.push(group); + continue; } - return FALSE; - } - virtual void visit(const LLSpatialGroup::OctreeState* branch) - { - for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + group->clearState(LLSpatialGroup::IN_IMAGE_QUEUE); + if (LLPipeline::sDynamicReflections) { - LLDrawable* drawable = *i; - if (!skip(drawable, mLights)) - { - if (mRes == 2) - { - mResults->insert(drawable); - } - else - { - LLVector3 v = LLVector3(drawable->getPositionGroup())-mPosition; - float dsq = v.magVecSquared(); - float maxd = mRad + drawable->getVisibilityRadius(); - if (dsq <= maxd*maxd) - { - mResults->insert(drawable); - } - } - } - } - } - - LLVector3 mPosition; - F32 mRad; - LLDrawable::drawable_set_t* mResults; - BOOL mLights; - U32 mRes; -}; - -S32 LLSpatialPartition::getDrawables(const LLVector3& pos, F32 rad, - LLDrawable::drawable_set_t &results, - BOOL get_lights) -{ - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - - LLOctreeGet getter(pos, rad, &results, get_lights); - getter.traverse(mOctree); + process_count--; + LLVector3 origin = group->mBounds[0]; + /*LLVector3 at = camera->getOrigin()-origin; + at.normVec(); + origin += at* (at * group->mBounds[1]);*/ - return results.size(); -} + LLCamera cube_cam; + cube_cam.setOrigin(origin); + cube_cam.setFar(64.f); -S32 LLSpatialPartition::getObjects(const LLVector3& pos, F32 rad, LLDrawable::drawable_set_t &results) -{ - LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); - group->rebound(); - return getDrawables(pos, rad, results, FALSE); -} + LLPointer cube_map = group->mReflectionMap; + group->mReflectionMap = NULL; + if (cube_map.isNull()) + { + cube_map = new LLCubeMap(); + cube_map->initGL(); + } -S32 LLSpatialPartition::getLights(const LLVector3& pos, F32 rad, LLDrawable::drawable_set_t &results) -{ - return getDrawables(pos, rad, results, TRUE); + gPipeline.generateReflectionMap(gPipeline.mCubeBuffer, cube_cam); + gPipeline.blurReflectionMap(gPipeline.mCubeBuffer, cube_map); + group->mReflectionMap = cube_map; + group->setState(LLSpatialGroup::GEOM_DIRTY); + } + + group->clearState(LLSpatialGroup::IMAGE_DIRTY); + } } void pushVerts(LLDrawInfo* params, U32 mask) { + LLRenderPass::applyModelMatrix(*params); params->mVertexBuffer->setBuffer(mask); - U32* indicesp = (U32*) params->mVertexBuffer->getIndicesPointer(); + U16* indicesp = (U16*) params->mVertexBuffer->getIndicesPointer(); glDrawRangeElements(params->mParticle ? GL_POINTS : GL_TRIANGLES, params->mStart, params->mEnd, params->mCount, - GL_UNSIGNED_INT, indicesp+params->mOffset); + GL_UNSIGNED_SHORT, indicesp+params->mOffset); } void pushVerts(LLSpatialGroup* group, U32 mask) @@ -2330,6 +1919,54 @@ void pushVerts(LLSpatialGroup* group, U32 mask) } } +void pushVerts(LLFace* face, U32 mask) +{ + LLVertexBuffer* buffer = face->mVertexBuffer; + + if (buffer) + { + buffer->setBuffer(mask); + U16* indicesp = (U16*) buffer->getIndicesPointer(); + U16 start = face->getGeomStart(); + U16 end = start + face->getGeomCount()-1; + U32 count = face->getIndicesCount(); + U16 offset = face->getIndicesStart(); + + glDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_SHORT, indicesp + offset); + } + +} + +void pushBufferVerts(LLVertexBuffer* buffer, U32 mask) +{ + if (buffer) + { + buffer->setBuffer(mask); + U16* indicesp = (U16*) buffer->getIndicesPointer(); + glDrawRangeElements(GL_TRIANGLES, 0, buffer->getRequestedVerts(), buffer->getRequestedIndices(), + GL_UNSIGNED_SHORT, indicesp); + } +} + +void pushBufferVerts(LLSpatialGroup* group, U32 mask) +{ + if (!group->mDrawMap.empty()) + { + LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin()); + LLRenderPass::applyModelMatrix(*params); + + pushBufferVerts(group->mVertexBuffer, mask); + + for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i) + { + for (LLSpatialGroup::buffer_list_t::iterator j = i->second.begin(); j != i->second.end(); ++j) + { + pushBufferVerts(*j, mask); + } + } + } +} + void pushVertsColorCoded(LLSpatialGroup* group, U32 mask) { LLDrawInfo* params = NULL; @@ -2353,11 +1990,12 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask) for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) { params = *j; + LLRenderPass::applyModelMatrix(*params); glColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f); params->mVertexBuffer->setBuffer(mask); - U32* indicesp = (U32*) params->mVertexBuffer->getIndicesPointer(); + U16* indicesp = (U16*) params->mVertexBuffer->getIndicesPointer(); glDrawRangeElements(params->mParticle ? GL_POINTS : GL_TRIANGLES, params->mStart, params->mEnd, params->mCount, - GL_UNSIGNED_INT, indicesp+params->mOffset); + GL_UNSIGNED_SHORT, indicesp+params->mOffset); col = (col+1)%col_count; } } @@ -2368,7 +2006,7 @@ void renderOctree(LLSpatialGroup* group) //render solid object bounding box, color //coded by buffer usage and activity LLGLDepthTest depth(GL_TRUE, GL_FALSE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); LLVector4 col; if (group->mBuilt > 0.f) { @@ -2385,34 +2023,59 @@ void renderOctree(LLSpatialGroup* group) if (group->mBufferUsage != GL_STATIC_DRAW_ARB) { - if (group->mBufferUsage == GL_DYNAMIC_DRAW_ARB) - { - glColor4f(1,0,0,group->mBuilt); - } - else - { - glColor4f(1,1,0,group->mBuilt); - } - LLGLDepthTest gl_depth(FALSE, FALSE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + gGL.color4f(1,0,0,group->mBuilt); + gGL.flush(); + glLineWidth(5.f); + drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); + gGL.flush(); + glLineWidth(1.f); + gGL.stop(); for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) { LLDrawable* drawable = *i; + if (!group->mSpatialPartition->isBridge()) + { + glPushMatrix(); + LLVector3 trans = drawable->getRegion()->getOriginAgent(); + glTranslatef(trans.mV[0], trans.mV[1], trans.mV[2]); + } + for (S32 j = 0; j < drawable->getNumFaces(); j++) { LLFace* face = drawable->getFace(j); - if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f && face->mVertexBuffer.notNull()) - { + if (face->mVertexBuffer.notNull()) + { + if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f) + { + glColor4f(0, 1, 0, group->mBuilt); + } + else if (gFrameTimeSeconds - face->mLastMoveTime < 0.5f) + { + glColor4f(1, 0, 0, group->mBuilt); + } + else + { + continue; + } + face->mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); //drawBox((face->mExtents[0] + face->mExtents[1])*0.5f, // (face->mExtents[1]-face->mExtents[0])*0.5f); - glDrawElements(GL_TRIANGLES, face->getIndicesCount(), GL_UNSIGNED_INT, - ((U32*) face->mVertexBuffer->getIndicesPointer())+face->getIndicesStart()); + glDrawElements(GL_TRIANGLES, face->getIndicesCount(), GL_UNSIGNED_SHORT, + ((U16*) face->mVertexBuffer->getIndicesPointer())+face->getIndicesStart()); } } + + if (!group->mSpatialPartition->isBridge()) + { + glPopMatrix(); + } } glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + gGL.start(); } } else @@ -2428,50 +2091,80 @@ void renderOctree(LLSpatialGroup* group) } } - glColor4fv(col.mV); + gGL.color4fv(col.mV); drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); + glDepthMask(GL_TRUE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - //draw opaque outline - glColor4f(col.mV[0], col.mV[1], col.mV[2], 1.f); - drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - if (group->mOctreeNode->hasLeafState()) + if (group->mBuilt <= 0.f) { - glColor4f(1,1,1,1); - } - else - { - glColor4f(0,1,1,1); + //draw opaque outline + gGL.color4f(col.mV[0], col.mV[1], col.mV[2], 1.f); + drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); + + if (group->mOctreeNode->isLeaf()) + { + gGL.color4f(1,1,1,1); + } + else + { + gGL.color4f(0,1,1,1); + } + + drawBoxOutline(group->mBounds[0],group->mBounds[1]); } - - drawBoxOutline(group->mBounds[0],group->mBounds[1]); // LLSpatialGroup::OctreeNode* node = group->mOctreeNode; -// glColor4f(0,1,0,1); +// gGL.color4f(0,1,0,1); // drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize())); } -void renderVisibility(LLSpatialGroup* group) +void renderVisibility(LLSpatialGroup* group, LLCamera* camera) { LLGLEnable blend(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); LLGLEnable cull(GL_CULL_FACE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isState(LLSpatialGroup::OCCLUDED)) && group->isVisible() && + !group->getData().empty(); + if (render_objects) { LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); glColor4f(0, 0.5f, 0, 0.5f); - pushVerts(group, LLVertexBuffer::MAP_VERTEX); + pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); } { LLGLDepthTest depth_over(GL_TRUE, GL_FALSE, GL_LEQUAL); - pushVertsColorCoded(group, LLVertexBuffer::MAP_VERTEX); + + if (render_objects) + { + glColor4f(0.f, 0.5f, 0.f,1.f); + pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); + } glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - pushVertsColorCoded(group, LLVertexBuffer::MAP_VERTEX); + if (render_objects) + { + glColor4f(0.f, 0.75f, 0.f,0.5f); + pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); + } + else if (camera && group->mOcclusionVerts) + { + LLVertexBuffer::unbind(); + glVertexPointer(3, GL_FLOAT, 0, group->mOcclusionVerts); + + glColor4f(1.0f, 0.f, 0.f, 0.5f); + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_occlusion_indices(camera, group->mBounds[0])); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + glColor4f(1.0f, 1.f, 1.f, 1.0f); + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_occlusion_indices(camera, group->mBounds[0])); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } } } @@ -2479,17 +2172,17 @@ void renderBoundingBox(LLDrawable* drawable) { if (drawable->isSpatialBridge()) { - glColor4f(1,0.5f,0,1); + gGL.color4f(1,0.5f,0,1); } else if (drawable->getVOVolume()) { if (drawable->isRoot()) { - glColor4f(1,1,0,1); + gGL.color4f(1,1,0,1); } else { - glColor4f(0,1,0,1); + gGL.color4f(0,1,0,1); } } else if (drawable->getVObj()) @@ -2497,27 +2190,27 @@ void renderBoundingBox(LLDrawable* drawable) switch (drawable->getVObj()->getPCode()) { case LLViewerObject::LL_VO_SURFACE_PATCH: - glColor4f(0,1,1,1); + gGL.color4f(0,1,1,1); break; case LLViewerObject::LL_VO_CLOUDS: - glColor4f(0.5f,0.5f,0.5f,1.0f); + gGL.color4f(0.5f,0.5f,0.5f,1.0f); break; case LLViewerObject::LL_VO_PART_GROUP: - glColor4f(0,0,1,1); + gGL.color4f(0,0,1,1); break; case LLViewerObject::LL_VO_WATER: - glColor4f(0,0.5f,1,1); + gGL.color4f(0,0.5f,1,1); break; case LL_PCODE_LEGACY_TREE: - glColor4f(0,0.5f,0,1); + gGL.color4f(0,0.5f,0,1); default: - glColor4f(1,0,1,1); + gGL.color4f(1,0,1,1); break; } } else { - glColor4f(1,0,0,1); + gGL.color4f(1,0,0,1); } const LLVector3* ext; @@ -2545,7 +2238,20 @@ void renderBoundingBox(LLDrawable* drawable) pos = (ext[0] + ext[1]) * 0.5f; size = (ext[1] - ext[0]) * 0.5f; - drawBoxOutline(pos,size); + LLViewerObject* vobj = drawable->getVObj(); + if (vobj && vobj->onActiveList()) + { + gGL.flush(); + glLineWidth(4.f*sinf(gFrameTimeSeconds*2.f)+1.f); + drawBoxOutline(pos,size); + gGL.flush(); + glLineWidth(1.f); + } + else + { + drawBoxOutline(pos,size); + } + } void renderTexturePriority(LLDrawable* drawable) @@ -2578,14 +2284,12 @@ void renderTexturePriority(LLDrawable* drawable) F32 t = vsize/sLastMaxTexPriority; LLVector4 col = lerp(cold, hot, t); - glColor4fv(col.mV); + gGL.color4fv(col.mV); } //else //{ - // glColor4f(1,0,1,1); + // gGL.color4f(1,0,1,1); //} - - LLVector3 center = (facep->mExtents[1]+facep->mExtents[0])*0.5f; LLVector3 size = (facep->mExtents[1]-facep->mExtents[0])*0.5f + LLVector3(0.01f, 0.01f, 0.01f); @@ -2597,10 +2301,10 @@ void renderTexturePriority(LLDrawable* drawable) F32 t = (F32) boost / (F32) (LLViewerImage::BOOST_MAX_LEVEL-1); LLVector4 col = lerp(boost_cold, boost_hot, t); LLGLEnable blend_on(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glColor4fv(col.mV); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); + gGL.color4fv(col.mV); drawBox(center, size); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }*/ } } @@ -2608,14 +2312,17 @@ void renderTexturePriority(LLDrawable* drawable) void renderPoints(LLDrawable* drawablep) { LLGLDepthTest depth(GL_FALSE, GL_FALSE); - glBegin(GL_POINTS); - glColor3f(1,1,1); - LLVector3 center(drawablep->getPositionGroup()); - for (S32 i = 0; i < drawablep->getNumFaces(); i++) + if (drawablep->getNumFaces()) { - glVertex3fv(drawablep->getFace(i)->mCenterLocal.mV); + gGL.begin(GL_POINTS); + gGL.color3f(1,1,1); + LLVector3 center(drawablep->getPositionGroup()); + for (S32 i = 0; i < drawablep->getNumFaces(); i++) + { + gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV); + } + gGL.end(); } - glEnd(); } void renderTextureAnim(LLDrawInfo* params) @@ -2626,29 +2333,67 @@ void renderTextureAnim(LLDrawInfo* params) } LLGLEnable blend(GL_BLEND); - glColor4f(1,1,0,0.5f); + gGL.color4f(1,1,0,0.5f); + pushVerts(params, LLVertexBuffer::MAP_VERTEX); +} + +void renderBatchSize(LLDrawInfo* params) +{ + glColor3ubv((GLubyte*) &(params->mDebugColor)); pushVerts(params, LLVertexBuffer::MAP_VERTEX); } +void renderLights(LLDrawable* drawablep) +{ + if (!drawablep->isLight()) + { + return; + } + + if (drawablep->getNumFaces()) + { + LLGLEnable blend(GL_BLEND); + glColor4f(0,1,1,0.5f); + + for (S32 i = 0; i < drawablep->getNumFaces(); i++) + { + pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); + } + + const LLVector3* ext = drawablep->getSpatialExtents(); + + LLVector3 pos = (ext[0] + ext[1]) * 0.5f; + LLVector3 size = (ext[1] - ext[0]) * 0.5f; + + { + LLGLDepthTest depth(GL_FALSE, GL_TRUE); + gGL.color4f(1,1,1,1); + drawBoxOutline(pos, size); + } + + gGL.color4f(1,1,0,1); + F32 rad = drawablep->getVOVolume()->getLightRadius(); + drawBoxOutline(pos, LLVector3(rad,rad,rad)); + } +} + class LLOctreeRenderNonOccluded : public LLOctreeTraveler { public: - LLOctreeRenderNonOccluded() {} + LLCamera* mCamera; + LLOctreeRenderNonOccluded(LLCamera* camera): mCamera(camera) {} virtual void traverse(const LLSpatialGroup::OctreeNode* node) { - const LLSpatialGroup::OctreeState* state = node->getOctState(); LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - - if ((!gPipeline.sUseOcclusion || !group->isState(LLSpatialGroup::OCCLUDED)) && - !group->isState(LLSpatialGroup::CULLED)) + if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])) { - state->accept(this); + node->accept(this); - for (U32 i = 0; i < state->getChildCount(); i++) + for (U32 i = 0; i < node->getChildCount(); i++) { - traverse(state->getChild(i)); + traverse(node->getChild(i)); } //draw tight fit bounding boxes for spatial group @@ -2659,19 +2404,25 @@ public: //render visibility wireframe if (group->mSpatialPartition->mRenderByGroup && - gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && - !group->isState(LLSpatialGroup::GEOM_DIRTY)) + gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) { - renderVisibility(group); + gGL.stop(); + glPushMatrix(); + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + renderVisibility(group, mCamera); + gGLLastMatrix = NULL; + glPopMatrix(); + gGL.start(); } } } - virtual void visit(const LLSpatialGroup::OctreeState* branch) + virtual void visit(const LLSpatialGroup::OctreeNode* branch) { LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - if (group->isState(LLSpatialGroup::CULLED | LLSpatialGroup::OCCLUDED)) + if (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])) { return; } @@ -2679,7 +2430,7 @@ public: LLVector3 nodeCenter = group->mBounds[0]; LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter()); - for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) { LLDrawable* drawable = *i; @@ -2697,6 +2448,11 @@ public: { renderPoints(drawable); } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LIGHTS)) + { + renderLights(drawable); + } } for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -2709,6 +2465,10 @@ public: { renderTextureAnim(draw_info); } + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BATCH_SIZE)) + { + renderBatchSize(draw_info); + } } } } @@ -2718,6 +2478,8 @@ void LLSpatialPartition::renderDebug() { if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE | LLPipeline::RENDER_DEBUG_OCCLUSION | + LLPipeline::RENDER_DEBUG_LIGHTS | + LLPipeline::RENDER_DEBUG_BATCH_SIZE | LLPipeline::RENDER_DEBUG_BBOXES | LLPipeline::RENDER_DEBUG_POINTS | LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | @@ -2737,57 +2499,23 @@ void LLSpatialPartition::renderDebug() LLGLDisable cullface(GL_CULL_FACE); LLGLEnable blend(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - LLGLDisable tex(GL_TEXTURE_2D); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + LLImageGL::unbindTexture(0); gPipeline.disableLights(); - - LLOctreeRenderNonOccluded render_debug; - render_debug.traverse(mOctree); - LLGLDisable cull_face(GL_CULL_FACE); + LLSpatialBridge* bridge = asBridge(); + LLCamera* camera = gCamera; - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && !mOccludedList.empty() && - mOcclusionIndices.notNull()) + if (bridge) { - LLGLDisable fog(GL_FOG); - LLGLDepthTest gls_depth(GL_FALSE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - mOcclusionIndices->setBuffer(0); - U32* indicesp = (U32*) mOcclusionIndices->getIndicesPointer(); - - LLGLEnable blend(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - LLGLEnable cull(GL_CULL_FACE); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - for (U32 i = 0; i < mOccludedList.size(); i++) - { //draw occluded nodes - LLSpatialGroup* node = mOccludedList[i]; - if (node->isDead() || - !node->isState(LLSpatialGroup::OCCLUDED) || - node->mOcclusionVerts.isNull()) - { - continue; - } - - node->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); - { - LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); - glColor4f(0.5, 0.5f, 0, 0.25f); - glDrawRangeElements(GL_TRIANGLES, 0, 7, 36, - GL_UNSIGNED_INT, indicesp); - } + camera = NULL; + } - { - LLGLDepthTest depth_over(GL_TRUE, GL_FALSE, GL_LEQUAL); - glColor4f(0.0,1.0f,1.0f,1.0f); - glDrawRangeElements(GL_TRIANGLES, 0, 7, 36, - GL_UNSIGNED_INT, indicesp); - } - } + LLOctreeStateCheck checker; + checker.traverse(mOctree); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } + LLOctreeRenderNonOccluded render_debug(camera); + render_debug.traverse(mOctree); } @@ -2816,8 +2544,7 @@ public: virtual LLDrawable* check(const LLSpatialGroup::OctreeNode* node) { - const LLSpatialGroup::OctreeState* state = node->getOctState(); - state->accept(this); + node->accept(this); for (U32 i = 0; i < node->getChildCount(); i++) { @@ -2841,9 +2568,9 @@ public: return mRet; } - virtual void visit(const LLSpatialGroup::OctreeState* branch) + virtual void visit(const LLSpatialGroup::OctreeNode* branch) { - for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) { check(*i); } @@ -2869,13 +2596,14 @@ LLDrawable* LLSpatialPartition::pickDrawable(const LLVector3& start, const LLVec return ret; } -LLDrawInfo::LLDrawInfo(U32 start, U32 end, U32 count, U32 offset, +LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, LLViewerImage* texture, LLVertexBuffer* buffer, BOOL fullbright, U8 bump, BOOL particle, F32 part_size) : mVertexBuffer(buffer), mTexture(texture), mTextureMatrix(NULL), + mModelMatrix(NULL), mStart(start), mEnd(end), mCount(count), @@ -2884,8 +2612,10 @@ LLDrawInfo::LLDrawInfo(U32 start, U32 end, U32 count, U32 offset, mBump(bump), mParticle(particle), mPartSize(part_size), - mVSize(0.f) + mVSize(0.f), + mGroup(NULL) { + mDebugColor = (rand() << 16) + rand(); } LLDrawInfo::~LLDrawInfo() @@ -2897,3 +2627,190 @@ LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) { return new LLVertexBuffer(type_mask, usage); } + +LLCullResult::LLCullResult() +{ + clear(); +} + +void LLCullResult::clear() +{ + mVisibleGroupsSize = 0; + mAlphaGroupsSize = 0; + mOcclusionGroupsSize = 0; + mDrawableGroupsSize = 0; + mVisibleListSize = 0; + mVisibleBridgeSize = 0; + + for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) + { + mRenderMapSize[i] = 0; + } +} + +LLCullResult::sg_list_t::iterator LLCullResult::beginVisibleGroups() +{ + return mVisibleGroups.begin(); +} + +LLCullResult::sg_list_t::iterator LLCullResult::endVisibleGroups() +{ + return mVisibleGroups.begin() + mVisibleGroupsSize; +} + +LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups() +{ + return mAlphaGroups.begin(); +} + +LLCullResult::sg_list_t::iterator LLCullResult::endAlphaGroups() +{ + return mAlphaGroups.begin() + mAlphaGroupsSize; +} + +LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups() +{ + return mOcclusionGroups.begin(); +} + +LLCullResult::sg_list_t::iterator LLCullResult::endOcclusionGroups() +{ + return mOcclusionGroups.begin() + mOcclusionGroupsSize; +} + +LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups() +{ + return mDrawableGroups.begin(); +} + +LLCullResult::sg_list_t::iterator LLCullResult::endDrawableGroups() +{ + return mDrawableGroups.begin() + mDrawableGroupsSize; +} + +LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList() +{ + return mVisibleList.begin(); +} + +LLCullResult::drawable_list_t::iterator LLCullResult::endVisibleList() +{ + return mVisibleList.begin() + mVisibleListSize; +} + +LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge() +{ + return mVisibleBridge.begin(); +} + +LLCullResult::bridge_list_t::iterator LLCullResult::endVisibleBridge() +{ + return mVisibleBridge.begin() + mVisibleBridgeSize; +} + +LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type) +{ + return mRenderMap[type].begin(); +} + +LLCullResult::drawinfo_list_t::iterator LLCullResult::endRenderMap(U32 type) +{ + return mRenderMap[type].begin() + mRenderMapSize[type]; +} + +void LLCullResult::pushVisibleGroup(LLSpatialGroup* group) +{ + if (mVisibleGroupsSize < mVisibleGroups.size()) + { + mVisibleGroups[mVisibleGroupsSize] = group; + } + else + { + mVisibleGroups.push_back(group); + } + ++mVisibleGroupsSize; +} + +void LLCullResult::pushAlphaGroup(LLSpatialGroup* group) +{ + if (mAlphaGroupsSize < mAlphaGroups.size()) + { + mAlphaGroups[mAlphaGroupsSize] = group; + } + else + { + mAlphaGroups.push_back(group); + } + ++mAlphaGroupsSize; +} + +void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group) +{ + if (mOcclusionGroupsSize < mOcclusionGroups.size()) + { + mOcclusionGroups[mOcclusionGroupsSize] = group; + } + else + { + mOcclusionGroups.push_back(group); + } + ++mOcclusionGroupsSize; +} + +void LLCullResult::pushDrawableGroup(LLSpatialGroup* group) +{ + if (mDrawableGroupsSize < mDrawableGroups.size()) + { + mDrawableGroups[mDrawableGroupsSize] = group; + } + else + { + mDrawableGroups.push_back(group); + } + ++mDrawableGroupsSize; +} + +void LLCullResult::pushDrawable(LLDrawable* drawable) +{ + if (mVisibleListSize < mVisibleList.size()) + { + mVisibleList[mVisibleListSize] = drawable; + } + else + { + mVisibleList.push_back(drawable); + } + ++mVisibleListSize; +} + +void LLCullResult::pushBridge(LLSpatialBridge* bridge) +{ + if (mVisibleBridgeSize < mVisibleBridge.size()) + { + mVisibleBridge[mVisibleBridgeSize] = bridge; + } + else + { + mVisibleBridge.push_back(bridge); + } + ++mVisibleBridgeSize; +} + +void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info) +{ + if (mRenderMapSize[type] < mRenderMap[type].size()) + { + mRenderMap[type][mRenderMapSize[type]] = draw_info; + } + else + { + mRenderMap[type].push_back(draw_info); + } + ++mRenderMapSize[type]; +} + + + + + + diff --git a/linden/indra/newview/llspatialpartition.h b/linden/indra/newview/llspatialpartition.h index 1936423..a38e3fe 100644 --- a/linden/indra/newview/llspatialpartition.h +++ b/linden/indra/newview/llspatialpartition.h @@ -40,14 +40,18 @@ #include "llvertexbuffer.h" #include "llgltypes.h" #include "llcubemap.h" +#include "lldrawpool.h" #include -#define SG_STATE_INHERIT_MASK (CULLED | OCCLUDED) -#define SG_INITIAL_STATE_MASK (OCCLUSION_DIRTY | DIRTY | GEOM_DIRTY) +#define SG_STATE_INHERIT_MASK (OCCLUDED) +#define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY) class LLSpatialPartition; class LLSpatialBridge; +class LLSpatialGroup; + +S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad); class LLDrawInfo : public LLRefCount { @@ -55,7 +59,7 @@ protected: ~LLDrawInfo(); public: - LLDrawInfo(U32 start, U32 end, U32 count, U32 offset, + LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, LLViewerImage* image, LLVertexBuffer* buffer, BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); @@ -64,9 +68,11 @@ public: LLPointer mTexture; LLPointer mReflectionMap; LLColor4U mGlowColor; + S32 mDebugColor; const LLMatrix4* mTextureMatrix; - U32 mStart; - U32 mEnd; + const LLMatrix4* mModelMatrix; + U16 mStart; + U16 mEnd; U32 mCount; U32 mOffset; BOOL mFullbright; @@ -74,7 +80,8 @@ public: BOOL mParticle; F32 mPartSize; F32 mVSize; - + LLSpatialGroup* mGroup; + struct CompareTexture { bool operator()(const LLDrawInfo& lhs, const LLDrawInfo& rhs) @@ -84,7 +91,7 @@ public: }; struct CompareTexturePtr - { + { //sort by texture bool operator()(const LLPointer& lhs, const LLPointer& rhs) { // sort by pointer, sort NULL down to the end @@ -93,6 +100,17 @@ public: } }; + struct CompareTexturePtrMatrix + { + bool operator()(const LLPointer& lhs, const LLPointer& rhs) + { + return lhs.get() != rhs.get() + && (lhs.isNull() || (rhs.notNull() && (lhs->mTexture.get() > rhs->mTexture.get() || + (lhs->mTexture.get() == rhs->mTexture.get() && lhs->mModelMatrix > rhs->mModelMatrix)))); + } + + }; + struct CompareBump { bool operator()(const LLPointer& lhs, const LLPointer& rhs) @@ -108,23 +126,24 @@ class LLSpatialGroup : public LLOctreeListener { friend class LLSpatialPartition; public: + static U32 sNodeCount; typedef std::vector > sg_vector_t; typedef std::set > sg_set_t; typedef std::vector > bridge_list_t; typedef std::vector > drawmap_elem_t; typedef std::map draw_map_t; - typedef std::map, LLPointer > buffer_map_t; + typedef std::vector > buffer_list_t; + typedef std::map, buffer_list_t> buffer_map_t; typedef LLOctreeListener BaseType; typedef LLOctreeListener OctreeListener; typedef LLTreeNode TreeNode; typedef LLOctreeNode OctreeNode; typedef LLOctreeRoot OctreeRoot; - typedef LLOctreeState OctreeState; typedef LLOctreeTraveler OctreeTraveler; - typedef LLOctreeState::element_iter element_iter; - typedef LLOctreeState::element_list element_list; + typedef LLOctreeNode::element_iter element_iter; + typedef LLOctreeNode::element_list element_list; struct CompareDistanceGreater { @@ -144,29 +163,22 @@ public: typedef enum { - IN_QUEUE = 0x00000001, - QUERY_PENDING = 0x00000002, - CULLED = 0x00000004, - OCCLUDED = 0x00000008, - DEAD = 0x00000010, - ACTIVE_OCCLUSION = 0x00000020, + OCCLUDED = 0x00000001, + IN_QUEUE = 0x00000002, + QUERY_PENDING = 0x00000004, + ACTIVE_OCCLUSION = 0x00000008, + DISCARD_QUERY = 0x00000010, + DEAD = 0x00000020, EARLY_FAIL = 0x00000040, - DEACTIVATE_OCCLUSION = 0x00000080, - RESHADOW = 0x00000100, - RESHADOW_QUEUE = 0x00000200, - DIRTY = 0x00000400, - OBJECT_DIRTY = 0x00000800, - GEOM_DIRTY = 0x00001000, - MATRIX_DIRTY = 0x00002000, - ALPHA_DIRTY = 0x00004000, - DISCARD_QUERY = 0x00008000, - QUERY_OUT = 0x00010000, - OCCLUDING = 0x00020000, - SKIP_FRUSTUM_CHECK = 0x00040000, - OCCLUSION_DIRTY = 0x00080000, - BELOW_WATER = 0x00100000, - IN_IMAGE_QUEUE = 0x00200000, - IMAGE_DIRTY = 0x00400000, + DIRTY = 0x00000080, + OBJECT_DIRTY = 0x00000100, + GEOM_DIRTY = 0x00000200, + ALPHA_DIRTY = 0x00000800, + SKIP_FRUSTUM_CHECK = 0x00001000, + IN_IMAGE_QUEUE = 0x00002000, + IMAGE_DIRTY = 0x00004000, + OCCLUSION_DIRTY = 0x00008000, + MESH_DIRTY = 0x00010000, } eSpatialState; typedef enum @@ -181,11 +193,12 @@ public: BOOL isDead() { return isState(DEAD); } BOOL isState(U32 state) const { return mState & state ? TRUE : FALSE; } U32 getState() { return mState; } - void setState(U32 state) { mState |= state; } - void clearState(U32 state) { mState &= ~state; } + void setState(U32 state); + void clearState(U32 state); void clearDrawMap(); void validate(); + void checkStates(); void validateDrawMap(); void setState(U32 state, S32 mode); @@ -196,20 +209,26 @@ public: BOOL addObject(LLDrawable *drawablep, BOOL add_all = FALSE, BOOL from_octree = FALSE); BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE); BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group - BOOL isVisible(); + BOOL isVisible() const; + void setVisible(); void shift(const LLVector3 &offset); BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax); void unbound(); BOOL rebound(); + void buildOcclusion(); //rebuild mOcclusionVerts + void checkOcclusion(); //read back last occlusion query (if any) + void doOcclusion(LLCamera* camera); //issue occlusion query void destroyGL(); void updateDistance(LLCamera& camera); + BOOL needsUpdate(); BOOL changeLOD(); void rebuildGeom(); - void makeStatic(); - + void dirtyGeom() { setState(GEOM_DIRTY); } - element_list& getData() { return mOctreeNode->getOctState()->getData(); } + void dirtyMesh() { setState(MESH_DIRTY); } + element_list& getData() { return mOctreeNode->getData(); } + U32 getElementCount() const { return mOctreeNode->getElementCount(); } //LISTENER FUNCTIONS virtual void handleInsertion(const TreeNode* node, LLDrawable* face); @@ -235,25 +254,24 @@ public: LLSpatialPartition* mSpatialPartition; LLVector3 mBounds[2]; LLVector3 mExtents[2]; + LLVector3 mObjectExtents[2]; LLVector3 mObjectBounds[2]; LLPointer mVertexBuffer; - LLPointer mOcclusionVerts; + F32* mOcclusionVerts; + GLuint mOcclusionQuery; LLPointer mReflectionMap; U32 mBufferUsage; draw_map_t mDrawMap; - U32 mVertexCount; - U32 mIndexCount; + S32 mVisible; F32 mDistance; F32 mDepth; F32 mLastUpdateDistance; F32 mLastUpdateTime; - F32 mLastAddTime; - F32 mLastRenderTime; - + LLVector3 mViewAngle; LLVector3 mLastUpdateViewAngle; @@ -275,7 +293,9 @@ public: class LLSpatialPartition: public LLGeometryManager { public: - LLSpatialPartition(U32 data_mask, BOOL is_volatile = FALSE, U32 mBufferUsage = GL_STATIC_DRAW_ARB); + static BOOL sFreezeState; //if true, no spatialgroup state updates will be made + + LLSpatialPartition(U32 data_mask, U32 mBufferUsage = GL_STATIC_DRAW_ARB); virtual ~LLSpatialPartition(); LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE); @@ -293,63 +313,42 @@ public: virtual void rebuildGeom(LLSpatialGroup* group); S32 cull(LLCamera &camera, std::vector* results = NULL, BOOL for_select = FALSE); // Cull on arbitrary frustum - BOOL checkOcclusion(LLSpatialGroup* group, LLCamera* camera); void markReimage(LLSpatialGroup* group); void processImagery(LLCamera* camera); - void processOcclusion(LLCamera* camera); - void buildOcclusion(); - void doOcclusion(LLCamera* camera); + BOOL isVisible(const LLVector3& v); - BOOL isVolatile() const { return mVolatile; } - + virtual LLSpatialBridge* asBridge() { return NULL; } virtual BOOL isBridge() { return asBridge() != NULL; } - S32 getObjects(const LLVector3& pos, F32 rad, LLDrawable::drawable_set_t &results ); - S32 getLights(const LLVector3& pos, F32 rad, LLDrawable::drawable_set_t &results ); - void renderDebug(); void restoreGL(); void resetVertexBuffers(); protected: - S32 getDrawables(const LLVector3& pos, F32 rad, LLDrawable::drawable_set_t &results, BOOL get_lights ); typedef std::set > spatial_group_set_t; spatial_group_set_t mSpatialGroups; - //things that might be occluded typedef std::queue > spatial_group_queue_t; - spatial_group_queue_t mOcclusionQueue; - + //things that need an image update spatial_group_queue_t mImageQueue; - //things awaiting query - spatial_group_queue_t mQueryQueue; - - std::vector mOcclusionQueries; - public: LLSpatialGroup::OctreeNode* mOctree; - + BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed + BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane U32 mBufferUsage; BOOL mRenderByGroup; BOOL mImageEnabled; U32 mLODSeed; - U32 mLODPeriod; + U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed) U32 mVertexDataMask; F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25); - BOOL mVolatile; //if TRUE, occlusion queries will be discarded when nodes change size BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering U32 mDrawableType; U32 mPartitionType; - - //index buffer for occlusion verts - LLPointer mOcclusionIndices; - - //things that are occluded - std::vector > mOccludedList; }; // class for creating bridges between spatial partitions @@ -370,7 +369,6 @@ public: virtual void setVisible(LLCamera& camera_in, std::vector* results = NULL, BOOL for_select = FALSE); virtual void updateDistance(LLCamera& camera_in); virtual void makeActive(); - virtual void makeStatic(); virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE); virtual BOOL updateMove(); virtual void shiftPos(const LLVector3& vec); @@ -383,6 +381,72 @@ public: LLDrawable* mDrawable; }; +class LLCullResult +{ +public: + LLCullResult(); + + typedef std::vector sg_list_t; + typedef std::vector drawable_list_t; + typedef std::vector bridge_list_t; + typedef std::vector drawinfo_list_t; + + void clear(); + + sg_list_t::iterator beginVisibleGroups(); + sg_list_t::iterator endVisibleGroups(); + + sg_list_t::iterator beginAlphaGroups(); + sg_list_t::iterator endAlphaGroups(); + + sg_list_t::iterator beginOcclusionGroups(); + sg_list_t::iterator endOcclusionGroups(); + + sg_list_t::iterator beginDrawableGroups(); + sg_list_t::iterator endDrawableGroups(); + + drawable_list_t::iterator beginVisibleList(); + drawable_list_t::iterator endVisibleList(); + + bridge_list_t::iterator beginVisibleBridge(); + bridge_list_t::iterator endVisibleBridge(); + + drawinfo_list_t::iterator beginRenderMap(U32 type); + drawinfo_list_t::iterator endRenderMap(U32 type); + + void pushVisibleGroup(LLSpatialGroup* group); + void pushAlphaGroup(LLSpatialGroup* group); + void pushOcclusionGroup(LLSpatialGroup* group); + void pushDrawableGroup(LLSpatialGroup* group); + void pushDrawable(LLDrawable* drawable); + void pushBridge(LLSpatialBridge* bridge); + void pushDrawInfo(U32 type, LLDrawInfo* draw_info); + + U32 getVisibleGroupsSize() { return mVisibleGroupsSize; } + U32 getAlphaGroupsSize() { return mAlphaGroupsSize; } + U32 getDrawableGroupsSize() { return mDrawableGroupsSize; } + U32 getVisibleListSize() { return mVisibleListSize; } + U32 getVisibleBridgeSize() { return mVisibleBridgeSize; } + U32 getRenderMapSize(U32 type) { return mRenderMapSize[type]; } + +private: + U32 mVisibleGroupsSize; + U32 mAlphaGroupsSize; + U32 mOcclusionGroupsSize; + U32 mDrawableGroupsSize; + U32 mVisibleListSize; + U32 mVisibleBridgeSize; + U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES]; + + sg_list_t mVisibleGroups; + sg_list_t mAlphaGroups; + sg_list_t mOcclusionGroups; + sg_list_t mDrawableGroups; + drawable_list_t mVisibleList; + bridge_list_t mVisibleBridge; + drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; +}; + //spatial partition for water (implemented in LLVOWater.cpp) class LLWaterPartition : public LLSpatialPartition { @@ -500,5 +564,6 @@ extern const F32 SG_BOX_RAD; extern const F32 SG_OBJ_SIDE; extern const F32 SG_MAX_OBJ_RAD; + #endif //LL_LLSPATIALPARTITION_H diff --git a/linden/indra/newview/llsprite.cpp b/linden/indra/newview/llsprite.cpp index bb78f1a..092d49f 100644 --- a/linden/indra/newview/llsprite.cpp +++ b/linden/indra/newview/llsprite.cpp @@ -199,8 +199,8 @@ void LLSprite::updateFace(LLFace &face) LLStrider verticesp; LLStrider normalsp; LLStrider tex_coordsp; - LLStrider indicesp; - S32 index_offset; + LLStrider indicesp; + U16 index_offset; // Setup face if (face.mVertexBuffer.isNull()) @@ -214,10 +214,6 @@ void LLSprite::updateFace(LLFace &face) } index_offset = face.getGeometry(verticesp,normalsp,tex_coordsp, indicesp); - if (-1 == index_offset) - { - return; - } *tex_coordsp = LLVector2(0.f, 0.f); *verticesp = mC; @@ -263,7 +259,7 @@ void LLSprite::updateFace(LLFace &face) *indicesp++ = 3 + index_offset; } - //face.mVertexBuffer->setBuffer(0); + face.mVertexBuffer->setBuffer(0); face.mCenterAgent = mPosition; } diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 2e7e609..69ac136 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -134,6 +134,7 @@ #include "llui.h" #include "llurldispatcher.h" #include "llurlsimstring.h" +#include "llurlhistory.h" #include "llurlwhitelist.h" #include "lluserauth.h" #include "llvieweraudio.h" @@ -143,10 +144,12 @@ #include "llviewergenericmessage.h" #include "llviewergesture.h" #include "llviewerimagelist.h" +#include "llviewermedia.h" #include "llviewermenu.h" #include "llviewermessage.h" #include "llviewernetwork.h" #include "llviewerobjectlist.h" +#include "llviewerparcelmedia.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "llviewerstats.h" @@ -160,7 +163,6 @@ #include "llxfermanager.h" #include "pipeline.h" #include "llappviewer.h" -#include "llmediaengine.h" #include "llfasttimerview.h" #include "llfloatermap.h" #include "llweb.h" @@ -168,28 +170,15 @@ #include "llnamelistctrl.h" #include "llnamebox.h" #include "llnameeditor.h" - -#if LL_LIBXUL_ENABLED -#include "llmozlib.h" -#endif // LL_LIBXUL_ENABLED +#include "llpostprocess.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" #if LL_WINDOWS #include "llwindebug.h" #include "lldxhardware.h" #endif -#if LL_QUICKTIME_ENABLED -#if LL_DARWIN -#include -#else -// quicktime specific includes -#include "MacTypes.h" -#include "QTML.h" -#include "Movies.h" -#include "FixMath.h" -#endif -#endif - // // exported globals // @@ -213,8 +202,6 @@ LLPointer gStartImageGL; static LLHost gAgentSimHost; static BOOL gSkipOptionalUpdate = FALSE; -bool gUseQuickTime = true; -bool gQuickTimeInitialized = false; static bool gGotUseCircuitCodeAck = false; LLString gInitialOutfit; LLString gInitialOutfitGender; // "male" or "female" @@ -545,80 +532,7 @@ BOOL idle_startup() // initialize the economy gGlobalEconomy = new LLGlobalEconomy(); - //--------------------------------------------------------------------- - // LibXUL (Mozilla) initialization - //--------------------------------------------------------------------- - #if LL_LIBXUL_ENABLED - set_startup_status(0.58f, "Initializing embedded web browser...", gAgent.mMOTD.c_str()); - display_startup(); - llinfos << "Initializing embedded web browser..." << llendl; - - #if LL_DARWIN - // For Mac OS, we store both the shared libraries and the runtime files (chrome/, plugins/, etc) in - // Second Life.app/Contents/MacOS/. This matches the way Firefox is distributed on the Mac. - std::string componentDir(gDirUtilp->getExecutableDir()); - #elif LL_WINDOWS - std::string componentDir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - componentDir += gDirUtilp->getDirDelimiter(); - #ifdef LL_DEBUG - componentDir += "mozilla_debug"; - #else - componentDir += "mozilla"; - #endif - #elif LL_LINUX - std::string componentDir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - componentDir += gDirUtilp->getDirDelimiter(); - componentDir += "mozilla-runtime-linux-i686"; - #else - std::string componentDir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - componentDir += gDirUtilp->getDirDelimiter(); - componentDir += "mozilla"; - #endif - -#if LL_LINUX - // Yuck, Mozilla init plays with the locale - push/pop - // the locale to protect it, as exotic/non-C locales - // causes our code lots of general critical weirdness - // and crashness. (SL-35450) - std::string saved_locale = setlocale(LC_ALL, NULL); -#endif // LL_LINUX - - // initialize Mozilla - pass in executable dir, location of extra dirs (chrome/, greprefs/, plugins/ etc.) and path to profile dir) - - std::string application_dir; - std::string component_dir; - std::string profile_dir; -#if LL_WINDOWS - // Fix strings passed into Mozilla; it expects local-codepage mbcs paths rather than UTF8 - llutf16string temp_16str = utf8str_to_utf16str( gDirUtilp->getExecutableDir() ); - application_dir = ll_convert_wide_to_string( (const wchar_t*) temp_16str.c_str() ); - - temp_16str = utf8str_to_utf16str( componentDir ); - component_dir = ll_convert_wide_to_string( (const wchar_t*) temp_16str.c_str() ); - - temp_16str = utf8str_to_utf16str( gDirUtilp->getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" ).c_str() ); - profile_dir = ll_convert_wide_to_string( (const wchar_t*) temp_16str.c_str() ); -#else - application_dir = gDirUtilp->getExecutableDir().c_str(); - component_dir = componentDir.c_str(); - profile_dir = gDirUtilp->getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" ).c_str(); -#endif - - LLMozLib::getInstance()->init( application_dir, componentDir, profile_dir ); - -#if LL_LINUX - setlocale(LC_ALL, saved_locale.c_str() ); -#endif // LL_LINUX - - std::ostringstream codec; - codec << "[Second Life "; - codec << "(" << gChannelName << ")"; - codec << " - " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD; - codec << "]"; - LLMozLib::getInstance()->setBrowserAgentId( codec.str() ); - LLMozLib::getInstance()->enableProxy( gSavedSettings.getBOOL("BrowserProxyEnabled"), gSavedSettings.getString("BrowserProxyAddress"), gSavedSettings.getS32("BrowserProxyPort") ); - #endif //------------------------------------------------- // Init audio, which may be needed for prefs dialog @@ -715,7 +629,29 @@ BOOL idle_startup() show_connect_box = TRUE; } + // Go to the next startup state + LLStartUp::setStartupState( STATE_MEDIA_INIT ); + return do_normal_idle; + } + + + //--------------------------------------------------------------------- + // LLMediaEngine Init + //--------------------------------------------------------------------- + if (STATE_MEDIA_INIT == LLStartUp::getStartupState()) + { + llinfos << "Initializing Multimedia...." << llendl; + set_startup_status(0.03f, "Initializing Multimedia...", gAgent.mMOTD.c_str()); + display_startup(); + LLViewerMedia::initClass(); + LLViewerParcelMedia::initClass(); + + if (gViewerWindow) + { + audio_update_volume(true); + } + LLStartUp::setStartupState( STATE_LOGIN_SHOW ); return do_normal_idle; } @@ -913,6 +849,9 @@ BOOL idle_startup() &LLURLDispatcher::dispatchFromTextEditor, &LLURLDispatcher::dispatchFromTextEditor ); + // Load URL History File + LLURLHistory::loadFile("url_history.xml"); + //------------------------------------------------- // Handle startup progress screen //------------------------------------------------- @@ -955,7 +894,7 @@ BOOL idle_startup() // Poke the VFS, which could potentially block for a while if // Windows XP is acting up - set_startup_status(0.05f, "Verifying cache files (can take 60-90 seconds)...", NULL); + set_startup_status(0.07f, "Verifying cache files (can take 60-90 seconds)...", NULL); display_startup(); gVFS->pokeFiles(); @@ -1398,8 +1337,13 @@ BOOL idle_startup() const char* look_at_str = gUserAuthp->getResponse("look_at"); if (look_at_str) { - LLMemoryStream mstr((U8*)look_at_str, strlen(look_at_str)); /* Flawfinder: ignore */ - LLSD sd = LLSDNotationParser::parse(mstr); +#if !LL_WINDOWS && !LL_DARWIN + size_t len = strnlen(look_at_str, MAX_STRING); +#else + size_t len = strlen(look_at_str); +#endif + LLMemoryStream mstr((U8*)look_at_str, len); + LLSD sd = LLSDSerialize::fromNotation(mstr, len); agent_start_look_at = ll_vector3_from_sd(sd); } @@ -1420,8 +1364,13 @@ BOOL idle_startup() const char* home_location = gUserAuthp->getResponse("home"); if(home_location) { - LLMemoryStream mstr((U8*)home_location, strlen(home_location)); /* Flawfinder: ignore */ - LLSD sd = LLSDNotationParser::parse(mstr); +#if !LL_WINDOWS && !LL_DARWIN + size_t len = strnlen(home_location, MAX_STRING); +#else + size_t len = strlen(home_location); +#endif + LLMemoryStream mstr((U8*)home_location, len); + LLSD sd = LLSDSerialize::fromNotation(mstr, len); S32 region_x = sd["region_handle"][0].asInteger(); S32 region_y = sd["region_handle"][1].asInteger(); U64 region_handle = to_region_handle(region_x, region_y); @@ -1594,6 +1543,11 @@ BOOL idle_startup() LLDrawable::initClass(); + // init the shader managers + LLPostProcess::initClass(); + LLWLParamManager::initClass(); + LLWaterParamManager::initClass(); + // RN: don't initialize VO classes in drone mode, they are too closely tied to rendering LLViewerObject::initVOClasses(); @@ -1785,7 +1739,7 @@ BOOL idle_startup() display_startup(); gImageList.decodeAllImages(1.f); } - LLStartUp::setStartupState( STATE_QUICKTIME_INIT ); + LLStartUp::setStartupState( STATE_WORLD_WAIT ); // JC - Do this as late as possible to increase likelihood Purify // will run. @@ -1819,79 +1773,8 @@ BOOL idle_startup() } //--------------------------------------------------------------------- - // LLMediaEngine Init - //--------------------------------------------------------------------- - if (STATE_QUICKTIME_INIT == LLStartUp::getStartupState()) - { - if (gViewerWindow) - { - audio_update_volume(true); - } - - #if LL_QUICKTIME_ENABLED // windows only right now but will be ported to mac - if (gUseQuickTime) - { - if(!gQuickTimeInitialized) - { - // initialize quicktime libraries (fails gracefully if quicktime not installed ($QUICKTIME) - llinfos << "Initializing QuickTime...." << llendl; - set_startup_status(0.57f, "Initializing QuickTime...", gAgent.mMOTD.c_str()); - display_startup(); - #if LL_WINDOWS - // Only necessary/available on Windows. - if ( InitializeQTML ( 0L ) != noErr ) - { - // quicktime init failed - turn off media engine support - LLMediaEngine::getInstance ()->setAvailable ( FALSE ); - llinfos << "...not found - unable to initialize." << llendl; - set_startup_status(0.57f, "QuickTime not found - unable to initialize.", gAgent.mMOTD.c_str()); - } - else - { - llinfos << "QUICKTIME> QuickTime version (hex) is " << std::hex << LLMediaEngine::getInstance()->getQuickTimeVersion() << llendl; - llinfos << "QUICKTIME> QuickTime version is " << std::dec << LLMediaEngine::getInstance()->getQuickTimeVersion() << llendl; - if ( LLMediaEngine::getInstance()->getQuickTimeVersion() < LL_MIN_QUICKTIME_VERSION ) - { - // turn off QuickTime if version is less than required - LLMediaEngine::getInstance ()->setAvailable ( FALSE ); - - // display a message here explaining why we disabled QuickTime - gViewerWindow->alertXml("QuickTimeOutOfDate"); - } - else - { - llinfos << ".. initialized successfully." << llendl; - set_startup_status(0.57f, "QuickTime initialized successfully.", gAgent.mMOTD.c_str()); - }; - }; - #elif LL_DARWIN - llinfos << "QUICKTIME> QuickTime version (hex) is " << std::hex << LLMediaEngine::getInstance()->getQuickTimeVersion() << llendl; - llinfos << "QUICKTIME> QuickTime version is " << std::dec << LLMediaEngine::getInstance()->getQuickTimeVersion() << llendl; - if ( LLMediaEngine::getInstance()->getQuickTimeVersion() < LL_MIN_QUICKTIME_VERSION ) - { - // turn off QuickTime if version is less than required - LLMediaEngine::getInstance ()->setAvailable ( FALSE ); - // display a message here explaining why we disabled QuickTime - gViewerWindow->alertXml("QuickTimeOutOfDate"); - } - #endif - - EnterMovies (); - gQuickTimeInitialized = true; - } - } - else - { - LLMediaEngine::getInstance()->setAvailable( FALSE ); - } - #endif - LLStartUp::setStartupState( STATE_WORLD_WAIT ); - return do_normal_idle; - } - - //--------------------------------------------------------------------- // Agent Send //--------------------------------------------------------------------- if(STATE_WORLD_WAIT == LLStartUp::getStartupState()) @@ -2437,8 +2320,13 @@ BOOL idle_startup() LLStartUp::setStartupState( STATE_STARTED ); - // Unmute audio if desired and setup volumes + // Unmute audio if desired and setup volumes. + // Unmute audio if desired and setup volumes. + // This is a not-uncommon crash site, so surround it with + // llinfos output to aid diagnosis. + llinfos << "Doing first audio_update_volume..." << llendl; audio_update_volume(); + llinfos << "Done first audio_update_volume." << llendl; // reset keyboard focus to sane state of pointing at world gFocusMgr.setKeyboardFocus(NULL); @@ -3132,18 +3020,6 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFunc("ParcelObjectOwnersReply", LLPanelLandObjects::processParcelObjectOwnersReply); - // Reponse to the "Refresh" button on land objects floater. - if (gSavedSettings.getBOOL("AudioStreamingVideo")) - { - msg->setHandlerFunc("ParcelMediaCommandMessage", LLMediaEngine::process_parcel_media); - msg->setHandlerFunc ( "ParcelMediaUpdate", LLMediaEngine::process_parcel_media_update ); - } - else - { - msg->setHandlerFunc("ParcelMediaCommandMessage", null_message_callback); - gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", null_message_callback ); - } - msg->setHandlerFunc("InitiateDownload", process_initiate_download); msg->setHandlerFunc("LandStatReply", LLFloaterTopObjects::handle_land_reply); msg->setHandlerFunc("GenericMessage", process_generic_message); diff --git a/linden/indra/newview/llstartup.h b/linden/indra/newview/llstartup.h index 872efba..f38f7bf 100644 --- a/linden/indra/newview/llstartup.h +++ b/linden/indra/newview/llstartup.h @@ -46,6 +46,7 @@ extern const char* SCREEN_LAST_FILENAME; enum EStartupState{ STATE_FIRST, // Initial startup + STATE_MEDIA_INIT, // Initialzie media library STATE_LOGIN_SHOW, // Show login screen STATE_LOGIN_WAIT, // Wait for user input at login screen STATE_LOGIN_CLEANUP, // Get rid of login screen and start login @@ -58,7 +59,6 @@ enum EStartupState{ STATE_WORLD_INIT, // Start building the world STATE_SEED_GRANTED_WAIT, // Wait for seed cap grant STATE_SEED_CAP_GRANTED, // Have seed cap grant - STATE_QUICKTIME_INIT, // Initialzie QT STATE_WORLD_WAIT, // Waiting for simulator STATE_AGENT_SEND, // Connect to a region STATE_AGENT_WAIT, // Wait for region @@ -72,8 +72,6 @@ enum EStartupState{ // exported symbols extern BOOL gAgentMovementCompleted; -extern bool gUseQuickTime; -extern bool gQuickTimeInitialized; extern LLPointer gStartImageGL; class LLStartUp diff --git a/linden/indra/newview/llstatbar.cpp b/linden/indra/newview/llstatbar.cpp index ceb9659..15dcd75 100644 --- a/linden/indra/newview/llstatbar.cpp +++ b/linden/indra/newview/llstatbar.cpp @@ -134,9 +134,9 @@ void LLStatBar::draw() mUpdateTimer.reset(); } - S32 width = mRect.getWidth() - 40; + S32 width = getRect().getWidth() - 40; S32 max_width = width; - S32 bar_top = mRect.getHeight() - 15; // 16 pixels from top. + S32 bar_top = getRect().getHeight() - 15; // 16 pixels from top. S32 bar_height = bar_top - 20; S32 tick_height = 4; S32 tick_width = 1; @@ -144,7 +144,7 @@ void LLStatBar::draw() F32 value_scale = max_width/(mMaxBar - mMinBar); - LLFontGL::sMonospace->renderUTF8(mLabel, 0, 0, mRect.getHeight(), LLColor4(1.f, 1.f, 1.f, 1.f), + LLFontGL::sMonospace->renderUTF8(mLabel, 0, 0, getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, 1.f), LLFontGL::LEFT, LLFontGL::TOP); char value_format[64]; /* Flawfinder: ignore */ @@ -161,7 +161,7 @@ void LLStatBar::draw() } // Draw the value. - LLFontGL::sMonospace->renderUTF8(value_str, 0, width, mRect.getHeight(), + LLFontGL::sMonospace->renderUTF8(value_str, 0, width, getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, 0.5f), LLFontGL::RIGHT, LLFontGL::TOP); diff --git a/linden/indra/newview/llstatgraph.cpp b/linden/indra/newview/llstatgraph.cpp index 910f85b..992b959 100644 --- a/linden/indra/newview/llstatgraph.cpp +++ b/linden/indra/newview/llstatgraph.cpp @@ -32,6 +32,7 @@ #include "llviewerprecompiledheaders.h" #include "llstatgraph.h" +#include "llglimmediate.h" #include "llmath.h" #include "llui.h" @@ -115,21 +116,21 @@ void LLStatGraph::draw() } } - //gl_drop_shadow(0, mRect.getHeight(), mRect.getWidth(), 0, + //gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, // gColors.getColor("ColorDropShadow"), // (S32) gSavedSettings.getF32("DropShadowFloater") ); color = gColors.getColor( "MenuDefaultBgColor" ); - glColor4fv(color.mV); - gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, TRUE); + gGL.color4fv(color.mV); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, TRUE); - glColor4fv(LLColor4::black.mV); - gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, FALSE); + gGL.color4fv(LLColor4::black.mV); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, FALSE); color = mThresholdColors[i]; - glColor4fv(color.mV); - gl_rect_2d(1, llround(frac*mRect.getHeight()), mRect.getWidth() - 1, 0, TRUE); + gGL.color4fv(color.mV); + gl_rect_2d(1, llround(frac*getRect().getHeight()), getRect().getWidth() - 1, 0, TRUE); } } diff --git a/linden/indra/newview/llstatusbar.cpp b/linden/indra/newview/llstatusbar.cpp index bdaf133..4e31151 100644 --- a/linden/indra/newview/llstatusbar.cpp +++ b/linden/indra/newview/llstatusbar.cpp @@ -49,6 +49,7 @@ #include "llfloaterbuycurrency.h" #include "llfloaterchat.h" #include "llfloaterdirectory.h" // to spawn search +#include "llfloaterlagmeter.h" #include "llfloaterland.h" #include "llfloaterregioninfo.h" #include "llfloaterscriptdebug.h" @@ -126,7 +127,7 @@ LLStatusBar::LLStatusBar(const std::string& name, const LLRect& rect) mSquareMetersCommitted(0) { // status bar can possible overlay menus? - mMouseOpaque = FALSE; + setMouseOpaque(FALSE); setIsChrome(TRUE); // size of day of the weeks and year @@ -163,8 +164,49 @@ LLStatusBar::LLStatusBar(const std::string& name, const LLRect& rect) childSetCommitCallback("search_editor", onCommitSearch, this); childSetAction("search_btn", onClickSearch, this); + childSetVisible("search_editor", gSavedSettings.getBOOL("ShowSearchBar")); + childSetVisible("search_btn", gSavedSettings.getBOOL("ShowSearchBar")); + childSetActionTextbox("ParcelNameText", onClickParcelInfo ); childSetActionTextbox("BalanceText", onClickBalance ); + + // Adding Net Stat Graph + S32 x = getRect().getWidth() - 2; + S32 y = 0; + LLRect r; + r.set( x-SIM_STAT_WIDTH, y+MENU_BAR_HEIGHT-1, x, y+1); + mSGBandwidth = new LLStatGraph("BandwidthGraph", r); + mSGBandwidth->setFollows(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); + mSGBandwidth->setStat(&gViewerStats->mKBitStat); + LLString text = childGetText("bandwidth_tooltip") + " "; + LLUIString bandwidth_tooltip = text; // get the text from XML until this widget is XML driven + mSGBandwidth->setLabel(bandwidth_tooltip.getString().c_str()); + mSGBandwidth->setUnits("Kbps"); + mSGBandwidth->setPrecision(0); + mSGBandwidth->setMouseOpaque(FALSE); + addChild(mSGBandwidth); + x -= SIM_STAT_WIDTH + 2; + + r.set( x-SIM_STAT_WIDTH, y+MENU_BAR_HEIGHT-1, x, y+1); + mSGPacketLoss = new LLStatGraph("PacketLossPercent", r); + mSGPacketLoss->setFollows(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); + mSGPacketLoss->setStat(&gViewerStats->mPacketsLostPercentStat); + text = childGetText("packet_loss_tooltip") + " "; + LLUIString packet_loss_tooltip = text; // get the text from XML until this widget is XML driven + mSGPacketLoss->setLabel(packet_loss_tooltip.getString().c_str()); + mSGPacketLoss->setUnits("%"); + mSGPacketLoss->setMin(0.f); + mSGPacketLoss->setMax(5.f); + mSGPacketLoss->setThreshold(0, 0.5f); + mSGPacketLoss->setThreshold(1, 1.f); + mSGPacketLoss->setThreshold(2, 3.f); + mSGPacketLoss->setPrecision(1); + mSGPacketLoss->setMouseOpaque(FALSE); + mSGPacketLoss->mPerSec = FALSE; + addChild(mSGPacketLoss); + + childSetActionTextbox("stat_btn", onClickStatGraph); + } LLStatusBar::~LLStatusBar() @@ -199,9 +241,9 @@ void LLStatusBar::draw() { refresh(); - if (mBgVisible) + if (isBackgroundVisible()) { - gl_drop_shadow(0, mRect.getHeight(), mRect.getWidth(), 0, + gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, LLUI::sColorsGroup->getColor("ColorDropShadow"), LLUI::sConfigGroup->getS32("DropShadowFloater") ); } @@ -212,6 +254,14 @@ void LLStatusBar::draw() // Per-frame updates of visibility void LLStatusBar::refresh() { + // Adding Net Stat Meter back in + F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f; + mSGBandwidth->setMin(0.f); + mSGBandwidth->setMax(bwtotal*1.25f); + mSGBandwidth->setThreshold(0, bwtotal*0.75f); + mSGBandwidth->setThreshold(1, bwtotal); + mSGBandwidth->setThreshold(2, bwtotal); + // *TODO: Localize / translate time // Get current UTC time, adjusted for the user's clock @@ -262,6 +312,8 @@ void LLStatusBar::refresh() S32 x = MENU_RIGHT + MENU_PARCEL_SPACING; S32 y = 0; + bool search_visible = gSavedSettings.getBOOL("ShowSearchBar"); + // reshape menu bar to its content's width if (MENU_RIGHT != gMenuBarView->getRect().getWidth()) { @@ -454,7 +506,7 @@ void LLStatusBar::refresh() mRegionDetails.mTime = mTextTime->getText(); mRegionDetails.mBalance = mBalance; - mRegionDetails.mAccesString = (char *)region->getSimAccessString(); + mRegionDetails.mAccesString = region->getSimAccessString(); mRegionDetails.mPing = region->getNetDetailsForLCD(); if (parcel && !parcel->getName().empty()) { @@ -466,7 +518,7 @@ void LLStatusBar::refresh() // keep these around for the LCD to use mRegionDetails.mRegionName = region->getName(); - mRegionDetails.mParcelName = (char *)parcel->getName().c_str(); + mRegionDetails.mParcelName = parcel->getName(); mRegionDetails.mX = pos_x; mRegionDetails.mY = pos_y; mRegionDetails.mZ = pos_z; @@ -476,7 +528,7 @@ void LLStatusBar::refresh() if (parcel->isPublic()) { - snprintf(mRegionDetails.mOwner, MAX_STRING, "Public"); + mRegionDetails.mOwner = "Public"; } else { @@ -488,16 +540,13 @@ void LLStatusBar::refresh() } else { - snprintf(mRegionDetails.mOwner, MAX_STRING, "Group Owned"); + mRegionDetails.mOwner = "Group Owned"; } } else { // Figure out the owner's name - char owner_first[MAX_STRING]; /*Flawfinder: ignore*/ - char owner_last[MAX_STRING]; /*Flawfinder: ignore*/ - gCacheName->getName(parcel->getOwnerID(), owner_first, owner_last); - snprintf(mRegionDetails.mOwner, MAX_STRING, "%s %s", owner_first, owner_last); /* Flawfinder: ignore */ + gCacheName->getFullName(parcel->getOwnerID(), mRegionDetails.mOwner); } } } @@ -516,7 +565,7 @@ void LLStatusBar::refresh() mRegionDetails.mZ = pos_z; mRegionDetails.mArea = 0; mRegionDetails.mForSale = FALSE; - snprintf(mRegionDetails.mOwner, MAX_STRING, "Unknown"); + mRegionDetails.mOwner = "Unknown"; mRegionDetails.mTraffic = 0.0f; } } @@ -525,7 +574,7 @@ void LLStatusBar::refresh() // no region location_name = "(Unknown)"; // keep these around for the LCD to use - mRegionDetails.mRegionName = LLString("Unknown"); + mRegionDetails.mRegionName = "Unknown"; mRegionDetails.mParcelName = "Unknown"; mRegionDetails.mAccesString = "Unknown"; mRegionDetails.mX = 0; @@ -533,17 +582,72 @@ void LLStatusBar::refresh() mRegionDetails.mZ = 0; mRegionDetails.mArea = 0; mRegionDetails.mForSale = FALSE; - snprintf(mRegionDetails.mOwner, MAX_STRING, "Unknown"); + mRegionDetails.mOwner = "Unknown"; mRegionDetails.mTraffic = 0.0f; } + mTextParcelName->setText(location_name); + + + // x = right edge + // loop through: stat graphs, search btn, search text editor, money, buy money, clock + // adjust rect + // finally adjust parcel name rect + + S32 new_right = getRect().getWidth(); + if (search_visible) + { + childGetRect("search_btn", r); + r.translate( new_right - r.mRight, 0); + childSetRect("search_btn", r); + new_right -= r.getWidth(); + + childGetRect("search_editor", r); + r.translate( new_right - r.mRight, 0); + childSetRect("search_editor", r); + new_right -= r.getWidth() + 6; + + } + else + { + childGetRect("stat_btn", r); + r.translate( new_right - r.mRight, 0); + childSetRect("stat_btn", r); + new_right -= r.getWidth() + 6; + } + + // Set rects of money, buy money, time + childGetRect("BalanceText", r); + r.translate( new_right - r.mRight, 0); + childSetRect("BalanceText", r); + new_right -= r.getWidth() - 18; + + childGetRect("buycurrency", r); + r.translate( new_right - r.mRight, 0); + childSetRect("buycurrency", r); + new_right -= r.getWidth() + 6; + + childGetRect("TimeText", r); + // mTextTime->getTextPixelWidth(); + r.translate( new_right - r.mRight, 0); + childSetRect("TimeText", r); + // new_right -= r.getWidth() + MENU_PARCEL_SPACING; + + // Adjust region name and parcel name x += 8; const S32 PARCEL_RIGHT = llmin(mTextTime->getRect().mLeft, mTextParcelName->getTextPixelWidth() + x + 5); - r.set(x+4, mRect.getHeight() - 2, PARCEL_RIGHT, 0); + r.set(x+4, getRect().getHeight() - 2, PARCEL_RIGHT, 0); mTextParcelName->setRect(r); + + // Set search bar visibility + childSetVisible("search_editor", search_visible); + childSetVisible("search_btn", search_visible); + mSGBandwidth->setVisible(! search_visible); + mSGPacketLoss->setVisible(! search_visible); + childSetEnabled("stat_btn", ! search_visible); } void LLStatusBar::setVisibleForMouselook(bool visible) @@ -553,6 +657,8 @@ void LLStatusBar::setVisibleForMouselook(bool visible) childSetVisible("buycurrency", visible); childSetVisible("search_editor", visible); childSetVisible("search_btn", visible); + mSGBandwidth->setVisible(visible); + mSGPacketLoss->setVisible(visible); setBackgroundVisible(visible); } @@ -664,7 +770,7 @@ static void onClickParcelInfo(void* data) { gParcelMgr->selectParcelAt(gAgent.getPositionGlobal()); - LLFloaterLand::show(); + LLFloaterLand::showInstance(); } static void onClickBalance(void* data) @@ -734,7 +840,7 @@ static void onClickBuyLand(void*) void LLStatusBar::setupDate() { // fill the day array with what's in the xui - LLString day_list = getFormattedUIString("StatBarDaysOfWeek"); + LLString day_list = getString("StatBarDaysOfWeek"); size_t length = day_list.size(); // quick input check @@ -758,7 +864,7 @@ void LLStatusBar::setupDate() } // fill the day array with what's in the xui - LLString month_list = getFormattedUIString( "StatBarMonthsOfYear" ); + LLString month_list = getString( "StatBarMonthsOfYear" ); length = month_list.size(); // quick input check @@ -808,6 +914,12 @@ void LLStatusBar::onClickSearch(void* data) LLFloaterDirectory::showFindAll(search_text); } +// static +void LLStatusBar::onClickStatGraph(void* data) +{ + LLFloaterLagMeter::show(data); +} + BOOL can_afford_transaction(S32 cost) { return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost))); diff --git a/linden/indra/newview/llstatusbar.h b/linden/indra/newview/llstatusbar.h index 72b0751..d6cf8de 100644 --- a/linden/indra/newview/llstatusbar.h +++ b/linden/indra/newview/llstatusbar.h @@ -51,30 +51,33 @@ class LLStatGraph; class LLRegionDetails { public: - LLRegionDetails() + LLRegionDetails() : + mRegionName("Unknown"), + mParcelName("Unknown"), + mAccesString("Unknown"), + mX(0), + mY(0), + mZ(0), + mArea (0), + mForSale(FALSE), + mOwner("Unknown"), + mTraffic(0), + mBalance(0), + mPing(0) { - mRegionName = LLString("Unknown"); - mParcelName = "Unknown"; - mAccesString = "Unknown"; - mX = 0; - mY = 0; - mZ = 0; - mArea = 0; - mForSale = FALSE; - snprintf(mOwner, MAX_STRING, "Unknown"); } - LLString mRegionName; - char *mParcelName; - char *mAccesString; + std::string mRegionName; + std::string mParcelName; + std::string mAccesString; S32 mX; S32 mY; S32 mZ; S32 mArea; BOOL mForSale; - char mOwner[MAX_STRING]; + std::string mOwner; F32 mTraffic; S32 mBalance; - LLString mTime; + std::string mTime; U32 mPing; }; @@ -120,6 +123,7 @@ private: static void onCommitSearch(LLUICtrl*, void* data); static void onClickSearch(void* data); + static void onClickStatGraph(void* data); private: LLTextBox *mTextBalance; @@ -128,6 +132,9 @@ private: LLTextBox* mTextParcelName; + LLStatGraph *mSGBandwidth; + LLStatGraph *mSGPacketLoss; + LLButton *mBtnBuyCurrency; S32 mBalance; diff --git a/linden/indra/newview/llstatview.cpp b/linden/indra/newview/llstatview.cpp index 20e9503..8a70508 100644 --- a/linden/indra/newview/llstatview.cpp +++ b/linden/indra/newview/llstatview.cpp @@ -47,7 +47,7 @@ LLStatView::LLStatView(const LLString& name, const LLString& label, const LLStri mNumStatBars(0), mSetting(setting) { - mReshapeFlags = FOLLOWS_TOP | FOLLOWS_LEFT; + setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); setLabel(label); BOOL open = FALSE; if (mSetting.length() > 0) @@ -98,7 +98,7 @@ LLStatBar *LLStatView::addStat(const LLString& name, LLStat *statp) mStatBars.push_back(stat_barp); // Rearrange all child bars. - reshape(mRect.getWidth(), mRect.getHeight()); + reshape(getRect().getWidth(), getRect().getHeight()); return stat_barp; } diff --git a/linden/indra/newview/llsurface.cpp b/linden/indra/newview/llsurface.cpp index 9e23713..b5eb902 100644 --- a/linden/indra/newview/llsurface.cpp +++ b/linden/indra/newview/llsurface.cpp @@ -663,83 +663,6 @@ BOOL LLSurface::idleUpdate(F32 max_update_time) return did_update; } -// TODO -- move this to LLViewerRegion class -void LLSurface::renderSurfaceBounds() -{ - // Shows the edge of the surface, so that visibility across regions can be seen - LLVector3 origin_agent = getOriginAgent(); - - glPushMatrix(); - LLGLSNoTexture no_texture; - - F32 region_width_meters = gWorldPointer->getRegionWidthInMeters(); - glTranslatef(origin_agent.mV[VX] + (region_width_meters * 0.005f), - origin_agent.mV[VY] + (region_width_meters * 0.005f), 0.f); - - glColor4ub(0, 128, 0, 64); - - F32 length = region_width_meters * 0.995f; - F32 height = length/8.0f; - - glBegin(GL_QUADS); - glVertex3f(length, 0, 0); - glVertex3f(0,0, 0); - glVertex3f(0,0, height); - glVertex3f(length,0, height); - - glVertex3f(length,0, height); - glVertex3f(0,0, height); - glVertex3f(0,0, 0); - glVertex3f(length, 0, 0); - glEnd(); - - glTranslatef(length, 0, 0); - glRotated(90, 0, 0, 1); - glBegin(GL_QUADS); - glVertex3f(length, 0, 0); - glVertex3f(0,0, 0); - glVertex3f(0,0, height); - glVertex3f(length,0, height); - - glVertex3f(length,0, height); - glVertex3f(0,0, height); - glVertex3f(0,0, 0); - glVertex3f(length, 0, 0); - - glEnd(); - glTranslatef(length, 0, 0); - glRotated(90, 0, 0, 1); - glBegin(GL_QUADS); - glVertex3f(length, 0, 0); - glVertex3f(0,0, 0); - glVertex3f(0,0, height); - glVertex3f(length,0, height); - - glVertex3f(length,0, height); - glVertex3f(0,0, height); - glVertex3f(0,0, 0); - glVertex3f(length, 0, 0); - glEnd(); - glTranslatef(length, 0, 0); - glRotated(90, 0, 0, 1); - glBegin(GL_QUADS); - glVertex3f(length, 0, 0); - glVertex3f(0,0, 0); - glVertex3f(0,0, height); - glVertex3f(length,0, height); - - glVertex3f(length,0, height); - glVertex3f(0,0, height); - glVertex3f(0,0, 0); - glVertex3f(length, 0, 0); - glEnd(); - glTranslatef(length, 0, 0); - glRotated(90, 0, 0, 1); - - glPopMatrix(); -} - - void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch) { diff --git a/linden/indra/newview/llsurface.h b/linden/indra/newview/llsurface.h index 2ecfd81..d8da6fc 100644 --- a/linden/indra/newview/llsurface.h +++ b/linden/indra/newview/llsurface.h @@ -120,8 +120,6 @@ public: // Update methods (called during idle, normally) BOOL idleUpdate(F32 max_update_time); - void renderSurfaceBounds(); - BOOL containsPosition(const LLVector3 &position); void moveZ(const S32 x, const S32 y, const F32 delta); diff --git a/linden/indra/newview/llsurfacepatch.cpp b/linden/indra/newview/llsurfacepatch.cpp index f076508..432ca01 100644 --- a/linden/indra/newview/llsurfacepatch.cpp +++ b/linden/indra/newview/llsurfacepatch.cpp @@ -364,9 +364,17 @@ const LLVector3 &LLSurfacePatch::getNormal(const U32 x, const U32 y) const void LLSurfacePatch::updateCameraDistanceRegion(const LLVector3 &pos_region) { - LLVector3 dv = pos_region; - dv -= mCenterRegion; - mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius)); + if (LLPipeline::sDynamicLOD) + { + LLVector3 dv = pos_region; + dv -= mCenterRegion; + mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/ + llmax(LLVOSurfacePatch::sLODFactor, 0.1f); + } + else + { + mVisInfo.mDistance = 0.f; + } } F32 LLSurfacePatch::getDistance() const @@ -833,8 +841,11 @@ void LLSurfacePatch::updateVisibility() F32 stride_per_distance = DEFAULT_DELTA_ANGLE / mSurfacep->getMetersPerGrid(); U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); + LLVector3 center = mCenterRegion + mSurfacep->getOriginAgent(); + LLVector3 radius = LLVector3(mRadius, mRadius, mRadius); + // sphere in frustum on global coordinates - if (gCamera->sphereInFrustum(mCenterRegion + mSurfacep->getOriginAgent(), mRadius) ) + if (gCamera->AABBInFrustumNoFarClip(center, radius)) { // We now need to calculate the render stride based on patchp's distance // from LLCamera render_stride is governed by a relation something like this... diff --git a/linden/indra/newview/lltexlayer.cpp b/linden/indra/newview/lltexlayer.cpp index 8958516..78fb126 100644 --- a/linden/indra/newview/lltexlayer.cpp +++ b/linden/indra/newview/lltexlayer.cpp @@ -52,6 +52,7 @@ #include "llxmltree.h" #include "pipeline.h" #include "v4coloru.h" +#include "llglimmediate.h" //#include "../tools/imdebug/imdebug.h" @@ -176,22 +177,22 @@ void LLTexLayerSetBuffer::cancelUpload() void LLTexLayerSetBuffer::pushProjection() { glMatrixMode(GL_PROJECTION); - glPushMatrix(); + gGL.pushMatrix(); glLoadIdentity(); glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gGL.pushMatrix(); glLoadIdentity(); } void LLTexLayerSetBuffer::popProjection() { glMatrixMode(GL_PROJECTION); - glPopMatrix(); + gGL.popMatrix(); glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gGL.popMatrix(); } BOOL LLTexLayerSetBuffer::needsRender() @@ -274,6 +275,7 @@ BOOL LLTexLayerSetBuffer::render() // Composite the color data LLGLSUIDefault gls_ui; success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mWidth, mHeight ); + gGL.flush(); if( upload_now ) { @@ -291,7 +293,7 @@ BOOL LLTexLayerSetBuffer::render() // reset GL state glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gGL.blendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // we have valid texture data now mInitialized = TRUE; @@ -761,7 +763,9 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) LLTexLayer* layer = *iter; if( layer->getRenderPass() == RP_COLOR ) { + gGL.flush(); success &= layer->render( x, y, width, height ); + gGL.flush(); } } @@ -769,8 +773,9 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) if( !getInfo()->mStaticAlphaFileName.empty() ) { LLGLSNoAlphaTest gls_no_alpha_test; + gGL.flush(); glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE ); - glBlendFunc( GL_ONE, GL_ZERO ); + gGL.blendFunc( GL_ONE, GL_ZERO ); { LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticAlphaFileName, TRUE ); @@ -787,19 +792,22 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) } LLImageGL::unbindTexture(0, GL_TEXTURE_2D); + gGL.flush(); glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gGL.blendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); } else if( getInfo()->mClearAlpha ) { // Set the alpha channel to one (clean up after previous blending) LLGLSNoTextureNoAlphaTest gls_no_alpha; - glColor4f( 0.f, 0.f, 0.f, 1.f ); + gGL.color4f( 0.f, 0.f, 0.f, 1.f ); + gGL.flush(); glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE ); gl_rect_2d_simple( width, height ); + gGL.flush(); glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); } stop_glerror(); @@ -827,7 +835,7 @@ BOOL LLTexLayerSet::renderBump( S32 x, S32 y, S32 width, S32 height ) // Set the alpha channel to one (clean up after previous blending) LLGLSNoTextureNoAlphaTest gls_no_texture_no_alpha; - glColor4f( 0.f, 0.f, 0.f, 1.f ); + gGL.color4f( 0.f, 0.f, 0.f, 1.f ); glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE ); gl_rect_2d_simple( width, height ); @@ -1321,14 +1329,16 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) renderAlphaMasks( x, y, width, height, &net_color ); alpha_mask_specified = TRUE; - glBlendFunc( GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA ); + gGL.flush(); + gGL.blendFunc( GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA ); } - glColor4fv( net_color.mV); + gGL.color4fv( net_color.mV); if( getInfo()->mWriteAllChannels ) { - glBlendFunc( GL_ONE, GL_ZERO ); + gGL.flush(); + gGL.blendFunc( GL_ONE, GL_ZERO ); } if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly ) @@ -1383,14 +1393,15 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height ) color_specified ) { LLGLSNoTextureNoAlphaTest gls; - glColor4fv( net_color.mV); + gGL.color4fv( net_color.mV); gl_rect_2d_simple( width, height ); } if( alpha_mask_specified || getInfo()->mWriteAllChannels ) { // Restore standard blend func value - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gGL.flush(); + gGL.blendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); stop_glerror(); } @@ -1506,15 +1517,16 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 LLGLSNoTextureNoAlphaTest gls_no_texture_no_alpha_test; // Clear the alpha - glBlendFunc( GL_ONE, GL_ZERO ); + gGL.flush(); + gGL.blendFunc( GL_ONE, GL_ZERO ); - glColor4f( 0.f, 0.f, 0.f, 0.f ); + gGL.color4f( 0.f, 0.f, 0.f, 0.f ); gl_rect_2d_simple( width, height ); } // Accumulate alphas LLGLSNoAlphaTest gls_no_alpha_test; - glColor4f( 1.f, 1.f, 1.f, 1.f ); + gGL.color4f( 1.f, 1.f, 1.f, 1.f ); for( iter = mParamAlphaList.begin(); iter != mParamAlphaList.end(); iter++ ) { @@ -1523,7 +1535,8 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 } // Approximates a min() function - glBlendFunc( GL_DST_ALPHA, GL_ZERO ); + gGL.flush(); + gGL.blendFunc( GL_DST_ALPHA, GL_ZERO ); // Accumulate the alpha component of the texture if( getInfo()->mLocalTexture != -1 ) @@ -1577,11 +1590,11 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4 } // Draw a rectangle with the layer color to multiply the alpha by that color's alpha. - // Note: we're still using glBlendFunc( GL_DST_ALPHA, GL_ZERO ); + // Note: we're still using gGL.blendFunc( GL_DST_ALPHA, GL_ZERO ); if( colorp->mV[VW] != 1.f ) { LLGLSNoTextureNoAlphaTest gls_no_texture_no_alpha_test; - glColor4fv( colorp->mV ); + gGL.color4fv( colorp->mV ); gl_rect_2d_simple( width, height ); } @@ -1947,13 +1960,14 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height ) return success; } + gGL.flush(); if( getInfo()->mMultiplyBlend ) { - glBlendFunc( GL_DST_ALPHA, GL_ZERO ); // Multiplication: approximates a min() function + gGL.blendFunc( GL_DST_ALPHA, GL_ZERO ); // Multiplication: approximates a min() function } else { - glBlendFunc( GL_ONE, GL_ONE ); // Addition: approximates a max() function + gGL.blendFunc( GL_ONE, GL_ONE ); // Addition: approximates a max() function } if( !getInfo()->mStaticImageFileName.empty() && !mStaticImageInvalid) @@ -2069,7 +2083,7 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height ) else { LLGLSNoTextureNoAlphaTest gls_no_texture_no_alpha_test; - glColor4f( 0.f, 0.f, 0.f, effective_weight ); + gGL.color4f( 0.f, 0.f, 0.f, effective_weight ); gl_rect_2d_simple( width, height ); } diff --git a/linden/indra/newview/lltexturectrl.cpp b/linden/indra/newview/lltexturectrl.cpp index 0314f7c..2ca9f99 100644 --- a/linden/indra/newview/lltexturectrl.cpp +++ b/linden/indra/newview/lltexturectrl.cpp @@ -34,6 +34,7 @@ #include "lltexturectrl.h" +#include "llglimmediate.h" #include "llagent.h" #include "llviewerimagelist.h" #include "llcheckboxctrl.h" @@ -462,7 +463,7 @@ BOOL LLFloaterTexturePicker::postBuild() if (!mLabel.empty()) { - std::string pick = childGetText("pick title"); + std::string pick = getString("pick title"); setTitle(pick + mLabel); } @@ -483,42 +484,42 @@ void LLFloaterTexturePicker::draw() { LLGLSNoTexture no_texture; LLGLEnable(GL_CULL_FACE); - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); - glVertex2i(owner_rect.mLeft, owner_rect.mTop); - glVertex2i(owner_rect.mRight, owner_rect.mTop); - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); - glVertex2i(local_rect.mRight, local_rect.mTop); - glVertex2i(local_rect.mLeft, local_rect.mTop); - - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); - glVertex2i(local_rect.mLeft, local_rect.mTop); - glVertex2i(local_rect.mLeft, local_rect.mBottom); - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); - glVertex2i(owner_rect.mLeft, owner_rect.mBottom); - glVertex2i(owner_rect.mLeft, owner_rect.mTop); - - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); - glVertex2i(local_rect.mRight, local_rect.mBottom); - glVertex2i(local_rect.mRight, local_rect.mTop); - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); - glVertex2i(owner_rect.mRight, owner_rect.mTop); - glVertex2i(owner_rect.mRight, owner_rect.mBottom); - - - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); - glVertex2i(local_rect.mLeft, local_rect.mBottom); - glVertex2i(local_rect.mRight, local_rect.mBottom); - glColor4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); - glVertex2i(owner_rect.mRight, owner_rect.mBottom); - glVertex2i(owner_rect.mLeft, owner_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop); + gGL.vertex2i(owner_rect.mRight, owner_rect.mTop); + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); + gGL.vertex2i(local_rect.mRight, local_rect.mTop); + gGL.vertex2i(local_rect.mLeft, local_rect.mTop); + + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); + gGL.vertex2i(local_rect.mLeft, local_rect.mTop); + gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop); + + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); + gGL.vertex2i(local_rect.mRight, local_rect.mBottom); + gGL.vertex2i(local_rect.mRight, local_rect.mTop); + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); + gGL.vertex2i(owner_rect.mRight, owner_rect.mTop); + gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom); + + + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); + gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); + gGL.vertex2i(local_rect.mRight, local_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); + gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom); } - glEnd(); + gGL.end(); } } - if (gFocusMgr.childHasMouseCapture(mDragHandle)) + if (gFocusMgr.childHasMouseCapture(getDragHandle())) { mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); } @@ -566,9 +567,9 @@ void LLFloaterTexturePicker::draw() // Border LLRect border( BORDER_PAD, - mRect.getHeight() - LLFLOATER_HEADER_SIZE - BORDER_PAD, + getRect().getHeight() - LLFLOATER_HEADER_SIZE - BORDER_PAD, ((TEX_PICKER_MIN_WIDTH / 2) - TEXTURE_INVENTORY_PADDING - HPAD) - BORDER_PAD, - BORDER_PAD + FOOTER_HEIGHT + (mRect.getHeight() - TEX_PICKER_MIN_HEIGHT)); + BORDER_PAD + FOOTER_HEIGHT + (getRect().getHeight() - TEX_PICKER_MIN_HEIGHT)); gl_rect_2d( border, LLColor4::black, FALSE ); @@ -908,13 +909,13 @@ LLTextureCtrl::LLTextureCtrl( mDirty( FALSE ) { mCaption = new LLTextBox( label, - LLRect( 0, BTN_HEIGHT_SMALL, mRect.getWidth(), 0 ), - NULL, + LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ), + label, LLFontGL::sSansSerifSmall ); mCaption->setFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM ); addChild( mCaption ); - S32 image_top = mRect.getHeight(); + S32 image_top = getRect().getHeight(); S32 image_bottom = BTN_HEIGHT_SMALL; S32 image_middle = (image_top + image_bottom) / 2; S32 line_height = llround(LLFontGL::sSansSerifSmall->getLineHeight()); @@ -922,14 +923,14 @@ LLTextureCtrl::LLTextureCtrl( mTentativeLabel = new LLTextBox( "Multiple", LLRect( 0, image_middle + line_height / 2, - mRect.getWidth(), image_middle - line_height / 2 ), - NULL, + getRect().getWidth(), image_middle - line_height / 2 ), + "Multiple", LLFontGL::sSansSerifSmall ); mTentativeLabel->setHAlign( LLFontGL::HCENTER ); mTentativeLabel->setFollowsAll(); addChild( mTentativeLabel ); - LLRect border_rect(0, mRect.getHeight(), mRect.getWidth(), 0); + LLRect border_rect(0, getRect().getHeight(), getRect().getWidth(), 0); border_rect.mBottom += BTN_HEIGHT_SMALL; mBorder = new LLViewBorder("border", border_rect, LLViewBorder::BEVEL_IN); addChild(mBorder); @@ -1013,7 +1014,7 @@ void LLTextureCtrl::setCaption(const LLString& caption) void LLTextureCtrl::setCanApplyImmediately(BOOL b) { mCanApplyImmediately = b; - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)LLFloater::getFloaterByHandle(mFloaterHandle); + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); if( floaterp ) { floaterp->setCanApplyImmediately(b); @@ -1031,7 +1032,7 @@ void LLTextureCtrl::setVisible( BOOL visible ) void LLTextureCtrl::setEnabled( BOOL enabled ) { - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)LLFloater::getFloaterByHandle(mFloaterHandle); + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); if( enabled ) { LLString tooltip; @@ -1061,7 +1062,7 @@ void LLTextureCtrl::setValid(BOOL valid ) mValid = valid; if (!valid) { - LLFloaterTexturePicker* pickerp = (LLFloaterTexturePicker*)LLFloater::getFloaterByHandle(mFloaterHandle); + LLFloaterTexturePicker* pickerp = (LLFloaterTexturePicker*)mFloaterHandle.get(); if (pickerp) { pickerp->setActive(FALSE); @@ -1096,7 +1097,7 @@ void LLTextureCtrl::setLabel(const LLString& label) void LLTextureCtrl::showPicker(BOOL take_focus) { - LLFloater* floaterp = LLFloater::getFloaterByHandle(mFloaterHandle); + LLFloater* floaterp = mFloaterHandle.get(); // Show the dialog if( floaterp ) @@ -1134,7 +1135,7 @@ void LLTextureCtrl::showPicker(BOOL take_focus) void LLTextureCtrl::closeFloater() { - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)LLFloater::getFloaterByHandle(mFloaterHandle); + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); if( floaterp ) { floaterp->setOwner(NULL); @@ -1180,7 +1181,7 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask) void LLTextureCtrl::onFloaterClose() { - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)LLFloater::getFloaterByHandle(mFloaterHandle); + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); if (floaterp) { @@ -1193,9 +1194,9 @@ void LLTextureCtrl::onFloaterClose() void LLTextureCtrl::onFloaterCommit(ETexturePickOp op) { - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)LLFloater::getFloaterByHandle(mFloaterHandle); + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); - if( floaterp && mEnabled) + if( floaterp && getEnabled()) { mDirty = (op != TEXTURE_CANCEL); if( floaterp->isDirty() ) @@ -1227,7 +1228,7 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id ) { mImageItemID.setNull(); mImageAssetID = asset_id; - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)LLFloater::getFloaterByHandle(mFloaterHandle); + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); if( floaterp && getEnabled() ) { floaterp->setImageID( asset_id ); @@ -1247,7 +1248,7 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, // returns true, then the cast was valid, and we can perform // the third test without problems. LLInventoryItem* item = (LLInventoryItem*)cargo_data; - if (mEnabled && (cargo_type == DAD_TEXTURE) && allowDrop(item)) + if (getEnabled() && (cargo_type == DAD_TEXTURE) && allowDrop(item)) { if (drop) { @@ -1290,7 +1291,7 @@ void LLTextureCtrl::draw() } // Border - LLRect border( 0, mRect.getHeight(), mRect.getWidth(), BTN_HEIGHT_SMALL ); + LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL ); gl_rect_2d( border, mBorderColor, FALSE ); // Interior @@ -1315,7 +1316,7 @@ void LLTextureCtrl::draw() gl_draw_x( interior, LLColor4::black ); } - mTentativeLabel->setVisible( !mTexturep.isNull() && mTentative ); + mTentativeLabel->setVisible( !mTexturep.isNull() && getTentative() ); LLUICtrl::draw(); } @@ -1371,7 +1372,7 @@ BOOL LLTextureCtrl::doDrop(LLInventoryItem* item) BOOL LLTextureCtrl::handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent) { - if( getVisible() && mEnabled && !called_from_parent && ' ' == uni_char ) + if( getVisible() && getEnabled() && !called_from_parent && ' ' == uni_char ) { showPicker(TRUE); return TRUE; @@ -1450,3 +1451,4 @@ BOOL LLToolTexEyedropper::handleHover(S32 x, S32 y, MASK mask) } + diff --git a/linden/indra/newview/lltexturectrl.h b/linden/indra/newview/lltexturectrl.h index 80fcac2..91dee4f 100644 --- a/linden/indra/newview/lltexturectrl.h +++ b/linden/indra/newview/lltexturectrl.h @@ -44,6 +44,7 @@ class LLFloaterTexturePicker; class LLInventoryItem; class LLTextBox; class LLViewBorder; +class LLViewerImage; // used for setting drag & drop callbacks. typedef BOOL (*drag_n_drop_callback)(LLUICtrl*, LLInventoryItem*, void*); @@ -163,7 +164,7 @@ private: LLUUID mImageAssetID; LLUUID mDefaultImageAssetID; LLString mDefaultImageName; - LLViewHandle mFloaterHandle; + LLHandle mFloaterHandle; LLTextBox* mTentativeLabel; LLTextBox* mCaption; LLString mLabel; diff --git a/linden/indra/newview/lltextureview.cpp b/linden/indra/newview/lltextureview.cpp index 96a6127..09392f4 100644 --- a/linden/indra/newview/lltextureview.cpp +++ b/linden/indra/newview/lltextureview.cpp @@ -40,6 +40,7 @@ #include "lllfsthread.h" #include "llui.h" #include "llimageworker.h" +#include "llglimmediate.h" #include "llhoverview.h" #include "llselectmgr.h" @@ -210,7 +211,7 @@ void LLTextureBar::draw() mImagep->mFetchPriority); } - LLFontGL::sMonospace->renderUTF8(tex_str, 0, title_x1, mRect.getHeight(), + LLFontGL::sMonospace->renderUTF8(tex_str, 0, title_x1, getRect().getHeight(), color, LLFontGL::LEFT, LLFontGL::TOP); // State @@ -246,7 +247,7 @@ void LLTextureBar::draw() mImagep->mFetchState; state = llclamp(state,0,fetch_state_desc_size-1); - LLFontGL::sMonospace->renderUTF8(fetch_state_desc[state].desc, 0, title_x2, mRect.getHeight(), + LLFontGL::sMonospace->renderUTF8(fetch_state_desc[state].desc, 0, title_x2, getRect().getHeight(), fetch_state_desc[state].color, LLFontGL::LEFT, LLFontGL::TOP); LLGLSNoTexture gls_no_texture; @@ -257,7 +258,7 @@ void LLTextureBar::draw() left = bar_left; right = left + bar_width; - glColor4f(0.f, 0.f, 0.f, 0.75f); + gGL.color4f(0.f, 0.f, 0.f, 0.75f); gl_rect_2d(left, top, right, bottom); F32 data_progress = mImagep->mDownloadProgress; @@ -268,7 +269,7 @@ void LLTextureBar::draw() right = left + llfloor(data_progress * (F32)bar_width); if (right > left) { - glColor4f(0.f, 0.f, 1.f, 0.75f); + gGL.color4f(0.f, 0.f, 1.f, 0.75f); gl_rect_2d(left, top, right, bottom); } } @@ -302,7 +303,7 @@ void LLTextureBar::draw() if (last_event < 1.f) { clr.setAlpha(1.f - last_event); - glColor4fv(clr.mV); + gGL.color4fv(clr.mV); gl_rect_2d(pip_x, top, pip_x + pip_width, bottom); } pip_x += pip_width + pip_space; @@ -316,7 +317,7 @@ void LLTextureBar::draw() { clr = mImagep->getMissed() ? LLColor4::red : LLColor4::magenta1; clr.setAlpha(1.f - last_event); - glColor4fv(clr.mV); + gGL.color4fv(clr.mV); gl_rect_2d(pip_x, top, pip_x + pip_width, bottom); } } @@ -328,7 +329,7 @@ void LLTextureBar::draw() // draw the packet data // { // LLString num_str = llformat("%3d/%3d", mImagep->mLastPacket+1, mImagep->mPackets); -// LLFontGL::sMonospace->renderUTF8(num_str, 0, bar_left + 100, mRect.getHeight(), color, +// LLFontGL::sMonospace->renderUTF8(num_str, 0, bar_left + 100, getRect().getHeight(), color, // LLFontGL::LEFT, LLFontGL::TOP); // } @@ -336,7 +337,7 @@ void LLTextureBar::draw() { LLString num_str = llformat("%3dx%3d (%d) %7d", mImagep->getWidth(), mImagep->getHeight(), mImagep->getDiscardLevel(), mImagep->mTextureMemory); - LLFontGL::sMonospace->renderUTF8(num_str, 0, title_x4, mRect.getHeight(), color, + LLFontGL::sMonospace->renderUTF8(num_str, 0, title_x4, getRect().getHeight(), color, LLFontGL::LEFT, LLFontGL::TOP); } } @@ -422,7 +423,7 @@ void LLGLTexMemBar::draw() LLGLSNoTexture gls_no_texture; - glColor4f(0.5f, 0.5f, 0.5f, 0.75f); + gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f); gl_rect_2d(left, top, right, bottom); @@ -430,15 +431,15 @@ void LLGLTexMemBar::draw() right = left + llfloor(bound_mem * bar_scale); if (bound_mem < llfloor(max_bound_mem * texmem_lower_bound_scale)) { - glColor4f(0.f, 1.f, 0.f, 0.75f); + gGL.color4f(0.f, 1.f, 0.f, 0.75f); } else if (bound_mem < max_bound_mem) { - glColor4f(1.f, 1.f, 0.f, 0.75f); + gGL.color4f(1.f, 1.f, 0.f, 0.75f); } else { - glColor4f(1.f, 0.f, 0.f, 0.75f); + gGL.color4f(1.f, 0.f, 0.f, 0.75f); } gl_rect_2d(left, top, right, bottom); @@ -450,22 +451,20 @@ void LLGLTexMemBar::draw() right = left + llfloor(total_mem * bar_scale); if (total_mem < llfloor(max_total_mem * texmem_lower_bound_scale)) { - glColor4f(0.f, 1.f, 0.f, 0.75f); + gGL.color4f(0.f, 1.f, 0.f, 0.75f); } else if (total_mem < max_total_mem) { - glColor4f(1.f, 1.f, 0.f, 0.75f); + gGL.color4f(1.f, 1.f, 0.f, 0.75f); } else { - glColor4f(1.f, 0.f, 0.f, 0.75f); + gGL.color4f(1.f, 0.f, 0.f, 0.75f); } gl_rect_2d(left, top, right, bottom); //---------------------------------------------------------------------------- - LLGLEnable tex(GL_TEXTURE_2D); - text = llformat("Textures: Count: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d(%d) RAW:%d", gImageList.getNumImages(), LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(), @@ -727,7 +726,7 @@ void LLTextureView::draw() mGLTexMemBar = new LLGLTexMemBar("gl texmem bar", this); addChild(mGLTexMemBar); - reshape(mRect.getWidth(), mRect.getHeight(), TRUE); + reshape(getRect().getWidth(), getRect().getHeight(), TRUE); /* count = gImageList.getNumImages(); @@ -806,3 +805,4 @@ BOOL LLTextureView::handleKey(KEY key, MASK mask, BOOL called_from_parent) return FALSE; } + diff --git a/linden/indra/newview/lltextureview.h b/linden/indra/newview/lltextureview.h index 2bf9461..bf0c518 100644 --- a/linden/indra/newview/lltextureview.h +++ b/linden/indra/newview/lltextureview.h @@ -33,7 +33,6 @@ #define LL_LLTEXTUREVIEW_H #include "llcontainerview.h" -#include "linked_lists.h" class LLViewerImage; class LLTextureBar; diff --git a/linden/indra/newview/lltool.cpp b/linden/indra/newview/lltool.cpp index 2be76a0..394b64d 100644 --- a/linden/indra/newview/lltool.cpp +++ b/linden/indra/newview/lltool.cpp @@ -42,7 +42,6 @@ #include "lltoolfocus.h" #include "llfocusmgr.h" #include "llagent.h" -#include "llviewborder.h" extern BOOL gDebugClicks; diff --git a/linden/indra/newview/lltool.h b/linden/indra/newview/lltool.h index 50e4da0..0c72e79 100644 --- a/linden/indra/newview/lltool.h +++ b/linden/indra/newview/lltool.h @@ -51,7 +51,7 @@ public: virtual ~LLTool(); // Hack to support LLFocusMgr - virtual BOOL isView() { return FALSE; } + virtual BOOL isView() const { return FALSE; } // Virtual functions inherited from LLMouseHandler virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); diff --git a/linden/indra/newview/lltoolbar.cpp b/linden/indra/newview/lltoolbar.cpp index 4120c2d..9edc469 100644 --- a/linden/indra/newview/lltoolbar.cpp +++ b/linden/indra/newview/lltoolbar.cpp @@ -389,7 +389,7 @@ void LLToolBar::updateCommunicateList() communicate_button->addSeparator(ADD_TOP); communicate_button->add(LLFloaterMute::getInstance()->getShortTitle(), LLSD("mute list"), ADD_TOP); - std::set::const_iterator floater_handle_it; + std::set >::const_iterator floater_handle_it; if (gIMMgr->getIMFloaterHandles().size() > 0) { @@ -398,7 +398,7 @@ void LLToolBar::updateCommunicateList() for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it) { - LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)LLFloater::getFloaterByHandle(*floater_handle_it); + LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)floater_handle_it->get(); if (im_floaterp) { LLString floater_title = im_floaterp->getNumUnreadMessages() > 0 ? "*" : ""; @@ -443,10 +443,10 @@ void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, void* user_data) LLFloaterChatterBox::getInstance()->addFloater(LLFloaterChat::getInstance(), FALSE); LLUUID session_to_show; - std::set::const_iterator floater_handle_it; + std::set >::const_iterator floater_handle_it; for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it) { - LLFloater* im_floaterp = LLFloater::getFloaterByHandle(*floater_handle_it); + LLFloater* im_floaterp = floater_handle_it->get(); if (im_floaterp) { if (im_floaterp->isFrontmost()) diff --git a/linden/indra/newview/lltoolbrush.cpp b/linden/indra/newview/lltoolbrush.cpp index 5f402a8..2db1d5b 100644 --- a/linden/indra/newview/lltoolbrush.cpp +++ b/linden/indra/newview/lltoolbrush.cpp @@ -35,6 +35,7 @@ #include "lltoolselectland.h" #include "llgl.h" +#include "llglimmediate.h" #include "message.h" @@ -107,10 +108,10 @@ void LLToolBrushLand::modifyLandAtPointGlobal(const LLVector3d &pos_global, S32 radioAction = gSavedSettings.getS32("RadioLandBrushAction"); determineAffectedRegions(mLastAffectedRegions, pos_global); - for(LLViewerRegion* regionp = mLastAffectedRegions.getFirstData(); - regionp != NULL; - regionp = mLastAffectedRegions.getNextData()) + for(region_list_t::iterator iter = mLastAffectedRegions.begin(); + iter != mLastAffectedRegions.end(); ++iter) { + LLViewerRegion* regionp = *iter; //BOOL is_changed = FALSE; LLVector3 pos_region = regionp->getPosRegionFromGlobal(pos_global); LLSurface &land = regionp->getLand(); @@ -199,7 +200,7 @@ void LLToolBrushLand::modifyLandInSelectionGlobal() S32 radioAction = gSavedSettings.getS32("RadioLandBrushAction"); - mLastAffectedRegions.removeAllNodes(); + mLastAffectedRegions.clear(); determineAffectedRegions(mLastAffectedRegions, LLVector3d(min.mdV[VX], min.mdV[VY], 0)); determineAffectedRegions(mLastAffectedRegions, LLVector3d(min.mdV[VX], max.mdV[VY], 0)); @@ -222,10 +223,10 @@ void LLToolBrushLand::modifyLandInSelectionGlobal() } // Stop if our selection include a no-terraform region - for(LLViewerRegion* regionp = mLastAffectedRegions.getFirstData(); - regionp != NULL; - regionp = mLastAffectedRegions.getNextData()) + for(region_list_t::iterator iter = mLastAffectedRegions.begin(); + iter != mLastAffectedRegions.end(); ++iter) { + LLViewerRegion* regionp = *iter; if (!canTerraform(regionp)) { alertNoTerraform(regionp); @@ -233,10 +234,10 @@ void LLToolBrushLand::modifyLandInSelectionGlobal() } } - for(LLViewerRegion* regionp = mLastAffectedRegions.getFirstData(); - regionp != NULL; - regionp = mLastAffectedRegions.getNextData()) + for(region_list_t::iterator iter = mLastAffectedRegions.begin(); + iter != mLastAffectedRegions.end(); ++iter) { + LLViewerRegion* regionp = *iter; //BOOL is_changed = FALSE; LLVector3 min_region = regionp->getPosRegionFromGlobal(min); LLVector3 max_region = regionp->getPosRegionFromGlobal(max); @@ -397,7 +398,7 @@ BOOL LLToolBrushLand::handleHover( S32 x, S32 y, MASK mask ) BOOL LLToolBrushLand::handleMouseUp(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; - mLastAffectedRegions.removeAllNodes(); + mLastAffectedRegions.clear(); if( hasMouseCapture() ) { // Release the mouse @@ -451,15 +452,15 @@ void LLToolBrushLand::render() spot.mdV[VY] = floor( spot.mdV[VY] + 0.5 ); mBrushIndex = gSavedSettings.getS32("RadioLandBrushSize"); - LLLinkedList regions; + region_list_t regions; determineAffectedRegions(regions, spot); // Now, for each region, render the overlay LLVector3 pos_world = gAgent.getRegion()->getPosRegionFromGlobal(spot); - for(LLViewerRegion* region = regions.getFirstData(); - region != NULL; - region = regions.getNextData()) + for(region_list_t::iterator iter = regions.begin(); + iter != regions.end(); ++iter) { + LLViewerRegion* region = *iter; renderOverlay(region->getLand(), region->getPosRegionFromGlobal(spot), pos_world); @@ -476,33 +477,29 @@ void LLToolBrushLand::renderOverlay(LLSurface& land, const LLVector3& pos_region LLGLSNoTexture gls_no_texture; LLGLDepthTest mDepthTest(GL_TRUE); glPushMatrix(); - glColor4fv(OVERLAY_COLOR.mV); + gGL.color4fv(OVERLAY_COLOR.mV); glTranslatef(0.0f, 0.0f, 1.0f); - //glPushMatrix(); - //glTranslatef(spot.mV[VX], spot.mV[VY], 100.0f); - //gl_rect_2d(0, 10, 10, 0); - //glPopMatrix(); + S32 i = (S32) pos_region.mV[VX]; S32 j = (S32) pos_region.mV[VY]; S32 half_edge = llfloor(LAND_BRUSH_SIZE[mBrushIndex]); - //F32 dz = 0.0f; - //S32 dist = 0; - glBegin(GL_POINTS); + + gGL.begin(GL_POINTS); for(S32 di = -half_edge; di <= half_edge; di++) { if((i+di) < 0 || (i+di) >= (S32)land.mGridsPerEdge) continue; for(S32 dj = -half_edge; dj <= half_edge; dj++) { if( (j+dj) < 0 || (j+dj) >= (S32)land.mGridsPerEdge ) continue; - glVertex3f(pos_world.mV[VX] + di, pos_world.mV[VY] + dj, + gGL.vertex3f(pos_world.mV[VX] + di, pos_world.mV[VY] + dj, land.getZ((i+di)+(j+dj)*land.mGridsPerEdge)); } } - glEnd(); + gGL.end(); glPopMatrix(); } -void LLToolBrushLand::determineAffectedRegions(LLLinkedList& regions, +void LLToolBrushLand::determineAffectedRegions(region_list_t& regions, const LLVector3d& spot ) const { LLVector3d corner(spot); @@ -510,27 +507,27 @@ void LLToolBrushLand::determineAffectedRegions(LLLinkedList& reg corner.mdV[VY] -= (LAND_BRUSH_SIZE[mBrushIndex] / 2); LLViewerRegion* region = NULL; region = gWorldPointer->getRegionFromPosGlobal(corner); - if(region && !regions.checkData(region)) + if(region && regions.find(region) == regions.end()) { - regions.addData(region); + regions.insert(region); } corner.mdV[VY] += LAND_BRUSH_SIZE[mBrushIndex]; region = gWorldPointer->getRegionFromPosGlobal(corner); - if(region && !regions.checkData(region)) + if(region && regions.find(region) == regions.end()) { - regions.addData(region); + regions.insert(region); } corner.mdV[VX] += LAND_BRUSH_SIZE[mBrushIndex]; region = gWorldPointer->getRegionFromPosGlobal(corner); - if(region && !regions.checkData(region)) + if(region && regions.find(region) == regions.end()) { - regions.addData(region); + regions.insert(region); } corner.mdV[VY] -= LAND_BRUSH_SIZE[mBrushIndex]; region = gWorldPointer->getRegionFromPosGlobal(corner); - if(region && !regions.checkData(region)) + if(region && regions.find(region) == regions.end()) { - regions.addData(region); + regions.insert(region); } } @@ -557,10 +554,10 @@ void LLToolBrushLand::onMouseCaptureLost() // static void LLToolBrushLand::undo() { - for(LLViewerRegion* regionp = mLastAffectedRegions.getFirstData(); - regionp != NULL; - regionp = mLastAffectedRegions.getNextData()) + for(region_list_t::iterator iter = mLastAffectedRegions.begin(); + iter != mLastAffectedRegions.end(); ++iter) { + LLViewerRegion* regionp = *iter; gMessageSystem->newMessageFast(_PREHASH_UndoLand); gMessageSystem->nextBlockFast(_PREHASH_AgentData); gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); @@ -573,10 +570,10 @@ void LLToolBrushLand::undo() /* void LLToolBrushLand::redo() { - for(LLViewerRegion* regionp = mLastAffectedRegions.getFirstData(); - regionp != NULL; - regionp = mLastAffectedRegions.getNextData()) + for(region_list_t::iterator iter = mLastAffectedRegions.begin(); + iter != mLastAffectedRegions.end(); ++iter) { + LLViewerRegion* regionp = *iter; gMessageSystem->newMessageFast(_PREHASH_RedoLand); gMessageSystem->nextBlockFast(_PREHASH_AgentData); gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); diff --git a/linden/indra/newview/lltoolbrush.h b/linden/indra/newview/lltoolbrush.h index 129a08c..9a12a18 100644 --- a/linden/indra/newview/lltoolbrush.h +++ b/linden/indra/newview/lltoolbrush.h @@ -40,8 +40,6 @@ class LLSurface; class LLVector3d; class LLViewerRegion; -template class LLLinkedList; - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLToolBrushLand // @@ -50,6 +48,8 @@ template class LLLinkedList; class LLToolBrushLand : public LLTool, public LLEditMenuHandler { + typedef std::set region_list_t; + public: LLToolBrushLand(); @@ -74,17 +74,13 @@ public: void modifyLandInSelectionGlobal(); virtual void undo(); - virtual BOOL canUndo() { return TRUE; } - - //virtual void redo(); - virtual BOOL canRedo() { return FALSE; } - + virtual BOOL canUndo() const { return TRUE; } protected: void brush( void ); void modifyLandAtPointGlobal( const LLVector3d &spot, MASK mask ); - void determineAffectedRegions(LLLinkedList& regions, + void determineAffectedRegions(region_list_t& regions, const LLVector3d& spot) const; void renderOverlay(LLSurface& land, const LLVector3& pos_region, const LLVector3& pos_world); @@ -103,7 +99,8 @@ protected: BOOL mGotHover; BOOL mLastShowParcelOwners; BOOL mBrushSelected; - LLLinkedList mLastAffectedRegions; + // Order doesn't matter and we do check for existance of regions, so use a set + region_list_t mLastAffectedRegions; }; extern LLToolBrushLand *gToolLand; diff --git a/linden/indra/newview/lltoolcomp.cpp b/linden/indra/newview/lltoolcomp.cpp index 2882b6f..055cbb7 100644 --- a/linden/indra/newview/lltoolcomp.cpp +++ b/linden/indra/newview/lltoolcomp.cpp @@ -173,7 +173,7 @@ void LLToolCompInspect::pickCallback(S32 x, S32 y, MASK mask) { if (gSelectMgr->getSelection()->getObjectCount()) { - gEditMenuHandler = gSelectMgr; + LLEditMenuHandler::gEditMenuHandler = gSelectMgr; } gToolInspect->setCurrentTool( gToolInspect->mSelectRect ); gToolInspect->mSelectRect->handleMouseDown( x, y, mask ); @@ -247,7 +247,7 @@ void LLToolCompTranslate::pickCallback(S32 x, S32 y, MASK mask) { if (gToolTranslate->mManip->getSelection()->getObjectCount()) { - gEditMenuHandler = gSelectMgr; + LLEditMenuHandler::gEditMenuHandler = gSelectMgr; } BOOL can_move = gToolTranslate->mManip->canAffectSelection(); @@ -372,7 +372,7 @@ void LLToolCompScale::pickCallback(S32 x, S32 y, MASK mask) { if (gToolStretch->mManip->getSelection()->getObjectCount()) { - gEditMenuHandler = gSelectMgr; + LLEditMenuHandler::gEditMenuHandler = gSelectMgr; } if( LLManip::LL_NO_PART != gToolStretch->mManip->getHighlightedPart() ) { @@ -572,7 +572,7 @@ void LLToolCompRotate::pickCallback(S32 x, S32 y, MASK mask) { if (gToolRotate->mManip->getSelection()->getObjectCount()) { - gEditMenuHandler = gSelectMgr; + LLEditMenuHandler::gEditMenuHandler = gSelectMgr; } if( LLManip::LL_NO_PART != gToolRotate->mManip->getHighlightedPart() ) { diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp index fb430d7..9524fd8 100644 --- a/linden/indra/newview/lltooldraganddrop.cpp +++ b/linden/indra/newview/lltooldraganddrop.cpp @@ -2778,9 +2778,9 @@ EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnLand( LLViewerInventoryCategory* cat = NULL; locateInventory(item, cat); if(!item || !item->isComplete()) return ACCEPT_NO; - if(!item->getPermissions().allowCopyBy(gAgent.getID(), - gAgent.getGroupID()) - || !item->getPermissions().allowTransferTo(LLUUID::null)) + + if(!gAgent.allowOperation(PERM_COPY, item->getPermissions()) + || !item->getPermissions().allowTransferTo(LLUUID::null)) { return ACCEPT_NO_LOCKED; } diff --git a/linden/indra/newview/lltoolfocus.cpp b/linden/indra/newview/lltoolfocus.cpp index fc64bd0..2e046c4 100644 --- a/linden/indra/newview/lltoolfocus.cpp +++ b/linden/indra/newview/lltoolfocus.cpp @@ -51,7 +51,6 @@ #include "llstatusbar.h" #include "lltoolmgr.h" #include "lltoolselect.h" -#include "llviewborder.h" #include "llviewercamera.h" #include "llviewerobject.h" #include "llviewerwindow.h" diff --git a/linden/indra/newview/lltoolgun.cpp b/linden/indra/newview/lltoolgun.cpp index ded0d52..3385064 100644 --- a/linden/indra/newview/lltoolgun.cpp +++ b/linden/indra/newview/lltoolgun.cpp @@ -37,6 +37,7 @@ #include "llagent.h" #include "llviewercontrol.h" #include "llsky.h" +#include "llappviewer.h" #include "llresmgr.h" #include "llfontgl.h" #include "llui.h" diff --git a/linden/indra/newview/lltoolmgr.cpp b/linden/indra/newview/lltoolmgr.cpp index 99cb54c..0a4a99d 100644 --- a/linden/indra/newview/lltoolmgr.cpp +++ b/linden/indra/newview/lltoolmgr.cpp @@ -438,9 +438,7 @@ void LLToolMgr::clearSavedTool() void LLToolset::addTool(LLTool* tool) { - llassert( !mToolList.checkData( tool ) ); // check for duplicates - - mToolList.addDataAtEnd( tool ); + mToolList.push_back( tool ); if( !mSelectedTool ) { mSelectedTool = tool; @@ -457,7 +455,7 @@ void LLToolset::selectTool(LLTool* tool) void LLToolset::selectToolByIndex( S32 index ) { - LLTool *tool = mToolList.getNthData( index ); + LLTool *tool = (index >= 0 && index < (S32)mToolList.size()) ? mToolList[index] : NULL; if (tool) { mSelectedTool = tool; @@ -467,13 +465,14 @@ void LLToolset::selectToolByIndex( S32 index ) BOOL LLToolset::isToolSelected( S32 index ) { - return (mToolList.getNthData( index ) == mSelectedTool); + LLTool *tool = (index >= 0 && index < (S32)mToolList.size()) ? mToolList[index] : NULL; + return (tool == mSelectedTool); } void LLToolset::selectFirstTool() { - mSelectedTool = mToolList.getFirstData(); + mSelectedTool = (0 < mToolList.size()) ? mToolList[0] : NULL; if (gToolMgr) { gToolMgr->setCurrentTool( mSelectedTool ); @@ -484,43 +483,52 @@ void LLToolset::selectFirstTool() void LLToolset::selectNextTool() { LLTool* next = NULL; - for( LLTool* cur = mToolList.getFirstData(); cur; cur = mToolList.getNextData() ) + for( tool_list_t::iterator iter = mToolList.begin(); + iter != mToolList.end(); ) { - if( cur == mSelectedTool ) + LLTool* cur = *iter++; + if( cur == mSelectedTool && iter != mToolList.end() ) { - next = mToolList.getNextData(); + next = *iter; break; } } - if( !next ) + if( next ) { - next = mToolList.getFirstData(); + mSelectedTool = next; + gToolMgr->setCurrentTool( mSelectedTool ); + } + else + { + selectFirstTool(); } - - mSelectedTool = next; - gToolMgr->setCurrentTool( mSelectedTool ); } void LLToolset::selectPrevTool() { LLTool* prev = NULL; - for( LLTool* cur = mToolList.getLastData(); cur; cur = mToolList.getPreviousData() ) + for( tool_list_t::reverse_iterator iter = mToolList.rbegin(); + iter != mToolList.rend(); ) { - if( cur == mSelectedTool ) + LLTool* cur = *iter++; + if( cur == mSelectedTool && iter != mToolList.rend() ) { - prev = mToolList.getPreviousData(); + prev = *iter; break; } } - if( !prev ) + if( prev ) { - prev = mToolList.getLastData(); + mSelectedTool = prev; + gToolMgr->setCurrentTool( mSelectedTool ); + } + else if (mToolList.size() > 0) + { + selectToolByIndex((S32)mToolList.size()-1); } - mSelectedTool = prev; - gToolMgr->setCurrentTool( mSelectedTool ); } void select_tool( void *tool_pointer ) diff --git a/linden/indra/newview/lltoolmgr.h b/linden/indra/newview/lltoolmgr.h index bdd24a7..c193be3 100644 --- a/linden/indra/newview/lltoolmgr.h +++ b/linden/indra/newview/lltoolmgr.h @@ -32,7 +32,6 @@ #ifndef LL_TOOLMGR_H #define LL_TOOLMGR_H -#include "doublelinkedlist.h" #include "llkeyboard.h" class LLTool; @@ -108,7 +107,8 @@ public: protected: LLTool* mSelectedTool; - LLDoubleLinkedList mToolList; + typedef std::vector tool_list_t; + tool_list_t mToolList; }; // Handy callbacks for switching tools diff --git a/linden/indra/newview/lltoolmorph.cpp b/linden/indra/newview/lltoolmorph.cpp index 37f3216..7368439 100644 --- a/linden/indra/newview/lltoolmorph.cpp +++ b/linden/indra/newview/lltoolmorph.cpp @@ -33,6 +33,7 @@ // File includes #include "lltoolmorph.h" +#include "llglimmediate.h" // Library includes #include "audioengine.h" @@ -66,7 +67,7 @@ //LLToolMorph *gToolMorph = NULL; //static -LLLinkedList LLVisualParamHint::sInstances; +LLVisualParamHint::instance_list_t LLVisualParamHint::sInstances; BOOL LLVisualParamReset::sDirty = FALSE; //----------------------------------------------------------------------------- @@ -92,7 +93,7 @@ LLVisualParamHint::LLVisualParamHint( mRect( pos_x, pos_y + height, pos_x + width, pos_y ), mLastParamWeight(0.f) { - LLVisualParamHint::sInstances.addData( this ); + LLVisualParamHint::sInstances.insert( this ); LLUUID id; id.set( gViewerArt.getString("avatar_thumb_bkgrnd.tga") ); mBackgroundp = gImageList.getImage(id, FALSE, TRUE); @@ -107,7 +108,7 @@ LLVisualParamHint::LLVisualParamHint( //----------------------------------------------------------------------------- LLVisualParamHint::~LLVisualParamHint() { - LLVisualParamHint::sInstances.removeData( this ); + LLVisualParamHint::sInstances.erase( this ); } //----------------------------------------------------------------------------- @@ -118,10 +119,10 @@ LLVisualParamHint::~LLVisualParamHint() void LLVisualParamHint::requestHintUpdates( LLVisualParamHint* exception1, LLVisualParamHint* exception2 ) { S32 delay_frames = 0; - for(LLVisualParamHint* instance = sInstances.getFirstData(); - instance; - instance = sInstances.getNextData()) + for (instance_list_t::iterator iter = sInstances.begin(); + iter != sInstances.end(); ++iter) { + LLVisualParamHint* instance = *iter; if( (instance != exception1) && (instance != exception2) ) { if( instance->mAllowsUpdates ) @@ -180,7 +181,7 @@ BOOL LLVisualParamHint::render() LLGLSUIDefault gls_ui; //LLGLState::verify(TRUE); LLViewerImage::bindTexture(mBackgroundp); - glColor4f(1.f, 1.f, 1.f, 1.f); + gGL.color4f(1.f, 1.f, 1.f, 1.f); gl_rect_2d_simple_tex( mWidth, mHeight ); mBackgroundp->unbindTexture(0, GL_TEXTURE_2D); @@ -227,6 +228,7 @@ BOOL LLVisualParamHint::render() mVisualParam->getCameraElevation() ); LLVector3 camera_pos = target_joint_pos + (camera_snapshot_offset * avatar_rotation); + gGL.stop(); gCamera->setAspect((F32)mWidth / (F32)mHeight); gCamera->setOriginAndLookAt( camera_pos, // camera @@ -242,7 +244,7 @@ BOOL LLVisualParamHint::render() avatarPoolp->renderAvatars(avatarp); // renders only one avatar } avatarp->setVisualParamWeight(mVisualParam, mLastParamWeight); - + gGL.start(); return TRUE; } @@ -256,21 +258,21 @@ void LLVisualParamHint::draw() bindTexture(); - glColor4f(1.f, 1.f, 1.f, 1.f); + gGL.color4f(1.f, 1.f, 1.f, 1.f); LLGLSUIDefault gls_ui; - glBegin(GL_QUADS); + gGL.begin(GL_QUADS); { - glTexCoord2i(0, 1); - glVertex2i(0, mHeight); - glTexCoord2i(0, 0); - glVertex2i(0, 0); - glTexCoord2i(1, 0); - glVertex2i(mWidth, 0); - glTexCoord2i(1, 1); - glVertex2i(mWidth, mHeight); + gGL.texCoord2i(0, 1); + gGL.vertex2i(0, mHeight); + gGL.texCoord2i(0, 0); + gGL.vertex2i(0, 0); + gGL.texCoord2i(1, 0); + gGL.vertex2i(mWidth, 0); + gGL.texCoord2i(1, 1); + gGL.vertex2i(mWidth, mHeight); } - glEnd(); + gGL.end(); LLImageGL::unbindTexture(0, GL_TEXTURE_2D); } diff --git a/linden/indra/newview/lltoolmorph.h b/linden/indra/newview/lltoolmorph.h index 9f9a88b..b8f56d3 100644 --- a/linden/indra/newview/lltoolmorph.h +++ b/linden/indra/newview/lltoolmorph.h @@ -35,7 +35,6 @@ #include "lltool.h" #include "m4math.h" #include "v2math.h" -#include "linked_lists.h" #include "lldynamictexture.h" #include "llundo.h" #include "lltextbox.h" @@ -93,8 +92,9 @@ protected: F32 mLastParamWeight; LLPointer mBackgroundp; - - static LLLinkedList sInstances; + + typedef std::set instance_list_t; + static instance_list_t sInstances; }; // this class resets avatar data at the end of an update cycle diff --git a/linden/indra/newview/lltoolpie.cpp b/linden/indra/newview/lltoolpie.cpp index f41fa8f..ab60c67 100644 --- a/linden/indra/newview/lltoolpie.cpp +++ b/linden/indra/newview/lltoolpie.cpp @@ -35,6 +35,7 @@ #include "indra_constants.h" #include "llclickaction.h" +#include "llmediabase.h" // for status codes #include "llparcel.h" #include "llagent.h" @@ -54,25 +55,33 @@ #include "lltoolmgr.h" #include "lltoolselect.h" #include "llviewercamera.h" +#include "llviewerparcelmedia.h" #include "llviewermenu.h" -#include "llviewerobject.h" #include "llviewerobjectlist.h" +#include "llviewerobject.h" #include "llviewerparcelmgr.h" #include "llviewerwindow.h" +#include "llviewermedia.h" #include "llvoavatar.h" #include "llworld.h" #include "llui.h" +#include "llweb.h" LLToolPie *gToolPie = NULL; LLPointer LLToolPie::sClickActionObject; -LLHandle LLToolPie::sLeftClickSelection = NULL; +LLSafeHandle LLToolPie::sLeftClickSelection = NULL; U8 LLToolPie::sClickAction = 0; extern void handle_buy(void*); extern BOOL gDebugClicks; +static void handle_click_action_play(); +static void handle_click_action_open_media(LLPointer objectp); +static ECursorType cursor_from_parcel_media(U8 click_action); + + LLToolPie::LLToolPie() : LLTool("Select"), mPieMouseButtonDown( FALSE ), @@ -87,6 +96,7 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask) { if (!gCamera) return FALSE; + gPickFaces = TRUE; //left mouse down always picks transparent gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, leftMouseCallback, TRUE, TRUE); @@ -137,7 +147,7 @@ BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show) else { // not selling passes, get info - LLFloaterLand::show(); + LLFloaterLand::showInstance(); } } @@ -211,6 +221,13 @@ BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show) sLeftClickSelection = LLToolSelect::handleObjectSelection(parent, MASK_NONE, FALSE, TRUE); } return TRUE; + case CLICK_ACTION_PLAY: + handle_click_action_play(); + return TRUE; + case CLICK_ACTION_OPEN_MEDIA: + // sClickActionObject = object; + handle_click_action_open_media(object); + return TRUE; } } @@ -411,6 +428,47 @@ U8 final_click_action(LLViewerObject* obj) return click_action; } +ECursorType cursor_from_object(LLViewerObject* object) +{ + LLViewerObject* parent = NULL; + if (object) + { + parent = object->getRootEdit(); + } + U8 click_action = final_click_action(object); + ECursorType cursor = UI_CURSOR_ARROW; + switch(click_action) + { + case CLICK_ACTION_SIT: + cursor = UI_CURSOR_TOOLSIT; + break; + case CLICK_ACTION_BUY: + cursor = UI_CURSOR_TOOLBUY; + break; + case CLICK_ACTION_OPEN: + // Open always opens the parent. + if (parent && parent->allowOpen()) + { + cursor = UI_CURSOR_TOOLOPEN; + } + break; + case CLICK_ACTION_PAY: + if ((object && object->flagTakesMoney()) + || (parent && parent->flagTakesMoney())) + { + cursor = UI_CURSOR_TOOLPAY; + } + break; + case CLICK_ACTION_PLAY: + case CLICK_ACTION_OPEN_MEDIA: + cursor = cursor_from_parcel_media(click_action); + break; + default: + break; + } + return cursor; +} + // When we get object properties after left-clicking on an object // with left-click = buy, if it's the same object, do the buy. // static @@ -486,28 +544,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) if (object && useClickAction(FALSE, mask, object, parent)) { - U8 click_action = final_click_action(object); - ECursorType cursor = UI_CURSOR_ARROW; - switch(click_action) - { - default: break; - case CLICK_ACTION_SIT: cursor = UI_CURSOR_TOOLSIT; break; - case CLICK_ACTION_BUY: cursor = UI_CURSOR_TOOLBUY; break; - case CLICK_ACTION_OPEN: - // Open always opens the parent. - if (parent && parent->allowOpen()) - { - cursor = UI_CURSOR_TOOLOPEN; - } - break; - case CLICK_ACTION_PAY: - if ((object && object->flagTakesMoney()) - || (parent && parent->flagTakesMoney())) - { - cursor = UI_CURSOR_TOOLPAY; - } - break; - } + ECursorType cursor = cursor_from_object(object); gViewerWindow->getWindow()->setCursor(cursor); lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; } @@ -677,4 +714,95 @@ void LLToolPie::render() return; } +static void handle_click_action_play() +{ + LLParcel* parcel = gParcelMgr->getAgentParcel(); + if (!parcel) return; + + LLMediaBase::EStatus status = LLViewerParcelMedia::getStatus(); + switch(status) + { + case LLMediaBase::STATUS_STARTED: + LLViewerParcelMedia::pause(); + break; + + case LLMediaBase::STATUS_PAUSED: + LLViewerParcelMedia::start(); + break; + + default: + LLViewerParcelMedia::play(parcel); + break; + } +} + +static void handle_click_action_open_media(LLPointer objectp) +{ + //FIXME: how do we handle object in different parcel than us? + LLParcel* parcel = gParcelMgr->getAgentParcel(); + if (!parcel) return; + + // did we hit an object? + if (objectp.isNull()) return; + + // did we hit a valid face on the object? + if( gLastHitObjectFace < 0 || gLastHitObjectFace >= objectp->getNumTEs() ) return; + + // is media playing on this face? + if (!LLViewerMedia::isActiveMediaTexture(objectp->getTE(gLastHitObjectFace)->getID())) + { + handle_click_action_play(); + return; + } + + std::string media_url = std::string ( parcel->getMediaURL () ); + std::string media_type = std::string ( parcel->getMediaType() ); + LLString::trim(media_url); + + // Get the scheme, see if that is handled as well. + LLURI uri(media_url); + std::string media_scheme = uri.scheme() != "" ? uri.scheme() : "http"; + + // HACK: This is directly referencing an impl name. BAD! + // This can be removed when we have a truly generic media browser that only + // builds an impl based on the type of url it is passed. + if( LLMediaManager::getInstance()->supportsMediaType( "LLMediaImplLLMozLib", media_scheme, media_type ) ) + { + LLWeb::loadURL(media_url); + } +} + +static ECursorType cursor_from_parcel_media(U8 click_action) +{ + // HACK: This is directly referencing an impl name. BAD! + // This can be removed when we have a truly generic media browser that only + // builds an impl based on the type of url it is passed. + + //FIXME: how do we handle object in different parcel than us? + ECursorType open_cursor = UI_CURSOR_ARROW; + LLParcel* parcel = gParcelMgr->getAgentParcel(); + if (!parcel) return open_cursor; + + std::string media_url = std::string ( parcel->getMediaURL () ); + std::string media_type = std::string ( parcel->getMediaType() ); + LLString::trim(media_url); + + // Get the scheme, see if that is handled as well. + LLURI uri(media_url); + std::string media_scheme = uri.scheme() != "" ? uri.scheme() : "http"; + + if( LLMediaManager::getInstance()->supportsMediaType( "LLMediaImplLLMozLib", media_scheme, media_type ) ) + { + open_cursor = UI_CURSOR_TOOLMEDIAOPEN; + } + + LLMediaBase::EStatus status = LLViewerParcelMedia::getStatus(); + switch(status) + { + case LLMediaBase::STATUS_STARTED: + return click_action == CLICK_ACTION_PLAY ? UI_CURSOR_TOOLPAUSE : open_cursor; + default: + return UI_CURSOR_TOOLPLAY; + } +} diff --git a/linden/indra/newview/lltoolpie.h b/linden/indra/newview/lltoolpie.h index c2d41a0..37ca5ea 100644 --- a/linden/indra/newview/lltoolpie.h +++ b/linden/indra/newview/lltoolpie.h @@ -78,7 +78,7 @@ protected: BOOL mMouseOutsideSlop; // for this drag, has mouse moved outside slop region static LLPointer sClickActionObject; static U8 sClickAction; - static LLHandle sLeftClickSelection; + static LLSafeHandle sLeftClickSelection; }; extern LLToolPie *gToolPie; diff --git a/linden/indra/newview/lltoolselect.cpp b/linden/indra/newview/lltoolselect.cpp index 33eb776..4371cbe 100644 --- a/linden/indra/newview/lltoolselect.cpp +++ b/linden/indra/newview/lltoolselect.cpp @@ -96,7 +96,7 @@ BOOL LLToolSelect::handleDoubleClick(S32 x, S32 y, MASK mask) } // static -LLHandle LLToolSelect::handleObjectSelection(LLViewerObject *object, MASK mask, BOOL ignore_group, BOOL temp_select) +LLSafeHandle LLToolSelect::handleObjectSelection(LLViewerObject *object, MASK mask, BOOL ignore_group, BOOL temp_select) { BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly"); BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly"); @@ -275,3 +275,4 @@ void LLToolSelect::onMouseCaptureLost() } + diff --git a/linden/indra/newview/lltoolselect.h b/linden/indra/newview/lltoolselect.h index 3ae0274..d9cb04b 100644 --- a/linden/indra/newview/lltoolselect.h +++ b/linden/indra/newview/lltoolselect.h @@ -49,7 +49,7 @@ public: virtual void stopEditing(); - static LLHandle handleObjectSelection(LLViewerObject *object, MASK mask, BOOL ignore_group, BOOL temp_select); + static LLSafeHandle handleObjectSelection(LLViewerObject *object, MASK mask, BOOL ignore_group, BOOL temp_select); virtual void onMouseCaptureLost(); virtual void handleDeselect(); diff --git a/linden/indra/newview/lltoolselectland.h b/linden/indra/newview/lltoolselectland.h index a5b0b11..dafec66 100644 --- a/linden/indra/newview/lltoolselectland.h +++ b/linden/indra/newview/lltoolselectland.h @@ -75,7 +75,7 @@ protected: LLVector3d mEastNorthTop; // global coords, from drag BOOL mLastShowParcelOwners; // store last Show Parcel Owners setting - LLHandle mSelection; // hold on to a parcel selection + LLSafeHandle mSelection; // hold on to a parcel selection }; extern LLToolSelectLand *gToolParcel; diff --git a/linden/indra/newview/lltoolselectrect.cpp b/linden/indra/newview/lltoolselectrect.cpp index 3b74770..6adca35 100644 --- a/linden/indra/newview/lltoolselectrect.cpp +++ b/linden/indra/newview/lltoolselectrect.cpp @@ -36,6 +36,7 @@ // Library includes #include "llgl.h" +#include "llglimmediate.h" #include "lldarray.h" // Viewer includes @@ -160,11 +161,11 @@ void LLToolSelectRect::draw() { if (gKeyboard->currentMask(TRUE) == MASK_CONTROL) { - glColor4f(1.f, 0.f, 0.f, 1.f); + gGL.color4f(1.f, 0.f, 0.f, 1.f); } else { - glColor4f(1.f, 1.f, 0.f, 1.f); + gGL.color4f(1.f, 1.f, 0.f, 1.f); } LLGLSNoTexture gls_no_texture; gl_rect_2d( @@ -175,11 +176,11 @@ void LLToolSelectRect::draw() FALSE); if (gKeyboard->currentMask(TRUE) == MASK_CONTROL) { - glColor4f(1.f, 0.f, 0.f, 0.1f); + gGL.color4f(1.f, 0.f, 0.f, 0.1f); } else { - glColor4f(1.f, 1.f, 0.f, 0.1f); + gGL.color4f(1.f, 1.f, 0.f, 0.1f); } gl_rect_2d( llmin(mDragStartX, mDragEndX), diff --git a/linden/indra/newview/lltoolview.cpp b/linden/indra/newview/lltoolview.cpp index 8aed5f8..ebdbcbb 100644 --- a/linden/indra/newview/lltoolview.cpp +++ b/linden/indra/newview/lltoolview.cpp @@ -72,7 +72,8 @@ LLToolView::LLToolView(const std::string& name, const LLRect& rect) LLToolView::~LLToolView() { - mContainList.deleteAllData(); + for_each(mContainList.begin(), mContainList.end(), DeletePointer()); + mContainList.clear(); } //*TODO:translate? @@ -118,7 +119,7 @@ void LLToolView::addTool(const LLString& icon_off, const LLString& icon_on, LLPa addChild(contain->mPanel); } - mContainList.addData(contain); + mContainList.push_back(contain); } @@ -130,7 +131,7 @@ LLRect LLToolView::getButtonRect(S32 button_index) const S32 HORIZ_SPACING = TOOL_SIZE + 5; const S32 VERT_SPACING = TOOL_SIZE + 14; - S32 tools_per_row = mRect.getWidth() / HORIZ_SPACING; + S32 tools_per_row = getRect().getWidth() / HORIZ_SPACING; S32 row = button_index / tools_per_row; S32 column = button_index % tools_per_row; @@ -153,11 +154,10 @@ void LLToolView::draw() // turn off highlighting for all containers // and hide all option panels except for the selected one. LLTool* selected = gToolMgr->getCurrentToolset()->getSelectedTool(); - for( LLToolContainer* contain = mContainList.getFirstData(); - contain != NULL; - contain = mContainList.getNextData() - ) + for (contain_list_t::iterator iter = mContainList.begin(); + iter != mContainList.end(); ++iter) { + LLToolContainer* contain = *iter; BOOL state = (contain->mTool == selected); contain->mButton->setToggleState( state ); if (contain->mPanel) @@ -175,8 +175,10 @@ LLToolContainer* LLToolView::findToolContainer( LLTool *tool ) { // Find the container for this tool llassert( tool ); - for( LLToolContainer* contain = mContainList.getFirstData(); contain; contain = mContainList.getNextData() ) + for (contain_list_t::iterator iter = mContainList.begin(); + iter != mContainList.end(); ++iter) { + LLToolContainer* contain = *iter; if( contain->mTool == tool ) { return contain; @@ -196,3 +198,4 @@ void LLToolView::onClickToolButton(void* userdata) } + diff --git a/linden/indra/newview/lltoolview.h b/linden/indra/newview/lltoolview.h index 22d6807..8c955a3 100644 --- a/linden/indra/newview/lltoolview.h +++ b/linden/indra/newview/lltoolview.h @@ -33,7 +33,6 @@ #define LL_LLTOOLVIEW_H // requires stdtypes.h -#include "linked_lists.h" #include "llpanel.h" // forward declares @@ -84,8 +83,8 @@ private: private: - LLLinkedList - mContainList; + typedef std::vector contain_list_t; + contain_list_t mContainList; S32 mButtonCount; // used to compute rectangles }; diff --git a/linden/indra/newview/lltracker.cpp b/linden/indra/newview/lltracker.cpp index 6dfc700..c1c060c 100644 --- a/linden/indra/newview/lltracker.cpp +++ b/linden/indra/newview/lltracker.cpp @@ -36,6 +36,7 @@ #include "lldarray.h" #include "llfontgl.h" #include "llgl.h" +#include "llglimmediate.h" #include "llinventory.h" #include "llmemory.h" #include "llstring.h" @@ -50,7 +51,6 @@ #include "llagent.h" #include "llcallingcard.h" #include "llcolorscheme.h" -#include "llcylinder.h" #include "llfloaterworldmap.h" #include "llhudtext.h" #include "llhudview.h" @@ -448,24 +448,24 @@ void draw_shockwave(F32 center_z, F32 t, S32 steps, LLColor4 color) F32 y = 0.f; LLColor4 ccol = LLColor4(1,1,1,(1.f-t)*0.25f); - glBegin(GL_TRIANGLE_FAN); - glColor4fv(ccol.mV); - glVertex3f(0.f, 0.f, center_z); + gGL.begin(GL_TRIANGLE_FAN); + gGL.color4fv(ccol.mV); + gGL.vertex3f(0.f, 0.f, center_z); // make sure circle is complete steps += 1; color.mV[3] = (1.f-t*t); - glColor4fv(color.mV); + gGL.color4fv(color.mV); while( steps-- ) { // Successive rotations - glVertex3f( x, y, center_z ); + gGL.vertex3f( x, y, center_z ); F32 x_new = x * cos_delta - y * sin_delta; y = x * sin_delta + y * cos_delta; x = x_new; } - glEnd(); + gGL.end(); } @@ -508,8 +508,7 @@ void LLTracker::renderBeacon(LLVector3d pos_global, draw_shockwave(1024.f, gRenderStartTime.getElapsedTimeF32(), 32, fogged_color); - //glScalef(1.f, 1.f, 1000.f); - glColor4fv(fogged_color.mV); + gGL.color4fv(fogged_color.mV); const U32 BEACON_VERTS = 256; const F32 step = 1024.0f/BEACON_VERTS; @@ -539,23 +538,23 @@ void LLTracker::renderBeacon(LLVector3d pos_global, an *= 2.f; an += 1.0f+dr; - glBegin(GL_TRIANGLE_STRIP); - glColor4fv(col_edge.mV); - glVertex3f(-x*a, -y*a, z); - glColor4fv(col_edge_next.mV); - glVertex3f(-x*an, -y*an, z_next); + gGL.begin(GL_TRIANGLE_STRIP); + gGL.color4fv(col_edge.mV); + gGL.vertex3f(-x*a, -y*a, z); + gGL.color4fv(col_edge_next.mV); + gGL.vertex3f(-x*an, -y*an, z_next); - glColor4fv(c_col.mV); - glVertex3f(0, 0, z); - glColor4fv(col_next.mV); - glVertex3f(0, 0, z_next); + gGL.color4fv(c_col.mV); + gGL.vertex3f(0, 0, z); + gGL.color4fv(col_next.mV); + gGL.vertex3f(0, 0, z_next); - glColor4fv(col_edge.mV); - glVertex3f(x*a,y*a,z); - glColor4fv(col_edge_next.mV); - glVertex3f(x*an,y*an,z_next); + gGL.color4fv(col_edge.mV); + gGL.vertex3f(x*a,y*a,z); + gGL.color4fv(col_edge_next.mV); + gGL.vertex3f(x*an,y*an,z_next); - glEnd(); + gGL.end(); } //gCylinder.render(1000); diff --git a/linden/indra/newview/lluploaddialog.cpp b/linden/indra/newview/lluploaddialog.cpp index fc58721..14128ee 100644 --- a/linden/indra/newview/lluploaddialog.cpp +++ b/linden/indra/newview/lluploaddialog.cpp @@ -78,7 +78,7 @@ LLUploadDialog::LLUploadDialog( const std::string& msg) LLRect msg_rect; for (int line_num=0; line_num<16; ++line_num) { - mLabelBox[line_num] = new LLTextBox( "Filename", msg_rect, "", font ); + mLabelBox[line_num] = new LLTextBox( "Filename", msg_rect, "Filename", font ); addChild(mLabelBox[line_num]); } @@ -100,7 +100,7 @@ void LLUploadDialog::setMessage( const std::string& msg) // Split message into lines, separated by '\n' S32 max_msg_width = 0; - LLDoubleLinkedList msg_lines; + std::list msg_lines; S32 size = msg.size() + 1;// + strlen("Uploading...\n\n"); char* temp_msg = new char[size]; @@ -118,7 +118,7 @@ void LLUploadDialog::setMessage( const std::string& msg) { S32 cur_width = S32(font->getWidth(token) + 0.99f) + TEXT_PAD; max_msg_width = llmax( max_msg_width, cur_width ); - msg_lines.addDataAtEnd( new LLString( token ) ); + msg_lines.push_back( std::string( token ) ); token = strtok( NULL, "\n" ); } delete[] temp_msg; @@ -126,33 +126,34 @@ void LLUploadDialog::setMessage( const std::string& msg) S32 line_height = S32( font->getLineHeight() + 0.99f ); S32 dialog_width = max_msg_width + 2 * HPAD; - S32 dialog_height = line_height * msg_lines.getLength() + 2 * VPAD; + S32 dialog_height = line_height * msg_lines.size() + 2 * VPAD; reshape( dialog_width, dialog_height, FALSE ); // Message - S32 msg_x = (mRect.getWidth() - max_msg_width) / 2; - S32 msg_y = mRect.getHeight() - VPAD - line_height; + S32 msg_x = (getRect().getWidth() - max_msg_width) / 2; + S32 msg_y = getRect().getHeight() - VPAD - line_height; int line_num; for (line_num=0; line_num<16; ++line_num) { mLabelBox[line_num]->setVisible(FALSE); } line_num = 0; - for( LLString* cur_line = msg_lines.getFirstData(); cur_line; cur_line = msg_lines.getNextData() ) + for (std::list::iterator iter = msg_lines.begin(); + iter != msg_lines.end(); ++iter) { + std::string& cur_line = *iter; LLRect msg_rect; msg_rect.setOriginAndSize( msg_x, msg_y, max_msg_width, line_height ); mLabelBox[line_num]->setRect(msg_rect); - mLabelBox[line_num]->setText(*cur_line); + mLabelBox[line_num]->setText(cur_line); mLabelBox[line_num]->setColor( gColors.getColor( "LabelTextColor" ) ); mLabelBox[line_num]->setVisible(TRUE); msg_y -= line_height; ++line_num; } - msg_lines.deleteAllData(); - centerDialog(); + centerWithin(gViewerWindow->getRootView()->getRect()); } LLUploadDialog::~LLUploadDialog() @@ -165,13 +166,5 @@ LLUploadDialog::~LLUploadDialog() LLUploadDialog::sDialog = NULL; } -void LLUploadDialog::centerDialog() -{ - LLRect window_rect = gViewerWindow->getRootView()->getRect(); - - S32 dialog_left = window_rect.mLeft + (window_rect.getWidth() - mRect.getWidth()) / 2; - S32 dialog_bottom = window_rect.mBottom + (window_rect.getHeight() - mRect.getHeight()) / 2; - translate( dialog_left - mRect.mLeft, dialog_bottom - mRect.mBottom ); -} diff --git a/linden/indra/newview/lluploaddialog.h b/linden/indra/newview/lluploaddialog.h index 02cb0be..130eff5 100644 --- a/linden/indra/newview/lluploaddialog.h +++ b/linden/indra/newview/lluploaddialog.h @@ -50,8 +50,6 @@ private: LLUploadDialog( const std::string& msg); virtual ~LLUploadDialog(); // No you can't kill it. It can only kill itself. - void centerDialog(); - LLTextBox* mLabelBox[16]; private: diff --git a/linden/indra/newview/llurldispatcher.cpp b/linden/indra/newview/llurldispatcher.cpp index 78b305c..6c1514c 100644 --- a/linden/indra/newview/llurldispatcher.cpp +++ b/linden/indra/newview/llurldispatcher.cpp @@ -39,6 +39,7 @@ #include "llfloaterdirectory.h" #include "llfloaterhtml.h" #include "llfloaterworldmap.h" +#include "llfloaterhtmlhelp.h" #include "llpanellogin.h" #include "llstartup.h" // gStartupState #include "llurlsimstring.h" @@ -159,9 +160,7 @@ bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, BOOL right_mouse) { if (matchPrefix(url, SLURL_SL_HELP_PREFIX)) { -#if LL_LIBXUL_ENABLED gViewerHtmlHelp.show(); -#endif // LL_LIBXUL_ENABLED return true; } return false; diff --git a/linden/indra/newview/llurlhistory.cpp b/linden/indra/newview/llurlhistory.cpp new file mode 100644 index 0000000..da69df6 --- /dev/null +++ b/linden/indra/newview/llurlhistory.cpp @@ -0,0 +1,137 @@ +/** + * @file llurlhistory.cpp + * @brief Manages a list of recent URLs + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llurlhistory.h" + +#include "lldir.h" +#include "llsdserialize.h" + +LLSD LLURLHistory::sHistorySD; + +const int MAX_URL_COUNT = 10; + +///////////////////////////////////////////////////////////////////////////// + +// static +bool LLURLHistory::loadFile(const LLString& filename) +{ + LLSD data; + { + LLString temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter(); + + llifstream file((temp_str + filename).c_str()); + + if (file.is_open()) + { + llinfos << "Loading history.xml file at " << filename << llendl; + LLSDSerialize::fromXML(data, file); + } + + if (data.isUndefined()) + { + llinfos << "file missing, ill-formed, " + "or simply undefined; not changing the" + " file" << llendl; + sHistorySD = LLSD(); + return false; + } + } + sHistorySD = data; + return true; +} + +// static +bool LLURLHistory::saveFile(const LLString& filename) +{ + LLString temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter(); + llofstream out((temp_str + filename).c_str()); + if (!out.good()) + { + llwarns << "Unable to open " << filename << " for output." << llendl; + return false; + } + + LLSDSerialize::toXML(sHistorySD, out); + + out.close(); + return true; +} +// static +// This function returns a portion of the history llsd that contains the collected +// url history +LLSD LLURLHistory::getURLHistory(const std::string& collection) +{ + if(sHistorySD.has(collection)) + { + return sHistorySD[collection]; + } + return LLSD(); +} + +// static +void LLURLHistory::addURL(const std::string& collection, const std::string& url) +{ + if(! url.empty()) + { + sHistorySD[collection].insert(0, url); + LLURLHistory::limitSize(collection); + } +} +// static +void LLURLHistory::removeURL(const std::string& collection, const std::string& url) +{ + LLSD::array_iterator iter = sHistorySD[collection].beginArray(); + LLSD::array_iterator end = sHistorySD[collection].endArray(); + for(int index = 0; index < sHistorySD[collection].size(); index++) + { + if(sHistorySD[collection].get(index).asString() == url) + { + sHistorySD[collection].erase(index); + } + } +} + +// static +void LLURLHistory::clear(const std::string& collection) +{ + sHistorySD[ collection ] = LLSD(); +} + +void LLURLHistory::limitSize(const std::string& collection) +{ + while(sHistorySD[collection].size() > MAX_URL_COUNT) + { + sHistorySD[collection].erase(MAX_URL_COUNT); + } +} + diff --git a/linden/indra/newview/llurlhistory.h b/linden/indra/newview/llurlhistory.h new file mode 100644 index 0000000..05d81b1 --- /dev/null +++ b/linden/indra/newview/llurlhistory.h @@ -0,0 +1,60 @@ +/** + * @file llurlhistory.h + * @brief Manages a list of recent URLs + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLURLHISTORY_H +#define LLURLHISTORY_H + +#include "llstring.h" + +class LLSD; + +class LLURLHistory +{ +public: + // Loads an xml file of URLs. Currently only supports Parcel URL history + static bool loadFile(const LLString& filename); + + // Saves the current history to XML + static bool saveFile(const LLString& filename); + + static LLSD getURLHistory(const std::string& collection); + + static void addURL(const std::string& collection, const std::string& url); + static void removeURL(const std::string& collection, const std::string& url); + static void clear(const std::string& collection); + + static void limitSize(const std::string& collection); + +private: + static LLSD sHistorySD; +}; + +#endif // LLURLHISTORY_H diff --git a/linden/indra/newview/llvelocitybar.cpp b/linden/indra/newview/llvelocitybar.cpp index c5c4b5c..5073aea 100644 --- a/linden/indra/newview/llvelocitybar.cpp +++ b/linden/indra/newview/llvelocitybar.cpp @@ -81,8 +81,8 @@ void LLVelocityBar::draw() LLGLSNoTexture gls_no_texture; // draw background box - // glColor4f(0.f, 0.f, 0.f, 0.3f); - // gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0); + // gGL.color4f(0.f, 0.f, 0.f, 0.3f); + // gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0); // draw white lines for special times // (60 hz = 16 ms, 30 hz = 33 ms, 15 hz = 66 ms) @@ -95,33 +95,32 @@ void LLVelocityBar::draw() right = left + TICK_WIDTH; gl_rect_2d(left, top, right, bottom, color); - left = (S32) (mRect.getWidth() * 1 / 6); + left = (S32) (getRect().getWidth() * 1 / 6); right = left + TICK_WIDTH; gl_rect_2d(left, top, right, bottom, color); - left = (S32) (mRect.getWidth() * 2 / 6); + left = (S32) (getRect().getWidth() * 2 / 6); right = left + TICK_WIDTH; gl_rect_2d(left, top, right, bottom, color); - left = (S32) (mRect.getWidth() * 3 / 6); + left = (S32) (getRect().getWidth() * 3 / 6); right = left + TICK_WIDTH; gl_rect_2d(left, top, right, bottom, color); - left = (S32) (mRect.getWidth() * 4 / 6); + left = (S32) (getRect().getWidth() * 4 / 6); right = left + TICK_WIDTH; gl_rect_2d(left, top, right, bottom, color); - left = (S32) (mRect.getWidth() * 5 / 6); + left = (S32) (getRect().getWidth() * 5 / 6); right = left + TICK_WIDTH; gl_rect_2d(left, top, right, bottom, color); - left = (S32) (mRect.getWidth() * 6 / 6); + left = (S32) (getRect().getWidth() * 6 / 6); right = left + TICK_WIDTH; gl_rect_2d(left, top, right, bottom, color); // draw labels for the bar - LLGLSTexture gls_texture; top = BAR_TOP + 15; left = 0; @@ -134,22 +133,22 @@ void LLVelocityBar::draw() left = - MAGIC_CHAR_WIDTH/2; LLFontGL::sMonospace->renderUTF8("0", 0, left, top, color, LLFontGL::LEFT, LLFontGL::TOP); - left = (mRect.getWidth()*1 / 6) - MAGIC_CHAR_WIDTH * 2; + left = (getRect().getWidth()*1 / 6) - MAGIC_CHAR_WIDTH * 2; LLFontGL::sMonospace->renderUTF8("1", 0, left, top, color, LLFontGL::LEFT, LLFontGL::TOP); - left = (mRect.getWidth()*2 / 6) - MAGIC_CHAR_WIDTH; + left = (getRect().getWidth()*2 / 6) - MAGIC_CHAR_WIDTH; LLFontGL::sMonospace->renderUTF8("2", 0, left, top, color, LLFontGL::LEFT, LLFontGL::TOP); - left = (mRect.getWidth()*3 / 6) - MAGIC_CHAR_WIDTH * 2; + left = (getRect().getWidth()*3 / 6) - MAGIC_CHAR_WIDTH * 2; LLFontGL::sMonospace->renderUTF8("3", 0, left, top, color, LLFontGL::LEFT, LLFontGL::TOP); - left = (mRect.getWidth()*4 / 6) - MAGIC_CHAR_WIDTH; + left = (getRect().getWidth()*4 / 6) - MAGIC_CHAR_WIDTH; LLFontGL::sMonospace->renderUTF8("4", 0, left, top, color, LLFontGL::LEFT, LLFontGL::TOP); - left = (mRect.getWidth()*5 / 6) - MAGIC_CHAR_WIDTH * 2; + left = (getRect().getWidth()*5 / 6) - MAGIC_CHAR_WIDTH * 2; LLFontGL::sMonospace->renderUTF8("5", 0, left, top, color, LLFontGL::LEFT, LLFontGL::TOP); - left = (mRect.getWidth()*6 / 6) - MAGIC_CHAR_WIDTH * 3; + left = (getRect().getWidth()*6 / 6) - MAGIC_CHAR_WIDTH * 3; LLFontGL::sMonospace->renderUTF8("6 m/s", 0, left, top, color, LLFontGL::LEFT, LLFontGL::TOP); // draw idle time @@ -158,6 +157,6 @@ void LLVelocityBar::draw() // Draw energy level left = 0; - right = (S32) (left + velocity * 0.33333f * mRect.getWidth() / 2.f); + right = (S32) (left + velocity * 0.33333f * getRect().getWidth() / 2.f); gl_rect_2d(left, top, right, bottom, bar_color); } diff --git a/linden/indra/newview/llviewerassetstorage.cpp b/linden/indra/newview/llviewerassetstorage.cpp index 00d9db2..d9d497a 100644 --- a/linden/indra/newview/llviewerassetstorage.cpp +++ b/linden/indra/newview/llviewerassetstorage.cpp @@ -87,6 +87,8 @@ void LLViewerAssetStorage::storeAssetData( { // This can happen if there's a bug in our code or if the VFS has been corrupted. llwarns << "LLViewerAssetStorage::storeAssetData() Data _should_ already be in the VFS, but it's not! " << asset_id << llendl; + // LLAssetStorage metric: Zero size VFS + reportMetric( asset_id, asset_type, NULL, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" ); delete req; if (callback) @@ -95,13 +97,21 @@ void LLViewerAssetStorage::storeAssetData( } return; } - else if(is_priority) - { - mPendingUploads.push_front(req); - } else { - mPendingUploads.push_back(req); + // LLAssetStorage metric: Successful Request + S32 size = mVFS->getSize(asset_id, asset_type); + const char *message = "Added to upload queue"; + reportMetric( asset_id, asset_type, NULL, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message ); + + if(is_priority) + { + mPendingUploads.push_front(req); + } + else + { + mPendingUploads.push_back(req); + } } // Read the data from the VFS if it'll fit in this packet. @@ -118,6 +128,10 @@ void LLViewerAssetStorage::storeAssetData( else { llwarns << "Probable corruption in VFS file, aborting store asset data" << llendl; + + // LLAssetStorage metric: VFS corrupt - bogus size + reportMetric( asset_id, asset_type, NULL, LLUUID::null, asset_size, MR_VFS_CORRUPTION, __FILE__, __LINE__, "VFS corruption" ); + if (callback) { callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT); @@ -143,6 +157,8 @@ void LLViewerAssetStorage::storeAssetData( else { llwarns << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl; + // LLAssetStorage metric: Zero size VFS + reportMetric( asset_id, asset_type, NULL, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" ); if (callback) { callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE); @@ -152,6 +168,8 @@ void LLViewerAssetStorage::storeAssetData( else { llwarns << "Attempt to move asset store request upstream w/o valid upstream provider" << llendl; + // LLAssetStorage metric: Upstream provider dead + reportMetric( asset_id, asset_type, NULL, LLUUID::null, 0, MR_NO_UPSTREAM, __FILE__, __LINE__, "No upstream provider" ); if (callback) { callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); @@ -170,8 +188,10 @@ void LLViewerAssetStorage::storeAssetData( bool user_waiting, F64 timeout) { - if(!filename) +if(!filename) { + // LLAssetStorage metric: no filename + reportMetric( LLUUID::null, asset_type, "", LLUUID::null, 0, MR_VFS_CORRUPTION, __FILE__, __LINE__, "Filename missing" ); llerrs << "No filename specified" << llendl; return; } @@ -181,9 +201,16 @@ void LLViewerAssetStorage::storeAssetData( llinfos << "ASSET_ID: " << asset_id << llendl; + S32 size = 0; FILE* fp = LLFile::fopen(filename, "rb"); if (fp) { + fseek(fp, 0, SEEK_END); + size = ftell(fp); + fseek(fp, 0, SEEK_SET); + } + if( size ) + { LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest; legacy->mUpCallback = callback; @@ -191,10 +218,6 @@ void LLViewerAssetStorage::storeAssetData( LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE); - fseek(fp, 0, SEEK_END); - S32 size = ftell(fp); - fseek(fp, 0, SEEK_SET); - file.setMaxSize(size); const S32 buf_size = 65536; @@ -210,7 +233,9 @@ void LLViewerAssetStorage::storeAssetData( { LLFile::remove(filename); } - + + // LLAssetStorage metric: Success not needed; handled in the overloaded method here: + LLViewerAssetStorage::storeAssetData( tid, asset_type, @@ -219,8 +244,18 @@ void LLViewerAssetStorage::storeAssetData( temp_file, is_priority); } - else + else // size == 0 (but previous block changes size) { + if( fp ) + { + // LLAssetStorage metric: Zero size + reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file was zero length" ); + } + else + { + // LLAssetStorage metric: Missing File + reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_FILE_NONEXIST, __FILE__, __LINE__, "The file didn't exist" ); + } if (callback) { callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE); diff --git a/linden/indra/newview/llvieweraudio.cpp b/linden/indra/newview/llvieweraudio.cpp index 58ce7a7..499673f 100644 --- a/linden/indra/newview/llvieweraudio.cpp +++ b/linden/indra/newview/llvieweraudio.cpp @@ -35,12 +35,12 @@ #include "audiosettings.h" #include "llagent.h" #include "llappviewer.h" -#include "llmediaengine.h" #include "llvieweraudio.h" #include "llviewercamera.h" #include "llviewercontrol.h" #include "llviewerwindow.h" #include "llvoiceclient.h" +#include "llviewermedia.h" ///////////////////////////////////////////////////////// @@ -153,13 +153,10 @@ void audio_update_volume(bool force_update) } // Streaming Media - if(LLMediaEngine::getInstance()) - { - F32 media_volume = gSavedSettings.getF32("AudioLevelMedia"); - media_volume = mute_volume * master_volume * (media_volume*media_volume); - BOOL media_muted = gSavedSettings.getBOOL("MuteMedia"); - LLMediaEngine::getInstance()->setVolume(media_muted ? 0.f : media_volume); - } + F32 media_volume = gSavedSettings.getF32("AudioLevelMedia"); + BOOL media_muted = gSavedSettings.getBOOL("MuteMedia"); + media_volume = mute_volume * master_volume * (media_volume*media_volume); + LLViewerMedia::setVolume( media_muted ? 0.0f : media_volume ); // Voice if (gVoiceClient) diff --git a/linden/indra/newview/llviewercamera.cpp b/linden/indra/newview/llviewercamera.cpp index 0a8e8c2..7c4271a 100644 --- a/linden/indra/newview/llviewercamera.cpp +++ b/linden/indra/newview/llviewercamera.cpp @@ -48,16 +48,46 @@ #include "llvovolume.h" #include "llworld.h" +GLfloat gGLZFar; +GLfloat gGLZNear; + LLViewerCamera *gCamera = NULL; +//glu pick matrix implementation borrowed from Mesa3D +glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLint* viewport) +{ + GLfloat m[16]; + GLfloat sx, sy; + GLfloat tx, ty; + + sx = viewport[2] / width; + sy = viewport[3] / height; + tx = (viewport[2] + 2.f * (viewport[0] - x)) / width; + ty = (viewport[3] + 2.f * (viewport[1] - y)) / height; + + #define M(row,col) m[col*4+row] + M(0,0) = sx; M(0,1) = 0.f; M(0,2) = 0.f; M(0,3) = tx; + M(1,0) = 0.f; M(1,1) = sy; M(1,2) = 0.f; M(1,3) = ty; + M(2,0) = 0.f; M(2,1) = 0.f; M(2,2) = 1.f; M(2,3) = 0.f; + M(3,0) = 0.f; M(3,1) = 0.f; M(3,2) = 0.f; M(3,3) = 1.f; + #undef M + + return glh::matrix4f(m); +} + +glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) +{ + GLfloat f = 1.f/tanf(DEG_TO_RAD*fovy/2.f); + + return glh::matrix4f(f/aspect, 0, 0, 0, + 0, f, 0, 0, + 0, 0, (zFar+zNear)/(zNear-zFar), (2.f*zFar*zNear)/(zNear-zFar), + 0, 0, -1.f, 0); +} + LLViewerCamera::LLViewerCamera() : LLCamera() { calcProjection(getFar()); - S32 i; - for (i = 0; i < 16; i++) - { - mGLProjectionMatrix[i] = 0.f; - } mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW; mPixelMeterRatio = 0.f; mScreenPixelArea = 0; @@ -79,7 +109,20 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, // constrain to max distance from avatar LLVector3 camera_offset = center - gAgent.getPositionAgent(); - setOriginAndLookAt(center, up_direction, point_of_interest); + LLViewerRegion * regp = gAgent.getRegion(); + F32 water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f; + + LLVector3 origin = center; + if (origin.mV[2] > water_height) + { + origin.mV[2] = llmax(origin.mV[2], water_height+0.20f); + } + else + { + origin.mV[2] = llmin(origin.mV[2], water_height-0.20f); + } + + setOriginAndLookAt(origin, up_direction, point_of_interest); F32 dpos = (center - last_position).magVec(); LLQuaternion rotation; @@ -98,6 +141,7 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, // Handy copies of last good GL matrices F64 gGLModelView[16]; +F64 gGLLastModelView[16]; F64 gGLProjection[16]; S32 gGLViewport[4]; @@ -139,46 +183,70 @@ void LLViewerCamera::calcProjection(const F32 far_distance) const // The picking region is centered on x,y and has the specified width and // height. -LLMatrix4 gProjectionMat; - //static -void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho) +void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zflip) { - GLint viewport[4]; - GLdouble model[16]; - GLdouble proj[16]; + GLint* viewport = (GLint*) gGLViewport; + GLdouble* model = gGLModelView; + GLdouble* proj = gGLProjection; GLdouble objX,objY,objZ; LLVector3 frust[8]; - glGetIntegerv(GL_VIEWPORT, viewport); - glGetDoublev(GL_MODELVIEW_MATRIX, model); - glGetDoublev(GL_PROJECTION_MATRIX,proj); - - gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); - frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); - gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); - frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); - - if (ortho) + if (zflip) { - LLVector3 far_shift = LLVector3(camera.getFar()*2.0f,0,0); + gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); + frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); + frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); + frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); + frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); + + gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); + frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); + frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); + frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); + frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); + for (U32 i = 0; i < 4; i++) { - frust[i+4] = frust[i] + far_shift; + frust[i+4] = frust[i+4]-frust[i]; + frust[i+4].normVec(); + frust[i+4] = frust[i] + frust[i+4]*camera.getFar(); } } else { - for (U32 i = 0; i < 4; i++) + gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); + frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); + frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); + frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); + frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); + + if (ortho) { - LLVector3 vec = frust[i] - camera.getOrigin(); - vec.normVec(); - frust[i+4] = camera.getOrigin() + vec*camera.getFar()*2.0f; + LLVector3 far_shift = LLVector3(camera.getFar()*2.0f,0,0); + for (U32 i = 0; i < 4; i++) + { + frust[i+4] = frust[i] + far_shift; + } + } + else + { + for (U32 i = 0; i < 4; i++) + { + LLVector3 vec = frust[i] - camera.getOrigin(); + vec.normVec(); + frust[i+4] = camera.getOrigin() + vec*camera.getFar(); + } } } @@ -209,14 +277,15 @@ void LLViewerCamera::setPerspective(BOOL for_selection, glMatrixMode( GL_PROJECTION ); glLoadIdentity(); + glh::matrix4f proj_mat; + if (for_selection) { // make a tiny little viewport // anything drawn into this viewport will be "selected" - const U8 VIEWPORT_VECTOR_LEN = 4; - GLint viewport[VIEWPORT_VECTOR_LEN]; - glGetIntegerv(GL_VIEWPORT, viewport); - gluPickMatrix(x + width / 2, y_from_bot + height / 2, width, height, viewport); + GLint* viewport = (GLint*) gGLViewport; + + proj_mat = gl_pick_matrix(x+width/2.f, y_from_bot+height/2.f, (GLfloat) width, (GLfloat) height, viewport); if (limit_select_distance) { @@ -236,6 +305,10 @@ void LLViewerCamera::setPerspective(BOOL for_selection, z_far = MAX_FAR_CLIP; } glViewport(x, y_from_bot, width, height); + gGLViewport[0] = x; + gGLViewport[1] = y_from_bot; + gGLViewport[2] = width; + gGLViewport[3] = height; } if (mZoomFactor > 1.f) @@ -243,27 +316,41 @@ void LLViewerCamera::setPerspective(BOOL for_selection, float offset = mZoomFactor - 1.f; int pos_y = mZoomSubregion / llceil(mZoomFactor); int pos_x = mZoomSubregion - (pos_y*llceil(mZoomFactor)); - glTranslatef(offset - (F32)pos_x * 2.f, offset - (F32)pos_y * 2.f, 0.f); - glScalef(mZoomFactor, mZoomFactor, 1.f); + glh::matrix4f translate; + translate.set_translate(glh::vec3f(offset - (F32)pos_x * 2.f, offset - (F32)pos_y * 2.f, 0.f)); + glh::matrix4f scale; + scale.set_scale(glh::vec3f(mZoomFactor, mZoomFactor, 1.f)); + + proj_mat = scale*proj_mat; + proj_mat = translate*proj_mat; } calcProjection(z_far); // Update the projection matrix cache - gluPerspective(fov_y, - aspect, - z_near, - z_far); - glGetDoublev(GL_PROJECTION_MATRIX, gGLProjection); - glGetFloatv(GL_PROJECTION_MATRIX, (float*)&gProjectionMat); - + proj_mat *= gl_perspective(fov_y,aspect,z_near,z_far); + + glLoadMatrixf(proj_mat.m); + + for (U32 i = 0; i < 16; i++) + { + gGLProjection[i] = proj_mat.m[i]; + } + + gGLZNear = z_near; + gGLZFar = z_far; + glMatrixMode( GL_MODELVIEW ); - glLoadMatrixf(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame + glh::matrix4f modelview((GLfloat*) OGL_TO_CFR_ROTATION); GLfloat ogl_matrix[16]; + getOpenGLTransform(ogl_matrix); - glMultMatrixf(ogl_matrix); + modelview *= glh::matrix4f(ogl_matrix); + + glLoadMatrixf(modelview.m); + if (for_selection && (width > 1 || height > 1)) { calculateFrustumPlanesFromWindow((F32)(x - width / 2) / (F32)gViewerWindow->getWindowWidth() - 0.5f, @@ -277,9 +364,11 @@ void LLViewerCamera::setPerspective(BOOL for_selection, if (!for_selection && mZoomFactor == 1.f) { // Save GL matrices for access elsewhere in code, especially project_world_to_screen - glGetDoublev(GL_PROJECTION_MATRIX, mGLProjectionMatrix); - glGetDoublev(GL_MODELVIEW_MATRIX, gGLModelView); - glGetIntegerv(GL_VIEWPORT, (GLint*)gGLViewport); + //glGetDoublev(GL_MODELVIEW_MATRIX, gGLModelView); + for (U32 i = 0; i < 16; i++) + { + gGLModelView[i] = modelview.m[i]; + } } updateFrustumPlanes(*this); @@ -302,7 +391,7 @@ void LLViewerCamera::projectScreenToPosAgent(const S32 screen_x, const S32 scree GLdouble x, y, z; gluUnProject( GLdouble(screen_x), GLdouble(screen_y), 0.0, - gGLModelView, mGLProjectionMatrix, (GLint*)gGLViewport, + gGLModelView, gGLProjection, (GLint*)gGLViewport, &x, &y, &z ); @@ -333,7 +422,7 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord } if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ], - gGLModelView, mGLProjectionMatrix, (GLint*)gGLViewport, + gGLModelView, gGLProjection, (GLint*)gGLViewport, &x, &y, &z)) { // convert screen coordinates to virtual UI coordinates @@ -431,7 +520,7 @@ BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent, GLdouble x, y, z; // object's window coords, GL-style if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ], gGLModelView, - mGLProjectionMatrix, (GLint*)gGLViewport, + gGLProjection, (GLint*)gGLViewport, &x, &y, &z)) { x /= gViewerWindow->getDisplayScale().mV[VX]; diff --git a/linden/indra/newview/llviewercamera.h b/linden/indra/newview/llviewercamera.h index 2fed21a..df89c19 100644 --- a/linden/indra/newview/llviewercamera.h +++ b/linden/indra/newview/llviewercamera.h @@ -62,7 +62,7 @@ public: const LLVector3 &up_direction, const LLVector3 &point_of_interest); - static void updateFrustumPlanes(LLCamera& camera, BOOL ortho = FALSE); + static void updateFrustumPlanes(LLCamera& camera, BOOL ortho = FALSE, BOOL zflip = FALSE); void setPerspective(BOOL for_selection, S32 x, S32 y_from_bot, S32 width, S32 height, BOOL limit_select_distance, F32 z_near = 0, F32 z_far = 0); const LLMatrix4 &getProjection() const; @@ -109,13 +109,14 @@ protected: S16 mZoomSubregion; public: - F64 mGLProjectionMatrix[16]; - }; extern LLViewerCamera *gCamera; extern F64 gGLModelView[16]; +extern F64 gGLLastModelView[16]; extern F64 gGLProjection[16]; extern S32 gGLViewport[4]; +extern F32 gGLZNear; +extern F32 gGLZFar; #endif // LL_LLVIEWERCAMERA_H diff --git a/linden/indra/newview/llviewercontrol.cpp b/linden/indra/newview/llviewercontrol.cpp index 99bc98a..3a82c05 100644 --- a/linden/indra/newview/llviewercontrol.cpp +++ b/linden/indra/newview/llviewercontrol.cpp @@ -114,13 +114,13 @@ BOOL LLFloaterSettingsDebug::postBuild() childSetCommitCallback("color_swatch", onCommitSettings); childSetUserData("color_swatch", this); childSetAction("default_btn", onClickDefault, this); - mComment = (LLTextEditor*)getChildByName("comment_text"); + mComment = getChild("comment_text"); return TRUE; } void LLFloaterSettingsDebug::draw() { - LLComboBox* settings_combo = (LLComboBox*)getChildByName("settings_combo"); + LLComboBox* settings_combo = getChild("settings_combo"); LLControlBase* controlp = (LLControlBase*)settings_combo->getCurrentUserdata(); updateControl(controlp); @@ -155,7 +155,7 @@ void LLFloaterSettingsDebug::onCommitSettings(LLUICtrl* ctrl, void* user_data) { LLFloaterSettingsDebug* floaterp = (LLFloaterSettingsDebug*)user_data; - LLComboBox* settings_combo = (LLComboBox*)floaterp->getChildByName("settings_combo"); + LLComboBox* settings_combo = floaterp->getChild("settings_combo"); LLControlBase* controlp = (LLControlBase*)settings_combo->getCurrentUserdata(); LLVector3 vector; @@ -229,7 +229,7 @@ void LLFloaterSettingsDebug::onCommitSettings(LLUICtrl* ctrl, void* user_data) void LLFloaterSettingsDebug::onClickDefault(void* user_data) { LLFloaterSettingsDebug* floaterp = (LLFloaterSettingsDebug*)user_data; - LLComboBox* settings_combo = (LLComboBox*)floaterp->getChildByName("settings_combo"); + LLComboBox* settings_combo = floaterp->getChild("settings_combo"); LLControlBase* controlp = (LLControlBase*)settings_combo->getCurrentUserdata(); if (controlp) @@ -246,7 +246,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) LLSpinCtrl* spinner2 = LLUICtrlFactory::getSpinnerByName(this, "val_spinner_2"); LLSpinCtrl* spinner3 = LLUICtrlFactory::getSpinnerByName(this, "val_spinner_3"); LLSpinCtrl* spinner4 = LLUICtrlFactory::getSpinnerByName(this, "val_spinner_4"); - LLColorSwatchCtrl* color_swatch = LLUICtrlFactory::getColorSwatchByName(this, "color_swatch"); + LLColorSwatchCtrl* color_swatch = getChild("color_swatch"); if (!spinner1 || !spinner2 || !spinner3 || !spinner4 || !color_swatch) { diff --git a/linden/indra/newview/llviewercontrol.h b/linden/indra/newview/llviewercontrol.h index e031053..bcea8db 100644 --- a/linden/indra/newview/llviewercontrol.h +++ b/linden/indra/newview/llviewercontrol.h @@ -70,6 +70,9 @@ void declare_settings(); void fixup_settings(); void settings_setup_listeners(); +// for the graphics settings +void create_graphics_group(LLControlGroup& group); + // saved at end of session extern LLControlGroup gSavedSettings; extern LLControlGroup gSavedPerAccountSettings; diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp index e85b275..1e4958b 100644 --- a/linden/indra/newview/llviewerdisplay.cpp +++ b/linden/indra/newview/llviewerdisplay.cpp @@ -31,6 +31,11 @@ #include "llviewerprecompiledheaders.h" +#include "llviewerdisplay.h" + +#include "llgl.h" +#include "llglimmediate.h" +#include "llglheaders.h" #include "llagent.h" #include "llviewercontrol.h" #include "llcoord.h" @@ -40,8 +45,6 @@ #include "lldrawpoolalpha.h" #include "llfeaturemanager.h" #include "llframestats.h" -#include "llgl.h" -#include "llglheaders.h" #include "llhudmanager.h" #include "llimagebmp.h" #include "llimagegl.h" @@ -62,6 +65,7 @@ #include "llvograss.h" #include "llworld.h" #include "pipeline.h" +#include "llspatialpartition.h" #include "llappviewer.h" #include "llstartup.h" #include "llfasttimer.h" @@ -71,6 +75,9 @@ #include "llcubemap.h" #include "llviewerregion.h" #include "lldrawpoolwater.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" +#include "llpostprocess.h" extern LLPointer gStartImageGL; extern BOOL gDisplaySwapBuffers; @@ -87,15 +94,19 @@ const F32 RESTORE_GL_TIME = 5.f; // Wait this long while reloading textures bef BOOL gForceRenderLandFence = FALSE; BOOL gDisplaySwapBuffers = FALSE; +BOOL gResizeScreenTexture = FALSE; +BOOL gSnapshot = FALSE; // Rendering stuff void pre_show_depth_buffer(); void post_show_depth_buffer(); void render_ui_and_swap(); +void render_ui_and_swap_if_needed(); +void render_hud_attachments(); void render_ui_3d(); void render_ui_2d(); void render_disconnected_background(); - +void render_hud_elements(); void process_keystrokes_async(); void display_startup() @@ -108,22 +119,43 @@ void display_startup() return; } + LLGLSDefault gls_default; + // Required for HTML update in login screen static S32 frame_count = 0; +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); +#endif + if (frame_count++ > 1) // make sure we have rendered a frame first { LLDynamicTexture::updateAllInstances(); } + +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); +#endif + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - LLGLSDefault gls_default; LLGLSUIDefault gls_ui; gPipeline.disableLights(); gViewerWindow->setup2DRender(); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + gGL.start(); gViewerWindow->draw(); + gGL.stop(); + +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); +#endif + gViewerWindow->mWindow->swapBuffers(); + glClear(GL_DEPTH_BUFFER_BIT); } @@ -141,6 +173,10 @@ void display_update_camera() } gCamera->setFar(final_far); gViewerWindow->setup3DRender(); + + // update all the sky/atmospheric/water settings + LLWLParamManager::instance()->update(gCamera); + LLWaterParamManager::instance()->update(gCamera); // Update land visibility too if (gWorldp) @@ -151,15 +187,24 @@ void display_update_camera() // Paint the display! -void display(BOOL rebuild, F32 zoom_factor, int subfield) +void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLFastTimer t(LLFastTimer::FTM_RENDER); + if (LLPipeline::sRenderFrameTest) + { + send_agent_pause(); + } + + gSnapshot = for_snapshot; + LLGLSDefault gls_default; LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL); // No clue where this is getting unset, but safe enough to reset it here. - LLGLState::resetTextureStates(); + //this causes frame stalls, try real hard not to uncomment this line - DaveP + //LLGLState::resetTextureStates(); + #ifndef LL_RELEASE_FOR_DOWNLOAD LLGLState::checkStates(); @@ -167,7 +212,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) #endif gPipeline.disableLights(); - + // Don't draw if the window is hidden or minimized. // In fact, must explicitly check the minimized state before drawing. // Attempting to draw into a minimized window causes a GL error. JC @@ -185,7 +230,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) } gViewerWindow->checkSettings(); + gViewerWindow->performPick(); + #ifndef LL_RELEASE_FOR_DOWNLOAD LLGLState::checkStates(); @@ -235,7 +282,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) stop_glerror(); LLImageGL::updateStats(gFrameTimeSeconds); - + LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName"); LLVOAvatar::sRenderGroupTitles = gSavedSettings.getBOOL("RenderGroupTitleAll"); gPipeline.mBackfaceCull = TRUE; @@ -369,18 +416,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) // Prepare for the next frame // - // Hmm... Should this be moved elsewhere? - djs 09/09/02 - // do render-to-texture stuff here - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) - { -// LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES); - if (LLDynamicTexture::updateAllInstances()) - { - glClear(GL_COLOR_BUFFER_BIT); - } - } - - ///////////////////////////// // // Update the camera @@ -398,18 +433,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) if (gDisconnected) { - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + render_ui_and_swap_if_needed(); + gDisplaySwapBuffers = TRUE; + render_disconnected_background(); } - else if (!gViewerWindow->isPickPending()) - { - glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); - //DEBUG TEMPORARY - glClear(GL_COLOR_BUFFER_BIT); - } - gViewerWindow->setupViewport(); - - + ////////////////////////// // // Set rendering options @@ -421,18 +450,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) pre_show_depth_buffer(); } - if(gUseWireframe)//gSavedSettings.getBOOL("UseWireframe")) - { - glClearColor(0.5f, 0.5f, 0.5f, 0.f); - glClear(GL_COLOR_BUFFER_BIT); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - LLPipeline::sUseOcclusion = FALSE; - } - else - { - LLPipeline::sUseOcclusion = gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery && gFeatureManagerp->isFeatureAvailable("UseOcclusion"); - } - stop_glerror(); /////////////////////////////////////// @@ -444,16 +461,27 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) F32 one[4] = {1.f, 1.f, 1.f, 1.f}; glLightModelfv (GL_LIGHT_MODEL_AMBIENT,one); stop_glerror(); - - //Increment drawable frame counter - LLDrawable::incrementVisible(); - + ///////////////////////////////////// // // Render // // Actually push all of our triangles to the screen. // + + // do render-to-texture stuff here + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) + { + LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES); + if (LLDynamicTexture::updateAllInstances()) + { + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + } + + gViewerWindow->setupViewport(); + if (!gDisconnected) { if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) @@ -461,30 +489,106 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); } - LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE); + //upkeep gl name pools + LLGLNamePool::upkeepPools(); + stop_glerror(); display_update_camera(); stop_glerror(); - + // *TODO: merge these two methods gHUDManager->updateEffects(); LLHUDObject::updateAll(); stop_glerror(); gFrameStats.start(LLFrameStats::UPDATE_GEOM); - const F32 max_geom_update_time = 0.005f; // 5 ms update time + const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time gPipeline.updateGeom(max_geom_update_time); stop_glerror(); - LLSpatialPartition* part = gPipeline.getSpatialPartition(LLPipeline::PARTITION_VOLUME); - part->processImagery(gCamera); + gFrameStats.start(LLFrameStats::UPDATE_CULL); + S32 water_clip = 0; + if (LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_ENVIRONMENT) > 1) + { + if (gCamera->cameraUnderWater()) + { + water_clip = -1; + } + else + { + water_clip = 1; + } + } - display_update_camera(); + //Increment drawable frame counter + LLDrawable::incrementVisible(); + + LLPipeline::sUseOcclusion = + (!gUseWireframe + && gFeatureManagerp->isFeatureAvailable("UseOcclusion") + && gSavedSettings.getBOOL("UseOcclusion") + && gGLManager.mHasOcclusionQuery) ? 2 : 0; + LLPipeline::sFastAlpha = gSavedSettings.getBOOL("RenderFastAlpha"); + LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); + LLVOAvatar::sMaxVisible = gSavedSettings.getS32("RenderAvatarMaxVisible"); + + S32 occlusion = LLPipeline::sUseOcclusion; + if (!gDisplaySwapBuffers) + { //depth buffer is invalid, don't overwrite occlusion state + LLPipeline::sUseOcclusion = llmin(occlusion, 1); + } - gFrameStats.start(LLFrameStats::UPDATE_CULL); - gPipeline.updateCull(*gCamera); + static LLCullResult result; + gPipeline.updateCull(*gCamera, result, water_clip); stop_glerror(); - + + BOOL to_texture = !for_snapshot && + gPipeline.canUseVertexShaders() && + LLPipeline::sRenderGlow && + gGLManager.mHasFramebufferObject; + + // now do the swap buffer (just before rendering to framebuffer) + { //swap and flush state from previous frame + { + LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY); + LLVertexBuffer::clientCopy(0.016); + } + + if (gResizeScreenTexture) + { + gResizeScreenTexture = FALSE; + gPipeline.resizeScreenTexture(); + } + + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + glClearColor(0,0,0,0); + + if (!for_snapshot) + { + render_ui_and_swap_if_needed(); + gDisplaySwapBuffers = TRUE; + + glh::matrix4f proj = glh_get_current_projection(); + glh::matrix4f mod = glh_get_current_modelview(); + glViewport(0,0,128,256); + LLVOAvatar::updateImpostors(); + glh_set_current_projection(proj); + glh_set_current_modelview(mod); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(proj.m); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(mod.m); + gViewerWindow->setupViewport(); + } + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + } + + if (!for_snapshot) + { + gPipeline.processImagery(*gCamera); + gPipeline.generateWaterReflection(*gCamera); + } + /////////////////////////////////// // // StateSort @@ -494,10 +598,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) // Also creates special lists for outlines and selected face rendering. // { - LLFastTimer t(LLFastTimer::FTM_REBUILD); - gFrameStats.start(LLFrameStats::STATE_SORT); - gPipeline.stateSort(*gCamera); + gPipeline.stateSort(*gCamera, result); stop_glerror(); if (rebuild) @@ -512,67 +614,133 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) stop_glerror(); } } + + LLPipeline::sUseOcclusion = occlusion; + + { + LLFastTimer t(LLFastTimer::FTM_UPDATE_SKY); + gSky.updateSky(); + } + + if(gUseWireframe) + { + glClearColor(0.5f, 0.5f, 0.5f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } + + //// render frontmost floater opaque for occlusion culling purposes + //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost(); + //// assumes frontmost floater with focus is opaque + //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp)) + //{ + // glMatrixMode(GL_MODELVIEW); + // glPushMatrix(); + // { + // LLGLSNoTexture gls_no_texture; + + // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + // glLoadIdentity(); + + // LLRect floater_rect = frontmost_floaterp->getScreenRect(); + // // deflate by one pixel so rounding errors don't occlude outside of floater extents + // floater_rect.stretch(-1); + // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidth(), + // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeight(), + // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidth(), + // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeight()); + // floater_3d_rect.translate(-0.5f, -0.5f); + // glTranslatef(0.f, 0.f, -gCamera->getNear()); + // glScalef(gCamera->getNear() * gCamera->getAspect() / sinf(gCamera->getView()), gCamera->getNear() / sinf(gCamera->getView()), 1.f); + // gGL.color4fv(LLColor4::white.mV); + // gGL.begin(GL_QUADS); + // { + // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f); + // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f); + // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f); + // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f); + // } + // gGL.end(); + // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + // } + // glPopMatrix(); + //} + + if (to_texture) + { + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + gPipeline.mScreen.bindTarget(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + } + + if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) + && !gRestoreGL) + { + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + LLPipeline::sUnderWaterRender = gCamera->cameraUnderWater() ? TRUE : FALSE; + gPipeline.renderGeom(*gCamera, TRUE); + LLPipeline::sUnderWaterRender = FALSE; + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + //store this frame's modelview matrix for use + //when rendering next frame's occlusion queries + for (U32 i = 0; i < 16; i++) + { + gGLLastModelView[i] = gGLModelView[i]; + } + stop_glerror(); + } + + render_hud_attachments(); + + if (to_texture) + { + gPipeline.mScreen.flush(); + } + + /// We copy the frame buffer straight into a texture here, + /// and then display it again with compositor effects. + /// Using render to texture would be faster/better, but I don't have a + /// grasp of their full display stack just yet. + // gPostProcess->apply(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); } + gFrameStats.start(LLFrameStats::RENDER_UI); - //// render frontmost floater opaque for occlusion culling purposes - //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost(); - //// assumes frontmost floater with focus is opaque - //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp)) - //{ - // glMatrixMode(GL_MODELVIEW); - // glPushMatrix(); - // { - // LLGLSNoTexture gls_no_texture; - - // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - // glLoadIdentity(); - - // LLRect floater_rect = frontmost_floaterp->getScreenRect(); - // // deflate by one pixel so rounding errors don't occlude outside of floater extents - // floater_rect.stretch(-1); - // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidth(), - // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeight(), - // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidth(), - // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeight()); - // floater_3d_rect.translate(-0.5f, -0.5f); - // glTranslatef(0.f, 0.f, -gCamera->getNear()); - // glScalef(gCamera->getNear() * gCamera->getAspect() / sinf(gCamera->getView()), gCamera->getNear() / sinf(gCamera->getView()), 1.f); - // glColor4fv(LLColor4::white.mV); - // glBegin(GL_QUADS); - // { - // glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f); - // glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f); - // glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f); - // glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f); - // } - // glEnd(); - // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - // } - // glPopMatrix(); - //} - - if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) - && !gRestoreGL - && !gDisconnected) + if (gHandleKeysAsync) { - gPipeline.renderGeom(*gCamera); + process_keystrokes_async(); stop_glerror(); } - //render hud attachments + gFrameStats.start(LLFrameStats::MISC_END); + stop_glerror(); + + if (LLPipeline::sRenderFrameTest) + { + send_agent_resume(); + LLPipeline::sRenderFrameTest = FALSE; + } +} + +void render_hud_attachments() +{ glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); - + + glh::matrix4f current_proj = glh_get_current_projection(); + glh::matrix4f current_mod = glh_get_current_modelview(); + if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices(FALSE)) { LLCamera hud_cam = *gCamera; - glClear(GL_DEPTH_BUFFER_BIT); LLVector3 origin = hud_cam.getOrigin(); hud_cam.setOrigin(-1.f,0,0); hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1)); LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE); + //only render hud objects U32 mask = gPipeline.getRenderTypeMask(); gPipeline.setRenderTypeMask(0); @@ -584,22 +752,22 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); } - BOOL use_occlusion = gSavedSettings.getBOOL("UseOcclusion"); - gSavedSettings.setBOOL("UseOcclusion", FALSE); + S32 use_occlusion = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = 0; + LLPipeline::sDisableShaders = TRUE; //cull, sort, and render hud objects - gPipeline.updateCull(hud_cam); + static LLCullResult result; + gPipeline.updateCull(hud_cam, result); - gPipeline.toggleRenderType(LLDrawPool::POOL_ALPHA_POST_WATER); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_GLOW); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA); - { - LLFastTimer ftm(LLFastTimer::FTM_REBUILD); - gPipeline.stateSort(hud_cam); - } - + gPipeline.stateSort(hud_cam, result); + gPipeline.renderGeom(hud_cam); //restore type mask @@ -608,33 +776,16 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield) { gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); } - gSavedSettings.setBOOL("UseOcclusion", use_occlusion); + LLPipeline::sUseOcclusion = use_occlusion; + LLPipeline::sDisableShaders = FALSE; } glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); - - gFrameStats.start(LLFrameStats::RENDER_UI); - - if (gHandleKeysAsync) - { - process_keystrokes_async(); - stop_glerror(); - } - -#ifndef LL_RELEASE_FOR_DOWNLOAD - LLGLState::checkStates(); -#endif - render_ui_and_swap(); -#ifndef LL_RELEASE_FOR_DOWNLOAD - LLGLState::checkStates(); -#endif - - gFrameStats.start(LLFrameStats::MISC_END); - stop_glerror(); - + glh_set_current_projection(current_proj); + glh_set_current_modelview(current_mod); } BOOL setup_hud_matrices(BOOL for_select) @@ -654,22 +805,22 @@ BOOL setup_hud_matrices(BOOL for_select) // clear z buffer and set up transform for hud if (!for_select) { - glClear(GL_DEPTH_BUFFER_BIT); + //glClear(GL_DEPTH_BUFFER_BIT); } LLBBox hud_bbox = my_avatarp->getHUDBBox(); // set up transform to encompass bounding box of HUD glMatrixMode(GL_PROJECTION); - glLoadIdentity(); F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); if (for_select) { //RN: reset viewport to window extents so ortho screen is calculated with proper reference frame gViewerWindow->setupViewport(); } - glOrtho(-0.5f * gCamera->getAspect(), 0.5f * gCamera->getAspect(), -0.5f, 0.5f, 0.f, hud_depth); - + glh::matrix4f proj = gl_ortho(-0.5f * gCamera->getAspect(), 0.5f * gCamera->getAspect(), -0.5f, 0.5f, 0.f, hud_depth); + proj.element(2,2) = -0.01f; + // apply camera zoom transform (for high res screenshots) F32 zoom_factor = gCamera->getZoomFactor(); S16 sub_region = gCamera->getZoomSubRegion(); @@ -678,16 +829,26 @@ BOOL setup_hud_matrices(BOOL for_select) float offset = zoom_factor - 1.f; int pos_y = sub_region / llceil(zoom_factor); int pos_x = sub_region - (pos_y*llceil(zoom_factor)); - glTranslatef(gCamera->getAspect() * 0.5f * (offset - (F32)pos_x * 2.f), 0.5f * (offset - (F32)pos_y * 2.f), 0.f); - glScalef(zoom_factor, zoom_factor, 1.f); + glh::matrix4f mat; + mat.set_scale(glh::vec3f(zoom_factor, zoom_factor, 1.f)); + mat.set_translate(glh::vec3f(gCamera->getAspect() * 0.5f * (offset - (F32)pos_x * 2.f), 0.5f * (offset - (F32)pos_y * 2.f), 0.f)); + proj *= mat; } + glLoadMatrixf(proj.m); + glh_set_current_projection(proj); + glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glLoadMatrixf(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame - glTranslatef(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f); - glScalef(zoom_level, zoom_level, zoom_level); + glh::matrix4f model((GLfloat*) OGL_TO_CFR_ROTATION); + glh::matrix4f mat; + mat.set_translate(glh::vec3f(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f)); + mat.set_scale(glh::vec3f(zoom_level, zoom_level, zoom_level)); + + model *= mat; + glLoadMatrixf(model.m); + glh_set_current_modelview(model); + return TRUE; } else @@ -702,15 +863,31 @@ void render_ui_and_swap() #ifndef LL_RELEASE_FOR_DOWNLOAD LLGLState::checkStates(); #endif + + { + BOOL to_texture = gPipeline.canUseVertexShaders() && + LLPipeline::sRenderGlow && + gGLManager.mHasFramebufferObject; + + if (to_texture) + { + gPipeline.renderBloom(gSnapshot); + } + } LLGLSDefault gls_default; + LLGLSUIDefault gls_ui; { - LLGLSUIDefault gls_ui; gPipeline.disableLights(); + } + + { LLVertexBuffer::startRender(); + gGL.start(); if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { LLFastTimer t(LLFastTimer::FTM_RENDER_UI); + if (!gDisconnected) { render_ui_3d(); @@ -724,71 +901,78 @@ void render_ui_and_swap() LLGLState::checkStates(); #endif } - LLVertexBuffer::stopRender(); - glFlush(); + gGL.stop(); - // now do the swap buffer - if (gDisplaySwapBuffers) { - LLFastTimer t(LLFastTimer::FTM_SWAP); - gViewerWindow->mWindow->swapBuffers(); + gViewerWindow->setup2DRender(); + gViewerWindow->updateDebugText(); + gViewerWindow->drawDebugText(); } + LLVertexBuffer::stopRender(); + } +} + +void render_ui_and_swap_if_needed() +{ + if (gDisplaySwapBuffers) + { + render_ui_and_swap(); + { - LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY); - LLVertexBuffer::clientCopy(0.016); + LLFastTimer t(LLFastTimer::FTM_SWAP); + gViewerWindow->mWindow->swapBuffers(); } - } } void renderCoordinateAxes() { LLGLSNoTexture gls_no_texture; - glBegin(GL_LINES); - glColor3f(1.0f, 0.0f, 0.0f); // i direction = X-Axis = red - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f(2.0f, 0.0f, 0.0f); - glVertex3f(3.0f, 0.0f, 0.0f); - glVertex3f(5.0f, 0.0f, 0.0f); - glVertex3f(6.0f, 0.0f, 0.0f); - glVertex3f(8.0f, 0.0f, 0.0f); + gGL.begin(GL_LINES); + gGL.color3f(1.0f, 0.0f, 0.0f); // i direction = X-Axis = red + gGL.vertex3f(0.0f, 0.0f, 0.0f); + gGL.vertex3f(2.0f, 0.0f, 0.0f); + gGL.vertex3f(3.0f, 0.0f, 0.0f); + gGL.vertex3f(5.0f, 0.0f, 0.0f); + gGL.vertex3f(6.0f, 0.0f, 0.0f); + gGL.vertex3f(8.0f, 0.0f, 0.0f); // Make an X - glVertex3f(11.0f, 1.0f, 1.0f); - glVertex3f(11.0f, -1.0f, -1.0f); - glVertex3f(11.0f, 1.0f, -1.0f); - glVertex3f(11.0f, -1.0f, 1.0f); - - glColor3f(0.0f, 1.0f, 0.0f); // j direction = Y-Axis = green - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f(0.0f, 2.0f, 0.0f); - glVertex3f(0.0f, 3.0f, 0.0f); - glVertex3f(0.0f, 5.0f, 0.0f); - glVertex3f(0.0f, 6.0f, 0.0f); - glVertex3f(0.0f, 8.0f, 0.0f); + gGL.vertex3f(11.0f, 1.0f, 1.0f); + gGL.vertex3f(11.0f, -1.0f, -1.0f); + gGL.vertex3f(11.0f, 1.0f, -1.0f); + gGL.vertex3f(11.0f, -1.0f, 1.0f); + + gGL.color3f(0.0f, 1.0f, 0.0f); // j direction = Y-Axis = green + gGL.vertex3f(0.0f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, 2.0f, 0.0f); + gGL.vertex3f(0.0f, 3.0f, 0.0f); + gGL.vertex3f(0.0f, 5.0f, 0.0f); + gGL.vertex3f(0.0f, 6.0f, 0.0f); + gGL.vertex3f(0.0f, 8.0f, 0.0f); // Make a Y - glVertex3f(1.0f, 11.0f, 1.0f); - glVertex3f(0.0f, 11.0f, 0.0f); - glVertex3f(-1.0f, 11.0f, 1.0f); - glVertex3f(0.0f, 11.0f, 0.0f); - glVertex3f(0.0f, 11.0f, 0.0f); - glVertex3f(0.0f, 11.0f, -1.0f); - - glColor3f(0.0f, 0.0f, 1.0f); // Z-Axis = blue - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f(0.0f, 0.0f, 2.0f); - glVertex3f(0.0f, 0.0f, 3.0f); - glVertex3f(0.0f, 0.0f, 5.0f); - glVertex3f(0.0f, 0.0f, 6.0f); - glVertex3f(0.0f, 0.0f, 8.0f); + gGL.vertex3f(1.0f, 11.0f, 1.0f); + gGL.vertex3f(0.0f, 11.0f, 0.0f); + gGL.vertex3f(-1.0f, 11.0f, 1.0f); + gGL.vertex3f(0.0f, 11.0f, 0.0f); + gGL.vertex3f(0.0f, 11.0f, 0.0f); + gGL.vertex3f(0.0f, 11.0f, -1.0f); + + gGL.color3f(0.0f, 0.0f, 1.0f); // Z-Axis = blue + gGL.vertex3f(0.0f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, 0.0f, 2.0f); + gGL.vertex3f(0.0f, 0.0f, 3.0f); + gGL.vertex3f(0.0f, 0.0f, 5.0f); + gGL.vertex3f(0.0f, 0.0f, 6.0f); + gGL.vertex3f(0.0f, 0.0f, 8.0f); // Make a Z - glVertex3f(-1.0f, 1.0f, 11.0f); - glVertex3f(1.0f, 1.0f, 11.0f); - glVertex3f(1.0f, 1.0f, 11.0f); - glVertex3f(-1.0f, -1.0f, 11.0f); - glVertex3f(-1.0f, -1.0f, 11.0f); - glVertex3f(1.0f, -1.0f, 11.0f); - glEnd(); + gGL.vertex3f(-1.0f, 1.0f, 11.0f); + gGL.vertex3f(1.0f, 1.0f, 11.0f); + gGL.vertex3f(1.0f, 1.0f, 11.0f); + gGL.vertex3f(-1.0f, -1.0f, 11.0f); + gGL.vertex3f(-1.0f, -1.0f, 11.0f); + gGL.vertex3f(1.0f, -1.0f, 11.0f); + gGL.end(); } @@ -798,11 +982,11 @@ void draw_axes() LLGLSNoTexture gls_no_texture; // A vertical white line at origin LLVector3 v = gAgent.getPositionAgent(); - glBegin(GL_LINES); - glColor3f(1.0f, 1.0f, 1.0f); - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f(0.0f, 0.0f, 40.0f); - glEnd(); + gGL.begin(GL_LINES); + gGL.color3f(1.0f, 1.0f, 1.0f); + gGL.vertex3f(0.0f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, 0.0f, 40.0f); + gGL.end(); // Some coordinate axes glPushMatrix(); glTranslatef( v.mV[VX], v.mV[VY], v.mV[VZ] ); @@ -822,9 +1006,9 @@ void render_ui_3d() // // Render selections - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); + //glDisableClientState(GL_COLOR_ARRAY); + //glDisableClientState(GL_TEXTURE_COORD_ARRAY); + //glDisableClientState(GL_NORMAL_ARRAY); ///////////////////////////////////////////////////////////// // @@ -891,7 +1075,7 @@ void render_ui_2d() glTranslatef((F32)half_width, (F32)half_height, 0.f); F32 zoom = gAgent.getAvatarObject()->mHUDCurZoom; glScalef(zoom,zoom,1.f); - glColor4fv(LLColor4::white.mV); + gGL.color4fv(LLColor4::white.mV); gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE); glPopMatrix(); stop_glerror(); @@ -909,6 +1093,7 @@ void render_ui_2d() void render_disconnected_background() { + gGL.start(); if (!gDisconnectedImagep && gDisconnected) { llinfos << "Loading last bitmap..." << llendl; @@ -951,7 +1136,7 @@ void render_disconnected_background() rawp++; } - + raw->expandToPowerOfTwo(); gDisconnectedImagep->createGLTexture(0, raw); gStartImageGL = gDisconnectedImagep; @@ -975,12 +1160,13 @@ void render_disconnected_background() glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f); LLViewerImage::bindTexture(gDisconnectedImagep); - glColor4f(1.f, 1.f, 1.f, 1.f); + gGL.color4f(1.f, 1.f, 1.f, 1.f); gl_rect_2d_simple_tex(width, height); LLImageGL::unbindTexture(0, GL_TEXTURE_2D); } glPopMatrix(); } + gGL.stop(); } void display_cleanup() diff --git a/linden/indra/newview/llviewerdisplay.h b/linden/indra/newview/llviewerdisplay.h index 16ad023..22c31b7 100644 --- a/linden/indra/newview/llviewerdisplay.h +++ b/linden/indra/newview/llviewerdisplay.h @@ -32,14 +32,17 @@ #ifndef LL_LLVIEWERDISPLAY_H #define LL_LLVIEWERDISPLAY_H +class LLPostProcess; + void display_startup(); void display_cleanup(); -void display(BOOL rebuild = TRUE, F32 zoom_factor = 1.f, int subfield = 0); +void display(BOOL rebuild = TRUE, F32 zoom_factor = 1.f, int subfield = 0, BOOL for_snapshot = FALSE); extern BOOL gDisplaySwapBuffers; extern BOOL gTeleportDisplay; extern LLFrameTimer gTeleportDisplayTimer; extern BOOL gForceRenderLandFence; +extern BOOL gResizeScreenTexture; #endif // LL_LLVIEWERDISPLAY_H diff --git a/linden/indra/newview/llviewerimage.cpp b/linden/indra/newview/llviewerimage.cpp index c771791..7cac905 100644 --- a/linden/indra/newview/llviewerimage.cpp +++ b/linden/indra/newview/llviewerimage.cpp @@ -188,6 +188,12 @@ void LLViewerImage::updateClass(const F32 velocity, const F32 angular_velocity) sDesiredDiscardBias = llclamp(sDesiredDiscardBias, sDesiredDiscardBiasMin, sDesiredDiscardBiasMax); } +// static +LLViewerImage* LLViewerImage::getImage(const LLUUID& image_id) +{ + return gImageList.getImage(image_id); +} + //---------------------------------------------------------------------------- const U32 LLViewerImage::sCurrentFileVersion = 1; @@ -417,7 +423,7 @@ void LLViewerImage::resetTextureStats(BOOL zero) mMaxVirtualSize = 0.0f; mMaxCosAngle = -1.0f; } - else + else if (getBoostLevel() != LLViewerImage::BOOST_SCULPTED) //don't decay sculpted prim textures { mMaxVirtualSize -= mMaxVirtualSize * .10f; // decay by 5%/update mMaxCosAngle = -1.0f; diff --git a/linden/indra/newview/llviewerimage.h b/linden/indra/newview/llviewerimage.h index 6a0e32f..732c773 100644 --- a/linden/indra/newview/llviewerimage.h +++ b/linden/indra/newview/llviewerimage.h @@ -82,6 +82,10 @@ public: static void initClass(); static void cleanupClass(); static void updateClass(const F32 velocity, const F32 angular_velocity); + + static LLViewerImage * getImage(const LLUUID &image_id); + // lightweight wrapper for gImageList.getImage() + static BOOL bindTexture(LLImageGL* image, const U32 stage = 0) { if (image) diff --git a/linden/indra/newview/llviewerimagelist.cpp b/linden/indra/newview/llviewerimagelist.cpp index 99ac3a7..0e29f76 100644 --- a/linden/indra/newview/llviewerimagelist.cpp +++ b/linden/indra/newview/llviewerimagelist.cpp @@ -31,9 +31,8 @@ #include "llviewerprecompiledheaders.h" -#include - #include "llviewerimagelist.h" + #include "imageids.h" #include "llgl.h" // fot gathering stats from GL #include "llimagegl.h" @@ -42,7 +41,6 @@ #include "llimagetga.h" #include "llimagejpeg.h" #include "llimagepng.h" -#include "llmediaengine.h" #include "llsdserialize.h" #include "llsys.h" @@ -56,10 +54,13 @@ #include "lltexturefetch.h" #include "llviewercontrol.h" #include "llviewerimage.h" +#include "llviewermedia.h" #include "llviewerregion.h" #include "pipeline.h" #include "llappviewer.h" +#include + //////////////////////////////////////////////////////////////////////////// void (*LLViewerImageList::sUUIDCallback)(void **, const LLUUID&) = NULL; @@ -85,12 +86,10 @@ LLStat LLViewerImageList::sFormattedMemStat(32, TRUE); /////////////////////////////////////////////////////////////////////////////// LLViewerImageList::LLViewerImageList() -: LLImageProviderInterface(), -mForceResetTextureStats(FALSE), -mUpdateStats(FALSE), -mMaxResidentTexMem(0), -mVideoMemorySetting(0), -mMovieImageHasMips(FALSE) + : LLImageProviderInterface(), + mForceResetTextureStats(FALSE), + mUpdateStats(FALSE), + mMaxResidentTexMem(0) { } @@ -98,7 +97,6 @@ void LLViewerImageList::init() { sNumImages = 0; mMaxResidentTexMem = 0; - mVideoMemorySetting = 0; if (gNoRender) { @@ -109,9 +107,7 @@ void LLViewerImageList::init() mUpdateStats = TRUE; // Update how much texture RAM we're allowed to use. - updateMaxResidentTexMem(); - - mMovieImageHasMips = FALSE; + updateMaxResidentTexMem(0); // 0 = use current doPreloadImages(); } @@ -166,14 +162,14 @@ void LLViewerImageList::doPreloadImages() preloadUIImage("spin_up_out_blue.tga", LLUUID::null, FALSE); preloadUIImage("square_btn_32x128.tga", LLUUID::null, FALSE, LLRectf(.125f, 0.5f, .875f, 0.5f )); preloadUIImage("square_btn_selected_32x128.tga", LLUUID::null, FALSE, LLRectf(.125f, 0.5f, .875f, 0.5f )); - preloadUIImage("startup_logo.tga", LLUUID::null, FALSE); // <<<<<<< --- needed? + preloadUIImage("startup_logo.tga", LLUUID::null, FALSE); // -- needed? preloadUIImage("tab_bottom_blue.tga", LLUUID::null, FALSE, LLRectf(0.109375f, 1.f - 0.4375f, 1.f - 0.109375f, 0.4375f)); preloadUIImage("tab_bottom_selected_blue.tga", LLUUID::null, FALSE, LLRectf(0.109375f, 1.f - 0.4375f, 1.f - 0.109375f, 0.4375f)); preloadUIImage("tab_left.tga", LLUUID::null, FALSE, LLRectf(.125f, 0.5f, .875f, 0.5f )); preloadUIImage("tab_left_selected.tga", LLUUID::null, FALSE, LLRectf(.125f, 0.5f, .875f, 0.5f )); preloadUIImage("tab_top_blue.tga", LLUUID::null, FALSE, LLRectf(0.109375f, 1.f - 0.4375f, 1.f - 0.109375f, 0.4375f)); preloadUIImage("tab_top_selected_blue.tga", LLUUID::null, FALSE, LLRectf(0.109375f, 1.f - 0.4375f, 1.f - 0.109375f, 0.4375f)); - + decodeAllImages(2.f); // decode preloaded images // These images are queued for decode during the login sequence, when @@ -190,6 +186,7 @@ void LLViewerImageList::doPreloadImages() preloadUIImage("eyes.tga", LLUUID::null, TRUE); preloadUIImage("foot_shadow.tga", LLUUID::null, TRUE); preloadUIImage("hair.tga", LLUUID::null, TRUE); + preloadUIImage("icon_diurnal.tga", LLUUID::null, TRUE); preloadUIImage("icon_for_sale.tga", LLUUID::null, FALSE); preloadUIImage("icon_popular.tga", LLUUID::null, FALSE); preloadUIImage("icon_top_pick.tga", LLUUID::null, FALSE); @@ -334,10 +331,7 @@ void LLViewerImageList::doPreloadImages() preloadUIImage("icn_voice-localchat.tga", LLUUID::null, FALSE); preloadUIImage("icn_voice-groupfocus.tga", LLUUID::null, FALSE); preloadUIImage("icn_voice-pvtfocus.tga", LLUUID::null, FALSE); - preloadUIImage("icn_media-pause.tga", LLUUID::null, FALSE); - preloadUIImage("icn_media-play.tga", LLUUID::null, FALSE); - preloadUIImage("icn_music-play.tga", LLUUID::null, FALSE); - preloadUIImage("icn_music-pause.tga", LLUUID::null, FALSE); + // TODO: Add images for media remote preloadUIImage("icn_chatbar.tga", LLUUID::null, FALSE); preloadUIImage("btn_chatbar.tga", LLUUID::null, FALSE, LLRectf(0.5f, 0.5f, 0.5f, 0.5f)); preloadUIImage("btn_chatbar_selected.tga", LLUUID::null, FALSE, LLRectf(0.5f, 0.5f, 0.5f, 0.5f)); @@ -714,38 +708,6 @@ void LLViewerImageList::deleteImage(LLViewerImage *image) /////////////////////////////////////////////////////////////////////////////// -void LLViewerImageList::updateMovieImage(const LLUUID& uuid, BOOL active) -{ - // IF the media image hasn't changed, do nothing - if (mMovieImageUUID == uuid) - { - return; - } - // If we have changed media uuid, restore the old one - if (!mMovieImageUUID.isNull()) - { - LLViewerImage* oldImage = getImage( mMovieImageUUID ); - if (oldImage) - { - oldImage->reinit(mMovieImageHasMips); - oldImage->mIsMediaTexture = FALSE; - } - mMovieImageUUID.setNull(); - } - // If the movie is playing, set the new media image - if (active && !uuid.isNull()) - { - LLViewerImage* viewerImage = getImage( uuid ); - if( viewerImage ) - { - mMovieImageUUID = uuid; - // Can't use mipmaps for movies because they don't update the full image - mMovieImageHasMips = viewerImage->getUseMipMaps(); - viewerImage->reinit(FALSE); - viewerImage->mIsMediaTexture = TRUE; - } - } -} //////////////////////////////////////////////////////////////////////////// @@ -767,9 +729,9 @@ void LLViewerImageList::updateImages(F32 max_time) updateImagesDecodePriorities(); max_time -= updateImagesFetchTextures(max_time); - max_time = llmax(max_time, 0.001f); + max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); max_time -= updateImagesCreateTextures(max_time); - max_time = llmax(max_time, 0.001f); + max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); if (!mDirtyTextureList.empty()) { @@ -779,7 +741,7 @@ void LLViewerImageList::updateImages(F32 max_time) } for (image_list_t::iterator iter = mCallbackList.begin(); - iter != mCallbackList.end(); ) + iter != mCallbackList.end(); ) { LLViewerImage* image = *iter++; // Do stuff to handle callbacks, update priorities, etc. @@ -789,8 +751,13 @@ void LLViewerImageList::updateImages(F32 max_time) break; // only actually do one callback per frame } } + - updateImagesMediaStreams(); + if (!gNoRender && !gGLManager.mIsDisabled) + { + LLViewerMedia::updateImagesMediaStreams(); + } + updateImagesUpdateStats(); } @@ -798,7 +765,7 @@ void LLViewerImageList::updateImagesDecodePriorities() { // Update the decode priority for N images each frame { - const size_t max_update_count = 256; + const size_t max_update_count = llmin((S32) (1024*gFrameIntervalSeconds) + 1, 32); //target 1024 textures per second S32 update_counter = llmin(max_update_count, mUUIDMap.size()/10); uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID); while(update_counter > 0) @@ -912,8 +879,8 @@ F32 LLViewerImageList::updateImagesFetchTextures(F32 max_time) // Update the decode priority for N images each frame // Make a list with 32 high priority entries + 256 cycled entries - const size_t max_priority_count = 32; - const size_t max_update_count = 256; + const size_t max_priority_count = llmin((S32) (256*10.f*gFrameIntervalSeconds)+1, 32); + const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256); // 32 high priority entries std::set entries; @@ -957,74 +924,6 @@ F32 LLViewerImageList::updateImagesFetchTextures(F32 max_time) return image_op_timer.getElapsedTimeF32(); } -void LLViewerImageList::updateImagesMediaStreams() -{ - if (gNoRender || gGLManager.mIsDisabled) return; - - // update media stream if required - LLMediaEngine* media_engine = LLMediaEngine::getInstance(); - if (media_engine) - { - if ( media_engine->update() ) - { - LLUUID media_uuid = media_engine->getImageUUID(); - updateMovieImage(media_uuid, TRUE); - if (!media_uuid.isNull()) - { - LLViewerImage* viewerImage = getImage( media_uuid ); - if( viewerImage ) - { - LLMediaBase* renderer = media_engine->getMediaRenderer(); - if ((renderer->getTextureWidth() != viewerImage->getWidth()) || - (renderer->getTextureHeight() != viewerImage->getHeight()) || - (renderer->getTextureDepth() != viewerImage->getComponents()) || - (viewerImage->getHasGLTexture() == FALSE)) - { - // destroy existing GL image - viewerImage->destroyGLTexture(); - - // set new size - viewerImage->setSize( renderer->getTextureWidth(), - renderer->getTextureHeight(), - renderer->getTextureDepth() ); - - LLPointer raw = new LLImageRaw(renderer->getTextureWidth(), - renderer->getTextureHeight(), - renderer->getTextureDepth()); - raw->clear(0x7f,0x7f,0x7f,0xff); - viewerImage->createGLTexture(0, raw); - } - - // Set the explicit format the instance wants - viewerImage->setExplicitFormat(renderer->getTextureFormatInternal(), - renderer->getTextureFormatPrimary(), - renderer->getTextureFormatType(), - renderer->getTextureFormatSwapBytes()); - // This should be redundant, but just in case: - viewerImage->setUseMipMaps(FALSE); - - LLImageRaw* rawImage = media_engine->getImageRaw(); - if ( rawImage ) - { - viewerImage->setSubImage(rawImage, 0, 0, - renderer->getMediaWidth(), - renderer->getMediaHeight()); - } - } - else - { - llwarns << "MediaEngine update unable to get viewer image for GL texture" << llendl; - } - } - } - else - { - LLUUID media_uuid = media_engine->getImageUUID(); - updateMovieImage(media_uuid, FALSE); - } - } -} - void LLViewerImageList::updateImagesUpdateStats() { if (mUpdateStats) @@ -1094,7 +993,7 @@ void LLViewerImageList::decodeAllImages(F32 max_time) imagep->updateFetch(); } max_time -= timer.getElapsedTimeF32(); - max_time = llmax(max_time, .01f); + max_time = llmax(max_time, .001f); F32 create_time = updateImagesCreateTextures(max_time); llinfos << "decodeAllImages() took " << timer.getElapsedTimeF32() << " seconds. " @@ -1220,97 +1119,80 @@ LLPointer LLViewerImageList::convertToUploadFile(LLPointer> 20); // In MB + //llinfos << "*** DETECTED " << system_ram << " MB of system memory." << llendl; + if (get_recommended) + max_texmem = llmin(max_texmem, (S32)(system_ram/2)); else - { - max_vram = llmin(max_vram, (U32)((F32)system_ram/1.5f)); - } - - S32 idx; - for (idx=0; idx < num_vram_settings; idx++) - { - if (idx == max) - break; - if ((vram_settings[idx] << 20) > max_vram) - { - idx--; - break; - } - } + max_texmem = llmin(max_texmem, (S32)(system_ram)); - if( idx == num_vram_settings ) - { - idx = num_vram_settings - 1; - } + max_texmem = llclamp(max_texmem, MIN_VIDEO_RAM, MAX_VIDEO_RAM); - return idx; + return max_texmem; } -const S32 VIDEO_CARD_MEM_SIZES[6] = { 0x1000000, // 16MB - 0x2000000, // 32MB - 0x4000000, // 64MB - 0x8000000, // 128MB - 0x10000000, // 256MB - 0x20000000, // 512MB -}; - -const S32 VIDEO_CARD_FRAMEBUFFER_MEM = 0xC00000; // 12MB +const S32 VIDEO_CARD_FRAMEBUFFER_MEM = 12; // MB -void LLViewerImageList::updateMaxResidentTexMem(S32 max, U32 fudge) +void LLViewerImageList::updateMaxResidentTexMem(S32 mem) { // Initialize the image pipeline VRAM settings - S32 cur_setting = gSavedSettings.getS32("GraphicsCardMemorySetting"); - S32 max_setting = getMaxVideoRamSetting(max); - if (max >= 0 && max != cur_setting) + S32 cur_mem = gSavedSettings.getS32("TextureMemory"); + S32 default_mem = getMaxVideoRamSetting(true); // recommended default + if (mem == 0) { - S32 default_setting = getMaxVideoRamSetting(-2); // recommended default - if (cur_setting >= 0 || max_setting != default_setting) - { - gSavedSettings.setS32("GraphicsCardMemorySetting", max_setting); - return; //listener will reenter this function - } - cur_setting = max_setting; // max_setting <= max + mem = cur_mem > 0 ? cur_mem : default_mem; } - else if (cur_setting < 0) + else if (mem < 0) { - S32 default_setting = getMaxVideoRamSetting(-2); // recommended default - cur_setting = default_setting; + mem = default_mem; } - mVideoMemorySetting = cur_setting; + + mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting()); + if (mem != cur_mem) + { + gSavedSettings.setS32("TextureMemory", mem); + return; //listener will re-enter this function + } + // TODO: set available resident texture mem based on use by other subsystems // currently max(12MB, VRAM/4) assumed... - S32 vram_amt = VIDEO_CARD_MEM_SIZES[cur_setting]; - S32 fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vram_amt/4); - mMaxResidentTexMem = vram_amt - fb_mem - fudge; + S32 vb_mem = mem; + S32 fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4); + mMaxResidentTexMem = (vb_mem - fb_mem)<<20; // llinfos << "Graphics Card memory set to " << (VIDEO_CARD_MEM_SIZES[cur_setting]>>20) // << " MB" << llendl; diff --git a/linden/indra/newview/llviewerimagelist.h b/linden/indra/newview/llviewerimagelist.h index 306dd5b..8a39405 100644 --- a/linden/indra/newview/llviewerimagelist.h +++ b/linden/indra/newview/llviewerimagelist.h @@ -33,7 +33,7 @@ #define LL_LLVIEWERIMAGELIST_H #include "lluuid.h" -#include "message.h" +//#include "message.h" #include "llgl.h" #include "llstat.h" #include "llviewerimage.h" @@ -52,6 +52,7 @@ const BOOL GL_TEXTURE_NO = FALSE; const BOOL IMMEDIATE_YES = TRUE; const BOOL IMMEDIATE_NO = FALSE; +class LLMessageSystem; class LLViewerImage; class LLTextureView; @@ -129,7 +130,6 @@ public: void addImageToList(LLViewerImage *image); void removeImageFromList(LLViewerImage *image); - void updateMovieImage(const LLUUID& image_id, BOOL active); void dirtyImage(LLViewerImage *image); // Using image stats, determine what images are necessary, and perform image updates. @@ -143,21 +143,21 @@ public: void setUpdateStats(BOOL b) { mUpdateStats = b; } S32 getMaxResidentTexMem() const { return mMaxResidentTexMem; } - S32 getVideoMemorySetting() const { return mVideoMemorySetting; } S32 getNumImages() { return mImageList.size(); } - static S32 getMaxVideoRamSetting(S32 max = -1); - void updateMaxResidentTexMem(S32 max = -1, U32 fudge = 0); + void updateMaxResidentTexMem(S32 mem); void doPreloadImages(); void doPrefetchImages(); + static S32 getMinVideoRamSetting(); + static S32 getMaxVideoRamSetting(bool get_recommended = false); + private: LLViewerImage* preloadUIImage(const LLString& filename, const LLUUID &image_set_id, BOOL use_mips, const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); void updateImagesDecodePriorities(); F32 updateImagesCreateTextures(F32 max_time); F32 updateImagesFetchTextures(F32 max_time); - void updateImagesMediaStreams(); void updateImagesUpdateStats(); public: @@ -186,12 +186,8 @@ private: BOOL mUpdateStats; S32 mMaxResidentTexMem; - S32 mVideoMemorySetting; LLFrameTimer mForceDecodeTimer; - LLUUID mMovieImageUUID; - U8 mMovieImageHasMips; - typedef std::map< LLUUID, LLPointer > uuid_ui_image_map_t; uuid_ui_image_map_t mUIImages; diff --git a/linden/indra/newview/llviewerinventory.cpp b/linden/indra/newview/llviewerinventory.cpp index add9f27..bbd6cd4 100644 --- a/linden/indra/newview/llviewerinventory.cpp +++ b/linden/indra/newview/llviewerinventory.cpp @@ -48,6 +48,8 @@ #include "llviewerregion.h" #include "llviewerobjectlist.h" #include "llpreviewgesture.h" +#include "llviewerwindow.h" + ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs ///---------------------------------------------------------------------------- @@ -213,6 +215,14 @@ void LLViewerInventoryItem::fetchFromServer(void) const } // virtual +BOOL LLViewerInventoryItem::unpackMessage(LLSD item) +{ + BOOL rv = LLInventoryItem::fromLLSD(item); + mIsComplete = TRUE; + return rv; +} + +// virtual BOOL LLViewerInventoryItem::unpackMessage( LLMessageSystem* msg, const char* block, S32 block_num) { @@ -420,30 +430,42 @@ void LLViewerInventoryCategory::removeFromServer( void ) bool LLViewerInventoryCategory::fetchDescendents() { if((VERSION_UNKNOWN == mVersion) - && mDescendentsRequested.hasExpired()) + && mDescendentsRequested.hasExpired()) //Expired check prevents multiple downloads. { const F32 FETCH_TIMER_EXPIRY = 10.0f; mDescendentsRequested.reset(); mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY); - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("FetchInventoryDescendents"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->nextBlock("InventoryData"); - msg->addUUID("FolderID", mUUID); - msg->addUUID("OwnerID", mOwnerID); // bitfield // 1 = by date // 2 = folders by date // Need to mask off anything but the first bit. // This comes from LLInventoryFilter from llfolderview.h U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1; - msg->addS32("SortOrder", sort_order); - msg->addBOOL("FetchFolders", FALSE); - msg->addBOOL("FetchItems", TRUE); - gAgent.sendReliableMessage(); + + std::string url = gAgent.getRegion()->getCapability("FetchInventoryDescendents"); + + if (!url.empty()) //Capability found. Build up LLSD and use it. + { + LLInventoryModel::startBackgroundFetch(mUUID); + } + else + { //Deprecated, but if we don't have a capability, use the old system. + llinfos << "FetchInventoryDescendents capability not found. Using deprecated UDP message." << llendl; + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("FetchInventoryDescendents"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + msg->nextBlock("InventoryData"); + msg->addUUID("FolderID", mUUID); + msg->addUUID("OwnerID", mOwnerID); + + msg->addS32("SortOrder", sort_order); + msg->addBOOL("FetchFolders", FALSE); + msg->addBOOL("FetchItems", TRUE); + gAgent.sendReliableMessage(); + } return true; } return false; diff --git a/linden/indra/newview/llviewerinventory.h b/linden/indra/newview/llviewerinventory.h index fcedcc1..016f7c8 100644 --- a/linden/indra/newview/llviewerinventory.h +++ b/linden/indra/newview/llviewerinventory.h @@ -99,6 +99,7 @@ public: //virtual void packMessage(LLMessageSystem* msg) const; virtual BOOL unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0); + virtual BOOL unpackMessage(LLSD item); virtual BOOL importFile(FILE* fp); virtual BOOL importLegacyStream(std::istream& input_stream); diff --git a/linden/indra/newview/llviewerjoint.cpp b/linden/indra/newview/llviewerjoint.cpp index 9645dfe..0aa9112 100644 --- a/linden/indra/newview/llviewerjoint.cpp +++ b/linden/indra/newview/llviewerjoint.cpp @@ -37,6 +37,7 @@ #include "llviewerjoint.h" #include "llgl.h" +#include "llglimmediate.h" #include "llmath.h" #include "llglheaders.h" #include "llsphere.h" @@ -147,19 +148,19 @@ void LLViewerJoint::renderSkeleton(BOOL recursive) //---------------------------------------------------------------- if (mComponents & SC_AXES) { - glBegin(GL_LINES); - glColor3f( 1.0f, 0.0f, 0.0f ); - glVertex3f( 0.0f, 0.0f, 0.0f ); - glVertex3f( 0.1f, 0.0f, 0.0f ); - - glColor3f( 0.0f, 1.0f, 0.0f ); - glVertex3f( 0.0f, 0.0f, 0.0f ); - glVertex3f( 0.0f, 0.1f, 0.0f ); - - glColor3f( 0.0f, 0.0f, 1.0f ); - glVertex3f( 0.0f, 0.0f, 0.0f ); - glVertex3f( 0.0f, 0.0f, 0.1f ); - glEnd(); + gGL.begin(GL_LINES); + gGL.color3f( 1.0f, 0.0f, 0.0f ); + gGL.vertex3f( 0.0f, 0.0f, 0.0f ); + gGL.vertex3f( 0.1f, 0.0f, 0.0f ); + + gGL.color3f( 0.0f, 1.0f, 0.0f ); + gGL.vertex3f( 0.0f, 0.0f, 0.0f ); + gGL.vertex3f( 0.0f, 0.1f, 0.0f ); + + gGL.color3f( 0.0f, 0.0f, 1.0f ); + gGL.vertex3f( 0.0f, 0.0f, 0.0f ); + gGL.vertex3f( 0.0f, 0.0f, 0.1f ); + gGL.end(); } //---------------------------------------------------------------- @@ -167,53 +168,53 @@ void LLViewerJoint::renderSkeleton(BOOL recursive) //---------------------------------------------------------------- if (mComponents & SC_JOINT) { - glColor3f( 1.0f, 1.0f, 0.0f ); + gGL.color3f( 1.0f, 1.0f, 0.0f ); - glBegin(GL_TRIANGLES); + gGL.begin(GL_TRIANGLES); // joint top half glNormal3f(nc, nc, nc); - glVertex3f(0.0f, 0.0f, 0.05f); - glVertex3f(0.05f, 0.0f, 0.0f); - glVertex3f(0.0f, 0.05f, 0.0f); + gGL.vertex3f(0.0f, 0.0f, 0.05f); + gGL.vertex3f(0.05f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, 0.05f, 0.0f); glNormal3f(-nc, nc, nc); - glVertex3f(0.0f, 0.0f, 0.05f); - glVertex3f(0.0f, 0.05f, 0.0f); - glVertex3f(-0.05f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, 0.0f, 0.05f); + gGL.vertex3f(0.0f, 0.05f, 0.0f); + gGL.vertex3f(-0.05f, 0.0f, 0.0f); glNormal3f(-nc, -nc, nc); - glVertex3f(0.0f, 0.0f, 0.05f); - glVertex3f(-0.05f, 0.0f, 0.0f); - glVertex3f(0.0f, -0.05f, 0.0f); + gGL.vertex3f(0.0f, 0.0f, 0.05f); + gGL.vertex3f(-0.05f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, -0.05f, 0.0f); glNormal3f(nc, -nc, nc); - glVertex3f(0.0f, 0.0f, 0.05f); - glVertex3f(0.0f, -0.05f, 0.0f); - glVertex3f(0.05f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, 0.0f, 0.05f); + gGL.vertex3f(0.0f, -0.05f, 0.0f); + gGL.vertex3f(0.05f, 0.0f, 0.0f); // joint bottom half glNormal3f(nc, nc, -nc); - glVertex3f(0.0f, 0.0f, -0.05f); - glVertex3f(0.0f, 0.05f, 0.0f); - glVertex3f(0.05f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, 0.0f, -0.05f); + gGL.vertex3f(0.0f, 0.05f, 0.0f); + gGL.vertex3f(0.05f, 0.0f, 0.0f); glNormal3f(-nc, nc, -nc); - glVertex3f(0.0f, 0.0f, -0.05f); - glVertex3f(-0.05f, 0.0f, 0.0f); - glVertex3f(0.0f, 0.05f, 0.0f); + gGL.vertex3f(0.0f, 0.0f, -0.05f); + gGL.vertex3f(-0.05f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, 0.05f, 0.0f); glNormal3f(-nc, -nc, -nc); - glVertex3f(0.0f, 0.0f, -0.05f); - glVertex3f(0.0f, -0.05f, 0.0f); - glVertex3f(-0.05f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, 0.0f, -0.05f); + gGL.vertex3f(0.0f, -0.05f, 0.0f); + gGL.vertex3f(-0.05f, 0.0f, 0.0f); glNormal3f(nc, -nc, -nc); - glVertex3f(0.0f, 0.0f, -0.05f); - glVertex3f(0.05f, 0.0f, 0.0f); - glVertex3f(0.0f, -0.05f, 0.0f); + gGL.vertex3f(0.0f, 0.0f, -0.05f); + gGL.vertex3f(0.05f, 0.0f, 0.0f); + gGL.vertex3f(0.0f, -0.05f, 0.0f); - glEnd(); + gGL.end(); } //---------------------------------------------------------------- @@ -258,7 +259,7 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass ) { triangle_count += drawShape( pixelArea, first_pass ); } - else if ( isTransparent() ) + else if ( isTransparent() && !LLPipeline::sReflectionRender) { // Hair and Skirt if ((pixelArea > MIN_PIXEL_AREA_3PASS_HAIR)) @@ -357,27 +358,27 @@ void LLViewerJoint::drawBone() glMultMatrixf( &rotateMat.mMatrix[0][0] ); // render the bone - glColor3f( 0.5f, 0.5f, 0.0f ); + gGL.color3f( 0.5f, 0.5f, 0.0f ); - glBegin(GL_TRIANGLES); + gGL.begin(GL_TRIANGLES); - glVertex3f( length, 0.0f, 0.0f); - glVertex3f( 0.0f, boneSize, 0.0f); - glVertex3f( 0.0f, 0.0f, boneSize); + gGL.vertex3f( length, 0.0f, 0.0f); + gGL.vertex3f( 0.0f, boneSize, 0.0f); + gGL.vertex3f( 0.0f, 0.0f, boneSize); - glVertex3f( length, 0.0f, 0.0f); - glVertex3f( 0.0f, 0.0f, -boneSize); - glVertex3f( 0.0f, boneSize, 0.0f); + gGL.vertex3f( length, 0.0f, 0.0f); + gGL.vertex3f( 0.0f, 0.0f, -boneSize); + gGL.vertex3f( 0.0f, boneSize, 0.0f); - glVertex3f( length, 0.0f, 0.0f); - glVertex3f( 0.0f, -boneSize, 0.0f); - glVertex3f( 0.0f, 0.0f, -boneSize); + gGL.vertex3f( length, 0.0f, 0.0f); + gGL.vertex3f( 0.0f, -boneSize, 0.0f); + gGL.vertex3f( 0.0f, 0.0f, -boneSize); - glVertex3f( length, 0.0f, 0.0f); - glVertex3f( 0.0f, 0.0f, boneSize); - glVertex3f( 0.0f, -boneSize, 0.0f); + gGL.vertex3f( length, 0.0f, 0.0f); + gGL.vertex3f( 0.0f, 0.0f, boneSize); + gGL.vertex3f( 0.0f, -boneSize, 0.0f); - glEnd(); + gGL.end(); // restore matrix glPopMatrix(); @@ -422,16 +423,7 @@ void LLViewerJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pix iter != mChildren.end(); ++iter) { LLViewerJoint* joint = (LLViewerJoint*)(*iter); - //F32 jointLOD = joint->getLOD(); - //if (pixel_area >= jointLOD || sDisableLOD) - { - joint->updateFaceSizes(num_vertices, num_indices, pixel_area); - - // if (jointLOD != DEFAULT_LOD) - // { - // break; - // } - } + joint->updateFaceSizes(num_vertices, num_indices, pixel_area); } } @@ -441,16 +433,7 @@ void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind) iter != mChildren.end(); ++iter) { LLViewerJoint* joint = (LLViewerJoint*)(*iter); - //F32 jointLOD = joint->getLOD(); - //if (pixel_area >= jointLOD || sDisableLOD) - { - joint->updateFaceData(face, pixel_area, damp_wind); - - // if (jointLOD != DEFAULT_LOD) - // { - // break; - // } - } + joint->updateFaceData(face, pixel_area, damp_wind); } } @@ -522,76 +505,6 @@ void LLViewerJoint::setVisible(BOOL visible, BOOL recursive) } } -void LLViewerJoint::writeCAL3D(apr_file_t* fp) -{ - LLVector3 bone_pos = mXform.getPosition(); - if (mParent) - { - bone_pos.scaleVec(mParent->getScale()); - bone_pos *= 100.f; - } - else - { - bone_pos.clearVec(); - } - - LLQuaternion bone_rot; - - S32 num_children = 0; - for (child_list_t::iterator iter = mChildren.begin(); - iter != mChildren.end(); ++iter) - { - LLViewerJoint* joint = (LLViewerJoint*)(*iter); - if (joint->mJointNum != -1) - { - num_children++; - } - } - - LLJoint* cur_joint = this; - LLVector3 rootSkinOffset; - if (mParent) - { - while (cur_joint) - { - rootSkinOffset -= cur_joint->getSkinOffset(); - cur_joint = (LLViewerJoint*)cur_joint->getParent(); - } - - rootSkinOffset *= 100.f; - } - - apr_file_printf(fp, " \n", mJointNum + 1, mName.c_str(), num_children); - apr_file_printf(fp, " %.6f %.6f %.6f\n", bone_pos.mV[VX], bone_pos.mV[VY], bone_pos.mV[VZ]); - apr_file_printf(fp, " %.6f %.6f %.6f %.6f\n", bone_rot.mQ[VX], bone_rot.mQ[VY], bone_rot.mQ[VZ], bone_rot.mQ[VW]); - apr_file_printf(fp, " %.6f %.6f %.6f\n", rootSkinOffset.mV[VX], rootSkinOffset.mV[VY], rootSkinOffset.mV[VZ]); - apr_file_printf(fp, " 0 0 0 1\n"); - apr_file_printf(fp, " %d\n", mParent ? mParent->mJointNum + 1 : -1); - - for (child_list_t::iterator iter = mChildren.begin(); - iter != mChildren.end(); ++iter) - { - LLViewerJoint* joint = (LLViewerJoint*)(*iter); - if (joint->mJointNum != -1) - { - apr_file_printf(fp, " %d\n", joint->mJointNum + 1); - } - } - apr_file_printf(fp, " \n"); - - // recurse - for (child_list_t::iterator iter = mChildren.begin(); - iter != mChildren.end(); ++iter) - { - LLViewerJoint* joint = (LLViewerJoint*)(*iter); - if (joint->mJointNum != -1) - { - joint->writeCAL3D(fp); - } - } - -} - //----------------------------------------------------------------------------- // LLViewerJointCollisionVolume() //----------------------------------------------------------------------------- diff --git a/linden/indra/newview/llviewerjoint.h b/linden/indra/newview/llviewerjoint.h index 0433ba9..ea0202e 100644 --- a/linden/indra/newview/llviewerjoint.h +++ b/linden/indra/newview/llviewerjoint.h @@ -131,7 +131,6 @@ public: virtual void dump(); void setVisible( BOOL visible, BOOL recursive ); - virtual void writeCAL3D(apr_file_t* fp); public: static BOOL sDisableLOD; diff --git a/linden/indra/newview/llviewerjointattachment.cpp b/linden/indra/newview/llviewerjointattachment.cpp index 1348ad0..0747f68 100644 --- a/linden/indra/newview/llviewerjointattachment.cpp +++ b/linden/indra/newview/llviewerjointattachment.cpp @@ -38,9 +38,11 @@ #include "llviewercontrol.h" #include "lldrawable.h" #include "llgl.h" +#include "llglimmediate.h" #include "llvoavatar.h" #include "llvolume.h" #include "pipeline.h" +#include "llspatialpartition.h" #include "llinventorymodel.h" #include "llviewerobjectlist.h" #include "llface.h" @@ -56,7 +58,6 @@ extern LLPipeline gPipeline; LLViewerJointAttachment::LLViewerJointAttachment() : mJoint(NULL), mAttachedObject(NULL), -mAttachmentDirty(FALSE), mVisibleInFirst(FALSE), mGroup(0), mIsHUDAttachment(FALSE), @@ -90,36 +91,18 @@ U32 LLViewerJointAttachment::drawShape( F32 pixelArea, BOOL first_pass ) { LLGLDisable cull_face(GL_CULL_FACE); - glColor4f(1.f, 1.f, 1.f, 1.f); - glBegin(GL_QUADS); + gGL.color4f(1.f, 1.f, 1.f, 1.f); + gGL.begin(GL_QUADS); { - glVertex3f(-0.1f, 0.1f, 0.f); - glVertex3f(-0.1f, -0.1f, 0.f); - glVertex3f(0.1f, -0.1f, 0.f); - glVertex3f(0.1f, 0.1f, 0.f); - }glEnd(); + gGL.vertex3f(-0.1f, 0.1f, 0.f); + gGL.vertex3f(-0.1f, -0.1f, 0.f); + gGL.vertex3f(0.1f, -0.1f, 0.f); + gGL.vertex3f(0.1f, 0.1f, 0.f); + }gGL.end(); } return 0; } -//----------------------------------------------------------------------------- -// lazyAttach() -//----------------------------------------------------------------------------- -void LLViewerJointAttachment::lazyAttach() -{ - if (!mAttachedObject) - { - return; - } - LLDrawable *drawablep = mAttachedObject->mDrawable; - - if (mAttachmentDirty && drawablep) - { - setupDrawable(drawablep); - mAttachmentDirty = FALSE; - } -} - void LLViewerJointAttachment::setupDrawable(LLDrawable* drawablep) { drawablep->mXform.setParent(&mXform); // LLViewerJointAttachment::lazyAttach @@ -174,7 +157,20 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object) if (mAttachedObject) { llwarns << "Attempted to attach object where an attachment already exists!" << llendl; - return FALSE; + + if (mAttachedObject == object) { + llinfos << "(same object re-attached)" << llendl; + removeObject(mAttachedObject); + // Pass through anyway to let setupDrawable() + // re-connect object to the joint correctly + } + else { + llinfos << "(objects differ, removing existing object)" << llendl; + // Rather hacky, but no-one can think of something + // better to do for this case. + gObjectList.killObject(mAttachedObject); + // Proceed with new object attachment + } } mAttachedObject = object; @@ -198,13 +194,14 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object) if (drawablep) { + //if object is active, make it static + if(drawablep->isActive()) + { + drawablep->makeStatic() ; + } + setupDrawable(drawablep); } - else - { - // do lazy update once we have a drawable for this object - mAttachmentDirty = TRUE; - } if (mIsHUDAttachment) { @@ -238,6 +235,12 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object) if (object->mDrawable.notNull()) { + //if object is active, make it static + if(object->mDrawable->isActive()) + { + object->mDrawable->makeStatic() ; + } + LLVector3 cur_position = object->getRenderPosition(); LLQuaternion cur_rotation = object->getRenderRotation(); diff --git a/linden/indra/newview/llviewerjointattachment.h b/linden/indra/newview/llviewerjointattachment.h index 275fce5..63484c7 100644 --- a/linden/indra/newview/llviewerjointattachment.h +++ b/linden/indra/newview/llviewerjointattachment.h @@ -82,7 +82,6 @@ public: S32 getGroup() { return mGroup; } S32 getPieSlice() { return mPieSlice; } - BOOL getAttachmentDirty() { return mAttachmentDirty && mAttachedObject; } LLViewerObject *getObject() { return mAttachedObject; } S32 getNumObjects() { return (mAttachedObject ? 1 : 0); } const LLUUID& getItemID() { return mItemID; } @@ -93,7 +92,6 @@ public: BOOL addObject(LLViewerObject* object); void removeObject(LLViewerObject *object); - void lazyAttach(); void setupDrawable(LLDrawable* drawable); void clampObjectPosition(); @@ -104,7 +102,6 @@ protected: LLJoint* mJoint; // Backlink only; don't make this an LLPointer. LLViewerObject* mAttachedObject; - BOOL mAttachmentDirty; // does attachment drawable need to be fixed up? BOOL mVisibleInFirst; LLVector3 mOriginalPos; S32 mGroup; diff --git a/linden/indra/newview/llviewerjointmesh.cpp b/linden/indra/newview/llviewerjointmesh.cpp index d90db4a..5c73319 100644 --- a/linden/indra/newview/llviewerjointmesh.cpp +++ b/linden/indra/newview/llviewerjointmesh.cpp @@ -193,48 +193,6 @@ BOOL LLViewerJointMesh::allocateSkinData( U32 numSkinJoints ) } //----------------------------------------------------------------------------- -// getSkinJointByIndex() -//----------------------------------------------------------------------------- -S32 LLViewerJointMesh::getBoundJointsByIndex(S32 index, S32 &joint_a, S32& joint_b) -{ - S32 num_joints = 0; - if (mNumSkinJoints == 0) - { - return num_joints; - } - - joint_a = -1; - joint_b = -1; - - LLPolyMesh *reference_mesh = mMesh->getReferenceMesh(); - - if (index < reference_mesh->mJointRenderData.count()) - { - LLJointRenderData* render_datap = reference_mesh->mJointRenderData[index]; - if (render_datap->mSkinJoint) - { - joint_a = render_datap->mSkinJoint->mJoint->mJointNum; - } - num_joints++; - } - if (index + 1 < reference_mesh->mJointRenderData.count()) - { - LLJointRenderData* render_datap = reference_mesh->mJointRenderData[index + 1]; - if (render_datap->mSkinJoint) - { - joint_b = render_datap->mSkinJoint->mJoint->mJointNum; - - if (joint_a == -1) - { - joint_a = render_datap->mSkinJoint->mJoint->getParent()->mJointNum; - } - } - num_joints++; - } - return num_joints; -} - -//----------------------------------------------------------------------------- // LLViewerJointMesh::freeSkinData() //----------------------------------------------------------------------------- void LLViewerJointMesh::freeSkinData() @@ -554,6 +512,8 @@ void llDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, G { glDrawRangeElements(mode,start,end,count,type,indices); } + + gPipeline.addTrianglesDrawn(count/3); } //-------------------------------------------------------------------- @@ -577,32 +537,13 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass) //---------------------------------------------------------------- if (!gRenderForSelect) { - if ((mFace->getPool()->getVertexShaderLevel() > 0)) - { - glColor4f(0,0,0,1); - - if (gMaterialIndex > 0) - { - glVertexAttrib4fvARB(gMaterialIndex, mColor.mV); - } - - if (mShiny && gSpecularIndex > 0) - { - glVertexAttrib4fARB(gSpecularIndex, 1,1,1,1); - } - } - else - { - glColor4fv(mColor.mV); - } + glColor4fv(mColor.mV); } stop_glerror(); LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), gRenderForSelect ? 0.0f : mShiny && !(mFace->getPool()->getVertexShaderLevel() > 0)); - LLGLEnable texture_2d((gRenderForSelect && isTransparent()) ? GL_TEXTURE_2D : 0); - //---------------------------------------------------------------- // setup current texture //---------------------------------------------------------------- @@ -660,8 +601,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass) gImageList.getImage(IMG_DEFAULT_AVATAR)->bind(); } - LLGLDisable tex(gRenderForSelect && !isTransparent() ? GL_TEXTURE_2D : 0); - if (gRenderForSelect) { if (isTransparent()) @@ -676,92 +615,18 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass) glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); // GL_TEXTURE_ENV_COLOR is set in renderPass1 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); } - } - else - { - //---------------------------------------------------------------- - // by default, backface culling is enabled - //---------------------------------------------------------------- - /*if (sRenderPass == AVATAR_RENDER_PASS_CLOTHING_INNER) + else { - LLImageGL::bindExternalTexture( sClothingMaskImageName, 1, GL_TEXTURE_2D ); - - glClientActiveTextureARB(GL_TEXTURE0_ARB); - glActiveTextureARB(GL_TEXTURE0_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); - - glClientActiveTextureARB(GL_TEXTURE1_ARB); - glEnable(GL_TEXTURE_2D); // Texture unit 1 - glActiveTextureARB(GL_TEXTURE1_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, sClothingInnerColor.mV); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_CONSTANT_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA); + LLImageGL::unbindTexture(0); } - else if (sRenderPass == AVATAR_RENDER_PASS_CLOTHING_OUTER) - { - glAlphaFunc(GL_GREATER, 0.1f); - LLImageGL::bindExternalTexture( sClothingMaskImageName, 1, GL_TEXTURE_2D ); - - glClientActiveTextureARB(GL_TEXTURE0_ARB); - glActiveTextureARB(GL_TEXTURE0_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); - - glClientActiveTextureARB(GL_TEXTURE1_ARB); - glEnable(GL_TEXTURE_2D); // Texture unit 1 - glActiveTextureARB(GL_TEXTURE1_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); - }*/ } - + mFace->mVertexBuffer->setBuffer(sRenderMask); U32 start = mMesh->mFaceVertexOffset; U32 end = start + mMesh->mFaceVertexCount - 1; U32 count = mMesh->mFaceIndexCount; - U32* indicesp = ((U32*) mFace->mVertexBuffer->getIndicesPointer()) + mMesh->mFaceIndexOffset; + U16* indicesp = ((U16*) mFace->mVertexBuffer->getIndicesPointer()) + mMesh->mFaceIndexOffset; if (mMesh->hasWeights()) { @@ -771,11 +636,11 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass) { uploadJointMatrices(); } - llDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_INT, indicesp); + llDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_SHORT, indicesp); } else { - llDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_INT, indicesp); + llDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_SHORT, indicesp); } } else @@ -783,7 +648,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass) glPushMatrix(); LLMatrix4 jointToWorld = getWorldMatrix(); glMultMatrixf((GLfloat*)jointToWorld.mMatrix); - llDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_INT, indicesp); + llDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_SHORT, indicesp); glPopMatrix(); } @@ -794,21 +659,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } - /*if (sRenderPass != AVATAR_RENDER_PASS_SINGLE) - { - LLImageGL::unbindTexture(1, GL_TEXTURE_2D); - glActiveTextureARB(GL_TEXTURE1_ARB); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); - - // Return to the default texture. - LLImageGL::unbindTexture(0, GL_TEXTURE_2D); - glClientActiveTextureARB(GL_TEXTURE0_ARB); - glActiveTextureARB(GL_TEXTURE0_ARB); - - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); - glAlphaFunc(GL_GREATER, 0.01f); - }*/ - if (mTexture.notNull()) { if (!mTexture->getClampS()) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -846,37 +696,36 @@ void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 //----------------------------------------------------------------------------- void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind) { - U32 i; - mFace = face; + if (mFace->mVertexBuffer.isNull()) + { + return; + } + LLStrider verticesp; LLStrider normalsp; - LLStrider binormalsp; LLStrider tex_coordsp; LLStrider vertex_weightsp; LLStrider clothing_weightsp; - LLStrider indicesp; + LLStrider indicesp; // Copy data into the faces from the polymesh data. if (mMesh && mValid) { if (mMesh->getNumVertices()) { - S32 index = face->getGeometryAvatar(verticesp, normalsp, binormalsp, tex_coordsp, vertex_weightsp, clothing_weightsp); + stop_glerror(); + face->getGeometryAvatar(verticesp, normalsp, tex_coordsp, vertex_weightsp, clothing_weightsp); + stop_glerror(); face->mVertexBuffer->getIndexStrider(indicesp); + stop_glerror(); - if (-1 == index) - { - return; - } - - for (i = 0; i < mMesh->getNumVertices(); i++) + for (U16 i = 0; i < mMesh->getNumVertices(); i++) { verticesp[mMesh->mFaceVertexOffset + i] = *(mMesh->getCoords() + i); tex_coordsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getTexCoords() + i); normalsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getNormals() + i); - binormalsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getBinormals() + i); vertex_weightsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getWeights() + i); if (damp_wind) { @@ -1001,6 +850,8 @@ void LLViewerJointMesh::updateGeometryOriginal(LLFace *mFace, LLPolyMesh *mMesh) o_normals[bidx] = normals[index] * gBlendRotMat; } + + buffer->setBuffer(0); } const U32 UPDATE_GEOMETRY_CALL_MASK = 0x1FFF; // 8K samples before overflow @@ -1166,99 +1017,4 @@ void LLViewerJointMesh::dump() } } -void LLViewerJointMesh::writeCAL3D(apr_file_t* fp, S32 material_num, LLCharacter* characterp) -{ - apr_file_printf(fp, "\t\n", mMesh->getNumVertices(), mMesh->getNumFaces(), material_num); - - const LLVector3* mesh_coords = mMesh->getCoords(); - const LLVector3* mesh_normals = mMesh->getNormals(); - const LLVector2* mesh_uvs = mMesh->getTexCoords(); - const F32* mesh_weights = mMesh->getWeights(); - LLVector3 mesh_offset; - LLVector3 scale(1.f, 1.f, 1.f); - S32 joint_a = -1; - S32 joint_b = -1; - S32 num_bound_joints = 0; - - if(!mMesh->hasWeights()) - { - num_bound_joints = 1; - LLJoint* cur_joint = this; - while(cur_joint) - { - if (cur_joint->mJointNum != -1 && joint_a == -1) - { - joint_a = cur_joint->mJointNum; - } - mesh_offset += cur_joint->getSkinOffset(); - cur_joint = cur_joint->getParent(); - } - } - - for (S32 i = 0; i < (S32)mMesh->getNumVertices(); i++) - { - LLVector3 coord = mesh_coords[i]; - - if (mMesh->hasWeights()) - { - // calculate joint to which this skinned vertex is bound - num_bound_joints = getBoundJointsByIndex(llfloor(mesh_weights[i]), joint_a, joint_b); - LLJoint* first_joint = characterp->getCharacterJoint(joint_a); - LLJoint* second_joint = characterp->getCharacterJoint(joint_b); - - LLVector3 first_joint_offset; - LLJoint* cur_joint = first_joint; - while(cur_joint) - { - first_joint_offset += cur_joint->getSkinOffset(); - cur_joint = cur_joint->getParent(); - } - - LLVector3 second_joint_offset; - cur_joint = second_joint; - while(cur_joint) - { - second_joint_offset += cur_joint->getSkinOffset(); - cur_joint = cur_joint->getParent(); - } - - LLVector3 first_coord = coord - first_joint_offset; - first_coord.scaleVec(first_joint->getScale()); - LLVector3 second_coord = coord - second_joint_offset; - if (second_joint) - { - second_coord.scaleVec(second_joint->getScale()); - } - - coord = lerp(first_joint_offset + first_coord, second_joint_offset + second_coord, fmodf(mesh_weights[i], 1.f)); - } - - // add offset to move rigid mesh to target location - coord += mesh_offset; - coord *= 100.f; - - apr_file_printf(fp, " \n", i, num_bound_joints); - apr_file_printf(fp, " %.4f %.4f %.4f\n", coord.mV[VX], coord.mV[VY], coord.mV[VZ]); - apr_file_printf(fp, " %.6f %.6f %.6f\n", mesh_normals[i].mV[VX], mesh_normals[i].mV[VY], mesh_normals[i].mV[VZ]); - apr_file_printf(fp, " %.6f %.6f\n", mesh_uvs[i].mV[VX], 1.f - mesh_uvs[i].mV[VY]); - if (num_bound_joints >= 1) - { - apr_file_printf(fp, " %.2f\n", joint_a + 1, 1.f - fmod(mesh_weights[i], 1.f)); - } - if (num_bound_joints == 2) - { - apr_file_printf(fp, " %.2f\n", joint_b + 1, fmod(mesh_weights[i], 1.f)); - } - apr_file_printf(fp, " \n"); - } - - LLPolyFace* mesh_faces = mMesh->getFaces(); - for (S32 i = 0; i < mMesh->getNumFaces(); i++) - { - apr_file_printf(fp, " \n", mesh_faces[i][0], mesh_faces[i][1], mesh_faces[i][2]); - } - - apr_file_printf(fp, " \n"); -} - // End diff --git a/linden/indra/newview/llviewerjointmesh.h b/linden/indra/newview/llviewerjointmesh.h index e1b5e58..c02275a 100644 --- a/linden/indra/newview/llviewerjointmesh.h +++ b/linden/indra/newview/llviewerjointmesh.h @@ -148,8 +148,7 @@ public: void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; } /*virtual*/ BOOL isAnimatable() { return FALSE; } - void writeCAL3D(apr_file_t* fp, S32 material_num, LLCharacter* characterp); - + // Avatar vertex skinning is a significant performance issue on computers // with avatar vertex programs turned off (for example, most Macs). We // therefore have custom versions that use SIMD instructions. @@ -169,8 +168,6 @@ private: // Allocate skin data BOOL allocateSkinData( U32 numSkinJoints ); - S32 getBoundJointsByIndex(S32 index, S32 &joint_a, S32& joint_b); - // Free skin data void freeSkinData(); }; diff --git a/linden/indra/newview/llviewerjointmesh_sse.cpp b/linden/indra/newview/llviewerjointmesh_sse.cpp index 79fda0b..262be47 100644 --- a/linden/indra/newview/llviewerjointmesh_sse.cpp +++ b/linden/indra/newview/llviewerjointmesh_sse.cpp @@ -105,6 +105,8 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh) blend_mat.multiply(coords[index], o_vertices[index]); ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]); } + + buffer->setBuffer(0); } #else diff --git a/linden/indra/newview/llviewerjointmesh_sse2.cpp b/linden/indra/newview/llviewerjointmesh_sse2.cpp index d1f858d..ebefdba 100644 --- a/linden/indra/newview/llviewerjointmesh_sse2.cpp +++ b/linden/indra/newview/llviewerjointmesh_sse2.cpp @@ -112,6 +112,8 @@ void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh) blend_mat.multiply(coords[index], o_vertices[index]); ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]); } + + //setBuffer(0) called in LLVOAvatar::renderSkinned } #else diff --git a/linden/indra/newview/llviewerjointmesh_vec.cpp b/linden/indra/newview/llviewerjointmesh_vec.cpp index 65bff2c..12fe597 100644 --- a/linden/indra/newview/llviewerjointmesh_vec.cpp +++ b/linden/indra/newview/llviewerjointmesh_vec.cpp @@ -95,4 +95,6 @@ void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh) blend_mat.multiply(coords[index], o_vertices[index]); ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]); } + + buffer->setBuffer(0); } diff --git a/linden/indra/newview/llviewerjointshape.cpp b/linden/indra/newview/llviewerjointshape.cpp deleted file mode 100644 index 279115b..0000000 --- a/linden/indra/newview/llviewerjointshape.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/** - * @file llviewerjointshape.cpp - * @brief Implementation of LLViewerJointShape class - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -//----------------------------------------------------------------------------- -// Header Files -//----------------------------------------------------------------------------- -#include "llviewerprecompiledheaders.h" - -#include "llviewerjointshape.h" - -#include "llbox.h" -#include "llsphere.h" -#include "llcylinder.h" -#include "llgldbg.h" -#include "llglheaders.h" - -F32 LLViewerJointShape::sColorScale = 1.0f; - -//----------------------------------------------------------------------------- -// LLViewerJointShape() -//----------------------------------------------------------------------------- -LLViewerJointShape::LLViewerJointShape() -{ - mType = ST_NULL; - mColor[0] = 1.0f; - mColor[1] = 1.0f; - mColor[2] = 1.0f; - mColor[3] = 1.0f; - mTexture = NULL; -} - - -//----------------------------------------------------------------------------- -// LLViewerJointShape() -//----------------------------------------------------------------------------- -LLViewerJointShape::LLViewerJointShape( ShapeType type, F32 red, F32 green, F32 blue, F32 alpha ) -{ - mType = type; - mColor[0] = red * sColorScale; - mColor[1] = green * sColorScale; - mColor[2] = blue * sColorScale; - mColor[3] = alpha; - mTexture = NULL; -} - - -//----------------------------------------------------------------------------- -// ~LLViewerJointShape() -// Class Destructor -//----------------------------------------------------------------------------- -LLViewerJointShape::~LLViewerJointShape() -{ -} - - -//-------------------------------------------------------------------- -// getType() -//-------------------------------------------------------------------- -LLViewerJointShape::ShapeType LLViewerJointShape::getType() -{ - return mType; -} - - -//-------------------------------------------------------------------- -// setType() -//-------------------------------------------------------------------- -void LLViewerJointShape::setType( ShapeType type ) -{ - mType = type; -} - - -//-------------------------------------------------------------------- -// getColor() -//-------------------------------------------------------------------- -void LLViewerJointShape::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha ) -{ - *red = mColor[0]; - *green = mColor[1]; - *blue = mColor[2]; - *alpha = mColor[3]; -} - -//-------------------------------------------------------------------- -// setColor() -//-------------------------------------------------------------------- -void LLViewerJointShape::setColor( F32 red, F32 green, F32 blue, F32 alpha ) -{ - mColor[0] = red * sColorScale; - mColor[1] = green * sColorScale; - mColor[2] = blue * sColorScale; - mColor[3] = alpha; -} - - -//-------------------------------------------------------------------- -// getTexture() -//-------------------------------------------------------------------- -LLViewerImage *LLViewerJointShape::getTexture() -{ - return mTexture; -} - -//-------------------------------------------------------------------- -// setTexture() -//-------------------------------------------------------------------- -void LLViewerJointShape::setTexture( LLViewerImage *texture ) -{ - mTexture = texture; -} - - -//-------------------------------------------------------------------- -// drawBone() -//-------------------------------------------------------------------- -void LLViewerJointShape::drawBone() -{ -} - - -//-------------------------------------------------------------------- -// isTransparent() -//-------------------------------------------------------------------- -BOOL LLViewerJointShape::isTransparent() -{ - return ( (mColor[3] < 1.0f) || - (!mTexture.isNull() && (mTexture->getComponents()==4)) ); -} - -//-------------------------------------------------------------------- -// drawShape() -//-------------------------------------------------------------------- -U32 LLViewerJointShape::drawShape( F32 pixelArea, BOOL first_pass ) -{ - U32 triangle_count = 0; - - //---------------------------------------------------------------- - // render ST_NULL - //---------------------------------------------------------------- - if (mType == ST_NULL) - { - return triangle_count; - } - - //---------------------------------------------------------------- - // setup current color - //---------------------------------------------------------------- - glColor4fv(mColor.mV); - - //---------------------------------------------------------------- - // setup current texture - //---------------------------------------------------------------- - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glLoadIdentity(); - if (mType == ST_SPHERE) - { - glTranslatef(-0.25f, 0.0f, 0.0f); - } - glMatrixMode(GL_MODELVIEW); - LLViewerImage::bindTexture(mTexture); - - //---------------------------------------------------------------- - // update pixel area - //---------------------------------------------------------------- - F32 s1 = llmax( getScale().mV[VX], llmax( getScale().mV[VY], getScale().mV[VZ] ) ); - F32 s2 = llmin( getScale().mV[VX], llmax( getScale().mV[VY], getScale().mV[VZ] ) ); - pixelArea *= s1 * s2; - - //---------------------------------------------------------------- - // render shape - //---------------------------------------------------------------- - switch ( mType ) - { - case ST_CUBE: - gBox.render(); - break; - - case ST_SPHERE: - gSphere.render( pixelArea ); - break; - - case ST_CYLINDER: - gCylinder.render( pixelArea ); - break; - - default: - break; - } - - //---------------------------------------------------------------- - // disable texture - //---------------------------------------------------------------- - if ( mTexture ) - { - glMatrixMode(GL_TEXTURE); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - } - - return triangle_count; -} - -// End diff --git a/linden/indra/newview/llviewerjointshape.h b/linden/indra/newview/llviewerjointshape.h deleted file mode 100644 index 91131c7..0000000 --- a/linden/indra/newview/llviewerjointshape.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @file llviewerjointshape.h - * @brief Implementation of LLViewerJointShape class - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLVIEWERJOINTSHAPE_H -#define LL_LLVIEWERJOINTSHAPE_H - -#include "llviewerjoint.h" -#include "llviewerimage.h" - -//----------------------------------------------------------------------------- -// class LLViewerJointShape -//----------------------------------------------------------------------------- -class LLViewerJointShape : - public LLViewerJoint -{ -public: - enum ShapeType - { - ST_NULL, - ST_CUBE, - ST_SPHERE, - ST_CYLINDER - }; - -protected: - ShapeType mType; - LLColor4 mColor; - LLPointer mTexture; - - static F32 sColorScale; - -public: - - // Constructor - LLViewerJointShape(); - LLViewerJointShape( ShapeType type, F32 red, F32 green, F32 blue, F32 alpha ); - - // Destructor - virtual ~LLViewerJointShape(); - - // Gets the shape type - ShapeType getType(); - - // Sets the shape type - void setType( ShapeType type ); - - // Gets the shape color - void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha ); - - // Sets the color scale factor applied to all subsequent setColor() calls. - static void setColorScale( F32 factor ) { sColorScale = factor; } - - // Sets the shape color - void setColor( F32 red, F32 green, F32 blue, F32 alpha ); - - // Gets the shape texture - LLViewerImage *getTexture(); - - // Sets the shape texture - void setTexture( LLViewerImage *texture ); - - virtual void drawBone(); - virtual BOOL isTransparent(); - /*virutal*/ BOOL isAnimatable() { return FALSE; } - /*virtual*/ U32 drawShape( F32 pixelArea, BOOL first_pass ); -}; - -#endif // LL_LLVIEWERJOINTSHAPE_H diff --git a/linden/indra/newview/llviewerkeyboard.cpp b/linden/indra/newview/llviewerkeyboard.cpp index bca447f..6fe1052 100644 --- a/linden/indra/newview/llviewerkeyboard.cpp +++ b/linden/indra/newview/llviewerkeyboard.cpp @@ -473,11 +473,8 @@ void stop_moving( EKeystate s ) void start_chat( EKeystate s ) { - if (!gChatBar->inputEditorHasFocus()) - { - // start chat - gChatBar->startChat(NULL); - } + // start chat + gChatBar->startChat(NULL); } void bind_keyboard_functions() diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp new file mode 100644 index 0000000..0cc4e2d --- /dev/null +++ b/linden/indra/newview/llviewermedia.cpp @@ -0,0 +1,634 @@ +/** + * @file llviewermedia.cpp + * @brief Client interface to the media engine + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llviewermedia.h" + +#include "llmimetypes.h" +#include "llviewercontrol.h" +#include "llviewerimage.h" +#include "llviewerwindow.h" +#include "llversionviewer.h" +#include "llviewerimagelist.h" + +#include "llevent.h" // LLSimpleListener +#include "llmediamanager.h" +#include "lluuid.h" + +// don't want to include llappviewer.h +extern std::string gChannelName; + +// Implementation functions not exported into header file +class LLViewerMediaImpl + : public LLMediaObserver +{ + public: + LLViewerMediaImpl() + : mMediaSource( NULL ), + mMovieImageID(), + mMovieImageHasMips(false) + { } + + void initControlListeners(); + + void destroyMediaSource(); + + void play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop); + + void stop(); + void pause(); + void start(); + void seek(F32 time); + void setVolume(F32 volume); + LLMediaBase::EStatus getStatus(); + + /*virtual*/ void onMediaSizeChange(const EventType& event_in); + /*virtual*/ void onMediaContentsChange(const EventType& event_in); + + void updateMovieImage(const LLUUID& image_id, BOOL active); + void updateImagesMediaStreams(); + LLUUID getMediaTextureID(); + + public: + + // a single media url with some data and an impl. + LLMediaBase* mMediaSource; + LLUUID mMovieImageID; + bool mMovieImageHasMips; + std::string mMediaURL; + std::string mMimeType; + private: + void initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source); +}; + +static LLViewerMediaImpl sViewerMediaImpl; + +void LLViewerMediaImpl::destroyMediaSource() +{ + LLMediaManager* mgr = LLMediaManager::getInstance(); + if ( mMediaSource ) + { + bool was_playing = LLViewerMedia::isMediaPlaying(); + mMediaSource->remObserver(this); + mgr->destroySource( mMediaSource ); + + // Restore the texture + updateMovieImage(LLUUID::null, was_playing); + + } + mMediaSource = NULL; +} + +void LLViewerMediaImpl::play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop) +{ + // first stop any previously playing media + stop(); + + // Save this first, as init/load below may fire events + mMovieImageID = placeholder_texture_id; + + // If the mime_type passed in is different than the cached one, and + // Auto-discovery is turned OFF, replace the cached mime_type with the new one. + if(mime_type != mMimeType && + ! gSavedSettings.getBOOL("AutoMimeDiscovery")) + { + mMimeType = mime_type; + } + LLURI url(media_url); + std::string scheme = url.scheme() != "" ? url.scheme() : "http"; + + LLMediaManager* mgr = LLMediaManager::getInstance(); + mMediaSource = mgr->createSourceFromMimeType(scheme, mMimeType ); + if ( !mMediaSource ) + { + if (mMimeType != "none/none") + { + llwarns << "media source create failed " << media_url + << " type " << mMimeType + << llendl; + } + return; + } + + if ((media_width != 0) && (media_height != 0)) + { + mMediaSource->setRequestedMediaSize(media_width, media_height); + } + + mMediaSource->setLooping(media_loop); + mMediaSource->setAutoScaled(media_auto_scale); + mMediaSource->addObserver( this ); + mMediaSource->navigateTo( media_url ); + mMediaSource->addCommand(LLMediaBase::COMMAND_START); + + // Store the URL and Mime Type + mMediaURL = media_url; + +} + +void LLViewerMediaImpl::stop() +{ + destroyMediaSource(); +} + +void LLViewerMediaImpl::pause() +{ + if(mMediaSource) + { + mMediaSource->addCommand(LLMediaBase::COMMAND_PAUSE); + } +} + +void LLViewerMediaImpl::start() +{ + if(mMediaSource) + { + mMediaSource->addCommand(LLMediaBase::COMMAND_START); + } +} + +void LLViewerMediaImpl::seek(F32 time) +{ + if(mMediaSource) + { + mMediaSource->seek(time); + } +} + +void LLViewerMediaImpl::setVolume(F32 volume) +{ + if(mMediaSource) + { + mMediaSource->setVolume( volume); + } +} + +LLMediaBase::EStatus LLViewerMediaImpl::getStatus() +{ + if (mMediaSource) + { + return mMediaSource->getStatus(); + } + else + { + return LLMediaBase::STATUS_UNKNOWN; + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active) +{ + // IF the media image hasn't changed, do nothing + if (mMovieImageID == uuid) + { + return; + } + // If we have changed media uuid, restore the old one + if (!mMovieImageID.isNull()) + { + LLViewerImage* oldImage = LLViewerImage::getImage( mMovieImageID ); + if (oldImage) + { + oldImage->reinit(mMovieImageHasMips); + oldImage->mIsMediaTexture = FALSE; + } + mMovieImageID.setNull(); + } + // If the movie is playing, set the new media image + if (active && !uuid.isNull()) + { + LLViewerImage* viewerImage = LLViewerImage::getImage( uuid ); + if( viewerImage ) + { + mMovieImageID = uuid; + // Can't use mipmaps for movies because they don't update the full image + mMovieImageHasMips = viewerImage->getUseMipMaps(); + viewerImage->reinit(FALSE); + viewerImage->mIsMediaTexture = TRUE; + } + } +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMediaImpl::updateImagesMediaStreams() +{ + LLMediaManager::updateClass(); +} + +void LLViewerMediaImpl::initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source) +{ + int media_width = media_source->getMediaWidth(); + int media_height = media_source->getMediaHeight(); + //int media_rowspan = media_source->getMediaRowSpan(); + + // if width & height are invalid, don't bother doing anything + if ( media_width < 1 || media_height < 1 ) + return; + + llinfos << "initializing media placeholder" << llendl; + llinfos << "movie image id " << mMovieImageID << llendl; + + int texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width ); + int texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height ); + int texture_depth = media_source->getMediaDepth(); + + // MEDIAOPT: check to see if size actually changed before doing work + placeholder_image->destroyGLTexture(); + // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work? + placeholder_image->reinit(FALSE); // probably not needed + + // MEDIAOPT: seems insane that we actually have to make an imageraw then + // immediately discard it + LLPointer raw = new LLImageRaw(texture_width, texture_height, texture_depth); + raw->clear(0x0f, 0x0f, 0x0f, 0xff); + int discard_level = 0; + + // ask media source for correct GL image format constants + placeholder_image->setExplicitFormat(media_source->getTextureFormatInternal(), + media_source->getTextureFormatPrimary(), + media_source->getTextureFormatType()); + + placeholder_image->createGLTexture(discard_level, raw); + + // placeholder_image->setExplicitFormat() + placeholder_image->setUseMipMaps(FALSE); + + // MEDIAOPT: set this dynamically on play/stop + placeholder_image->mIsMediaTexture = true; +} + + + +// virtual +void LLViewerMediaImpl::onMediaContentsChange(const EventType& event_in) +{ + LLMediaBase* media_source = event_in.getSubject(); + LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID ); + if ((placeholder_image) && (placeholder_image->getHasGLTexture())) + { + if (placeholder_image->getUseMipMaps()) + { + // bad image! NO MIPMAPS! + initializePlaceholderImage(placeholder_image, media_source); + } + + U8* data = media_source->getMediaData(); + S32 x_pos = 0; + S32 y_pos = 0; + S32 width = media_source->getMediaWidth(); + S32 height = media_source->getMediaHeight(); + S32 data_width = media_source->getMediaDataWidth(); + S32 data_height = media_source->getMediaDataHeight(); + placeholder_image->setSubImage(data, data_width, data_height, + x_pos, y_pos, width, height); + } +} + + +// virtual +void LLViewerMediaImpl::onMediaSizeChange(const EventType& event_in) +{ + LLMediaBase* media_source = event_in.getSubject(); + LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID ); + if (placeholder_image) + { + initializePlaceholderImage(placeholder_image, media_source); + } + else + { + llinfos << "no placeholder image" << llendl; + } +} + + + // Get the image we're using + + /* + // update media stream if required + LLMediaEngine* media_engine = LLMediaEngine::getInstance(); + if (media_engine) + { + if ( media_engine->update() ) + { + LLUUID media_uuid = media_engine->getImageUUID(); + updateMovieImage(media_uuid, TRUE); + if (!media_uuid.isNull()) + { + LLViewerImage* viewerImage = getImage( media_uuid ); + if( viewerImage ) + { + LLMediaBase* renderer = media_engine->getMediaRenderer(); + if ((renderer->getTextureWidth() != viewerImage->getWidth()) || + (renderer->getTextureHeight() != viewerImage->getHeight()) || + (renderer->getTextureDepth() != viewerImage->getComponents()) || + (viewerImage->getHasGLTexture() == FALSE)) + { + // destroy existing GL image + viewerImage->destroyGLTexture(); + + // set new size + viewerImage->setSize( renderer->getTextureWidth(), + renderer->getTextureHeight(), + renderer->getTextureDepth() ); + + LLPointer raw = new LLImageRaw(renderer->getTextureWidth(), + renderer->getTextureHeight(), + renderer->getTextureDepth()); + raw->clear(0x7f,0x7f,0x7f,0xff); + viewerImage->createGLTexture(0, raw); + } + + // Set the explicit format the instance wants + viewerImage->setExplicitFormat(renderer->getTextureFormatInternal(), + renderer->getTextureFormatPrimary(), + renderer->getTextureFormatType(), + renderer->getTextureFormatSwapBytes()); + // This should be redundant, but just in case: + viewerImage->setUseMipMaps(FALSE); + + LLImageRaw* rawImage = media_engine->getImageRaw(); + if ( rawImage ) + { + viewerImage->setSubImage(rawImage, 0, 0, + renderer->getMediaWidth(), + renderer->getMediaHeight()); + } + } + else + { + llwarns << "MediaEngine update unable to get viewer image for GL texture" << llendl; + } + } + } + else + { + LLUUID media_uuid = media_engine->getImageUUID(); + updateMovieImage(media_uuid, FALSE); + } + } + */ + + +////////////////////////////////////////////////////////////////////////////////////////// +LLUUID LLViewerMediaImpl::getMediaTextureID() +{ + return mMovieImageID; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// Wrapper class +////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::initClass() +{ + LLMediaManagerData* init_data = new LLMediaManagerData; + +// std::string executable_dir = std::string( arg0 ).substr( 0, std::string( arg0 ).find_last_of("\\/") ); +// std::string component_dir = std::string( executable_dir ).substr( 0, std::string( executable_dir ).find_last_of("\\/") ); +// component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") ); +// component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") ); +// component_dir += "\\newview\\app_settings\\mozilla"; + + +#if LL_DARWIN + // For Mac OS, we store both the shared libraries and the runtime files (chrome/, plugins/, etc) in + // Second Life.app/Contents/MacOS/. This matches the way Firefox is distributed on the Mac. + std::string component_dir(gDirUtilp->getExecutableDir()); +#elif LL_WINDOWS + std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); + component_dir += gDirUtilp->getDirDelimiter(); + #ifdef LL_DEBUG + component_dir += "mozilla_debug"; + #else // LL_DEBUG + component_dir += "mozilla"; + #endif // LL_DEBUG +#elif LL_LINUX + std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); + component_dir += gDirUtilp->getDirDelimiter(); + component_dir += "mozilla-runtime-linux-i686"; +#else + std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); + component_dir += gDirUtilp->getDirDelimiter(); + component_dir += "mozilla"; +#endif + + // append our magic version number string to the browser user agent id + std::ostringstream codec; + codec << "[Second Life "; + codec << "(" << gChannelName << ")"; + codec << " - " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD; + codec << "]"; + init_data->setBrowserUserAgentId( codec.str() ); + + std::string application_dir = gDirUtilp->getExecutableDir(); + + init_data->setBrowserApplicationDir( application_dir ); + std::string profile_dir = gDirUtilp->getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" ); + init_data->setBrowserProfileDir( profile_dir ); + init_data->setBrowserComponentDir( component_dir ); + std::string profile_name("Second Life"); + init_data->setBrowserProfileName( profile_name ); + init_data->setBrowserParentWindow( gViewerWindow->getPlatformWindow() ); + + LLMediaManager::initClass( init_data ); + + LLMediaManager* mm = LLMediaManager::getInstance(); + LLMIMETypes::mime_info_map_t::const_iterator it; + for (it = LLMIMETypes::sMap.begin(); it != LLMIMETypes::sMap.end(); ++it) + { + const LLString& mime_type = it->first; + const LLMIMETypes::LLMIMEInfo& info = it->second; + mm->addMimeTypeImplNameMap( mime_type, info.mImpl ); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::cleanupClass() +{ + LLMediaManager::cleanupClass(); +} + +// static +void LLViewerMedia::play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop) +{ + sViewerMediaImpl.play(media_url, mime_type, placeholder_texture_id, + media_width, media_height, media_auto_scale, media_loop); +} + +// static +void LLViewerMedia::stop() +{ + sViewerMediaImpl.stop(); +} + +// static +void LLViewerMedia::pause() +{ + sViewerMediaImpl.pause(); +} + +// static +void LLViewerMedia::start() +{ + sViewerMediaImpl.start(); +} + +// static +void LLViewerMedia::seek(F32 time) +{ + sViewerMediaImpl.seek(time); +} + +// static +void LLViewerMedia::setVolume(F32 volume) +{ + sViewerMediaImpl.setVolume(volume); +} + +// static +LLMediaBase::EStatus LLViewerMedia::getStatus() +{ + return sViewerMediaImpl.getStatus(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +LLUUID LLViewerMedia::getMediaTextureID() +{ + return sViewerMediaImpl.getMediaTextureID(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::getMediaSize(S32 *media_width, S32 *media_height) +{ + // make sure we're valid + + if ( sViewerMediaImpl.mMediaSource != NULL ) + { + *media_width = sViewerMediaImpl.mMediaSource->getMediaWidth(); + *media_height = sViewerMediaImpl.mMediaSource->getMediaHeight(); + return true; + } + return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::getTextureSize(S32 *texture_width, S32 *texture_height) +{ + if ( sViewerMediaImpl.mMediaSource != NULL ) + { + S32 media_width = sViewerMediaImpl.mMediaSource->getMediaWidth(); + S32 media_height = sViewerMediaImpl.mMediaSource->getMediaHeight(); + *texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width ); + *texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height ); + return true; + } + return false; +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::updateImagesMediaStreams() +{ + sViewerMediaImpl.updateImagesMediaStreams(); +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isMediaPlaying() +{ + LLMediaBase::EStatus status = sViewerMediaImpl.getStatus(); + return (status == LLMediaBase::STATUS_STARTED ); +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isMediaPaused() +{ + LLMediaBase::EStatus status = sViewerMediaImpl.getStatus(); + return (status == LLMediaBase::STATUS_PAUSED); +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::hasMedia() +{ + return sViewerMediaImpl.mMediaSource != NULL; +} + +////////////////////////////////////////////////////////////////////////////////////////// +//static +bool LLViewerMedia::isActiveMediaTexture(const LLUUID& id) +{ + return (id.notNull() + && id == getMediaTextureID() + && isMediaPlaying()); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +std::string LLViewerMedia::getMediaURL() +{ + return sViewerMediaImpl.mMediaURL; +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +std::string LLViewerMedia::getMimeType() +{ + return sViewerMediaImpl.mMimeType; +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setMimeType(std::string mime_type) +{ + sViewerMediaImpl.mMimeType = mime_type; +} + + diff --git a/linden/indra/newview/llviewermedia.h b/linden/indra/newview/llviewermedia.h new file mode 100644 index 0000000..a335117 --- /dev/null +++ b/linden/indra/newview/llviewermedia.h @@ -0,0 +1,72 @@ +/** + * @file llviewermedia.h + * @brief Client interface to the media engine + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLVIEWERMEDIA_H +#define LLVIEWERMEDIA_H + +#include "llmediabase.h" // for status codes + +class LLUUID; + +class LLViewerMedia +{ + public: + static void initClass(); + static void cleanupClass(); + + static void play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop); + static void stop(); + static void pause(); + static void start(); + static void seek(F32 time); + static void setVolume(F32 volume); + static LLMediaBase::EStatus getStatus(); + + static LLUUID getMediaTextureID(); + static bool getMediaSize(S32 *media_width, S32 *media_height); + static bool getTextureSize(S32 *texture_width, S32 *texture_height); + static bool isMediaPlaying(); + static bool isMediaPaused(); + static bool hasMedia(); + static bool isActiveMediaTexture(const LLUUID& id); + + static std::string getMediaURL(); + static std::string getMimeType(); + static void setMimeType(std::string mime_type); + + static void updateImagesMediaStreams(); +}; + +#endif // LLVIEWERMEDIA_H diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 18bdaad..0f48d7d 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -94,6 +94,7 @@ #include "llfloaterbuyland.h" #include "llfloaterchat.h" #include "llfloatercustomize.h" +#include "llfloaterdaycycle.h" #include "llfloaterdirectory.h" #include "llfloatereditui.h" #include "llfloaterchatterbox.h" @@ -104,6 +105,7 @@ #include "llfloatergroupinvite.h" #include "llfloatergroups.h" #include "llfloaterhtml.h" +#include "llfloaterhtmlhelp.h" #include "llfloaterinspect.h" #include "llfloaterlagmeter.h" #include "llfloaterland.h" @@ -112,12 +114,16 @@ #include "llfloatermute.h" #include "llfloateropenobject.h" #include "llfloaterpermissionsmgr.h" +#include "llfloaterpostprocess.h" #include "llfloaterpreference.h" #include "llfloaterregioninfo.h" #include "llfloaterreporter.h" #include "llfloaterscriptdebug.h" +#include "llfloaterenvsettings.h" #include "llfloatertest.h" #include "llfloatertools.h" +#include "llfloaterwater.h" +#include "llfloaterwindlight.h" #include "llfloaterworldmap.h" #include "llframestats.h" #include "llframestatview.h" @@ -192,6 +198,9 @@ #include "llappviewer.h" #include "roles_constants.h" #include "llviewerjoystick.h" +#include "llwlanimator.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" #include "lltexlayer.h" @@ -244,8 +253,8 @@ LLPieMenu *gPieLand = NULL; // local constants const LLString LANDMARK_MENU_NAME("Landmarks"); -const LLString CLIENT_MENU_NAME("Client"); -const LLString SERVER_MENU_NAME("Server"); +const LLString CLIENT_MENU_NAME("Advanced"); +const LLString SERVER_MENU_NAME("Admin"); const LLString SAVE_INTO_INVENTORY("Save Object Back to My Inventory"); const LLString SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents"); @@ -423,7 +432,6 @@ BOOL enable_dehinge(void*); void handle_force_delete(void*); void print_object_info(void*); void print_agent_nvpairs(void*); -void show_debug_menus(); void toggle_debug_menus(void*); void toggle_map( void* user_data ); void export_info_callback(LLAssetInfo *info, void **user_data, S32 result); @@ -612,13 +620,13 @@ void set_underclothes_menu_options() { if (gMenuHolder && gAgent.isTeen()) { - gMenuHolder->getChildByName("Self Underpants", TRUE)->setVisible(FALSE); - gMenuHolder->getChildByName("Self Undershirt", TRUE)->setVisible(FALSE); + gMenuHolder->getChild("Self Underpants", TRUE)->setVisible(FALSE); + gMenuHolder->getChild("Self Undershirt", TRUE)->setVisible(FALSE); } if (gMenuBarView && gAgent.isTeen()) { - gMenuBarView->getChildByName("Menu Underpants", TRUE)->setVisible(FALSE); - gMenuBarView->getChildByName("Menu Undershirt", TRUE)->setVisible(FALSE); + gMenuBarView->getChild("Menu Underpants", TRUE)->setVisible(FALSE); + gMenuBarView->getChild("Menu Undershirt", TRUE)->setVisible(FALSE); } } @@ -655,16 +663,16 @@ void init_menus() gPieSelf = gUICtrlFactory->buildPieMenu("menu_pie_self.xml", gMenuHolder); // TomY TODO: what shall we do about these? - gDetachScreenPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Detach HUD", true); - gDetachPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Detach", true); + gDetachScreenPieMenu = gMenuHolder->getChild("Object Detach HUD", true); + gDetachPieMenu = gMenuHolder->getChild("Object Detach", true); gPieAvatar = gUICtrlFactory->buildPieMenu("menu_pie_avatar.xml", gMenuHolder); gPieObject = gUICtrlFactory->buildPieMenu("menu_pie_object.xml", gMenuHolder); - gAttachScreenPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Attach HUD", true); - gAttachPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Attach", true); - gPieRate = (LLPieMenu*)gMenuHolder->getChildByName("Rate Menu", true); + gAttachScreenPieMenu = gMenuHolder->getChild("Object Attach HUD"); + gAttachPieMenu = gMenuHolder->getChild("Object Attach"); + gPieRate = gMenuHolder->getChild("Rate Menu"); gPieAttachment = gUICtrlFactory->buildPieMenu("menu_pie_attachment.xml", gMenuHolder); @@ -714,8 +722,8 @@ void init_menus() gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", upload_cost); gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", upload_cost); - gAFKMenu = (LLMenuItemCallGL*)gMenuBarView->getChildByName("Set Away", TRUE); - gBusyMenu = (LLMenuItemCallGL*)gMenuBarView->getChildByName("Set Busy", TRUE); + gAFKMenu = gMenuBarView->getChild("Set Away", TRUE); + gBusyMenu = gMenuBarView->getChild("Set Busy", TRUE); gAttachSubMenu = gMenuBarView->getChildMenuByName("Attach Object", TRUE); gDetachSubMenu = gMenuBarView->getChildMenuByName("Detach Object", TRUE); @@ -1100,17 +1108,26 @@ void init_client_menu(LLMenuGL* menu) menu->append(new LLMenuItemCallGL("Debug Settings", LLFloaterSettingsDebug::show, NULL, NULL)); menu->append(new LLMenuItemCheckGL("View Admin Options", &handle_admin_override_toggle, NULL, &check_admin_override, NULL, 'V', MASK_CONTROL | MASK_ALT)); + + menu->append(new LLMenuItemCallGL("Request Admin Status", + &handle_god_mode, NULL, NULL, 'G', MASK_ALT | MASK_CONTROL)); + + menu->append(new LLMenuItemCallGL("Leave Admin Status", + &handle_leave_god_mode, NULL, NULL, 'G', MASK_ALT | MASK_SHIFT | MASK_CONTROL)); + menu->createJumpKeys(); } void init_debug_world_menu(LLMenuGL* menu) { +/* REMOVE mouse move sun from menu options menu->append(new LLMenuItemCheckGL("Mouse Moves Sun", &menu_toggle_control, NULL, &menu_check_control, (void*)"MouseSun", 'M', MASK_CONTROL|MASK_ALT)); +*/ menu->append(new LLMenuItemCheckGL("Sim Sun Override", &menu_toggle_control, NULL, @@ -1179,6 +1196,7 @@ void init_debug_ui_menu(LLMenuGL* menu) menu->appendSeparator(); menu->append(new LLMenuItemCheckGL("Show Time", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowTime")); menu->append(new LLMenuItemCheckGL("Show Render Info", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowRenderInfo")); + menu->append(new LLMenuItemCheckGL("Show Color Under Cursor", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowColor")); menu->createJumpKeys(); } @@ -1322,6 +1340,9 @@ void init_debug_rendering_menu(LLMenuGL* menu) sub_menu->append(new LLMenuItemCheckGL("Occlusion", &LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, (void*)LLPipeline::RENDER_DEBUG_OCCLUSION)); + sub_menu->append(new LLMenuItemCheckGL("Render Batches", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_BATCH_SIZE)); sub_menu->append(new LLMenuItemCheckGL("Animated Textures", &LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, (void*)LLPipeline::RENDER_DEBUG_TEXTURE_ANIM)); @@ -1337,18 +1358,15 @@ void init_debug_rendering_menu(LLMenuGL* menu) sub_menu->append(new LLMenuItemCheckGL("Pick Render", &LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, (void*)LLPipeline::RENDER_DEBUG_PICKING)); + sub_menu->append(new LLMenuItemCheckGL("Lights", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_LIGHTS)); sub_menu->append(new LLMenuItemCheckGL("Particles", &LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, (void*)LLPipeline::RENDER_DEBUG_PARTICLES)); sub_menu->append(new LLMenuItemCheckGL("Composition", &LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, (void*)LLPipeline::RENDER_DEBUG_COMPOSITION)); - sub_menu->append(new LLMenuItemCheckGL("ShadowMap", &LLPipeline::toggleRenderDebug, NULL, - &LLPipeline::toggleRenderDebugControl, - (void*)LLPipeline::RENDER_DEBUG_SHADOW_MAP)); - sub_menu->append(new LLMenuItemCheckGL("LightTrace",&LLPipeline::toggleRenderDebug, NULL, - &LLPipeline::toggleRenderDebugControl, - (void*)LLPipeline::RENDER_DEBUG_LIGHT_TRACE)); sub_menu->append(new LLMenuItemCheckGL("Glow",&LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, (void*)LLPipeline::RENDER_DEBUG_GLOW)); @@ -1373,6 +1391,9 @@ void init_debug_rendering_menu(LLMenuGL* menu) sub_menu->append(new LLMenuItemToggleGL("Randomize Framerate", &gRandomizeFramerate)); sub_menu->append(new LLMenuItemToggleGL("Periodic Slow Frame", &gPeriodicSlowFrame)); + + sub_menu->append(new LLMenuItemToggleGL("Frame Test", &LLPipeline::sRenderFrameTest)); + sub_menu->createJumpKeys(); menu->appendMenu( sub_menu ); @@ -1396,6 +1417,8 @@ void init_debug_rendering_menu(LLMenuGL* menu) item->setEnabled(gGLManager.mHasOcclusionQuery && gFeatureManagerp->isFeatureAvailable("UseOcclusion")); menu->append(item); + item = new LLMenuItemCheckGL("Fast Alpha", menu_toggle_control, NULL, menu_check_control, (void*)"RenderFastAlpha"); + menu->append(item); item = new LLMenuItemCheckGL("Animate Textures", menu_toggle_control, NULL, menu_check_control, (void*)"AnimateTextures"); menu->append(item); @@ -1585,19 +1608,11 @@ void init_server_menu(LLMenuGL* menu) &LLPanelRegionTools::onSaveState, &enable_god_customer_service, NULL)); // menu->append(new LLMenuItemCallGL("Force Join Group", handle_force_join_group)); - - - - menu->appendSeparator(); +// +// menu->appendSeparator(); // // menu->append(new LLMenuItemCallGL( "OverlayTitle", // &handle_show_overlay_title, &enable_god_customer_service, NULL)); - - menu->append(new LLMenuItemCallGL("Request Admin Status", - &handle_god_mode, NULL, NULL, 'G', MASK_ALT | MASK_CONTROL)); - - menu->append(new LLMenuItemCallGL("Leave Admin Status", - &handle_leave_god_mode, NULL, NULL, 'G', MASK_ALT | MASK_SHIFT | MASK_CONTROL)); menu->createJumpKeys(); } @@ -2009,11 +2024,12 @@ class LLSelfEnableRemoveAllAttachments : public view_listener_t if (gAgent.getAvatarObject()) { LLVOAvatar* avatarp = gAgent.getAvatarObject(); - for (LLViewerJointAttachment* attachmentp = avatarp->mAttachmentPoints.getFirstData(); - attachmentp; - attachmentp = avatarp->mAttachmentPoints.getNextData()) + for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); + iter != avatarp->mAttachmentPoints.end(); ) { - if (attachmentp->getObject()) + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if (attachment->getObject()) { new_value = true; break; @@ -2625,12 +2641,10 @@ BOOL check_admin_override(void*) void handle_admin_override_toggle(void*) { - if(!gAgent.getAdminOverride()) - { - gAgent.setAdminOverride(TRUE); - show_debug_menus(); - } - else gAgent.setAdminOverride(FALSE); + gAgent.setAdminOverride(!gAgent.getAdminOverride()); + + // The above may have affected which debug menus are visible + show_debug_menus(); } void handle_god_mode(void*) @@ -2647,7 +2661,6 @@ void set_god_level(U8 god_level) { U8 old_god_level = gAgent.getGodLevel(); gAgent.setGodLevel( god_level ); - show_debug_menus(); gIMMgr->refresh(); gParcelMgr->notifyObservers(); @@ -2679,6 +2692,9 @@ void set_god_level(U8 god_level) LLNotifyBox::showXml("LeavingGodMode", args); } + + // changing god-level can affect which menus we see + show_debug_menus(); } #ifdef TOGGLE_HACKED_GODLIKE_VIEWER @@ -3349,9 +3365,9 @@ class LLEditDuplicate : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if(gEditMenuHandler) + if(LLEditMenuHandler::gEditMenuHandler) { - gEditMenuHandler->duplicate(); + LLEditMenuHandler::gEditMenuHandler->duplicate(); } return true; } @@ -3361,7 +3377,7 @@ class LLEditEnableDuplicate : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool new_value = gEditMenuHandler && gEditMenuHandler->canDuplicate(); + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDuplicate(); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -4443,7 +4459,7 @@ class LLEditEnableCut : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool new_value = gEditMenuHandler && gEditMenuHandler->canCut(); + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCut(); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -4453,9 +4469,9 @@ class LLEditCut : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if( gEditMenuHandler ) + if( LLEditMenuHandler::gEditMenuHandler ) { - gEditMenuHandler->cut(); + LLEditMenuHandler::gEditMenuHandler->cut(); } return true; } @@ -4465,7 +4481,7 @@ class LLEditEnableCopy : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool new_value = gEditMenuHandler && gEditMenuHandler->canCopy(); + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCopy(); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -4475,9 +4491,9 @@ class LLEditCopy : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if( gEditMenuHandler ) + if( LLEditMenuHandler::gEditMenuHandler ) { - gEditMenuHandler->copy(); + LLEditMenuHandler::gEditMenuHandler->copy(); } return true; } @@ -4487,7 +4503,7 @@ class LLEditEnablePaste : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool new_value = gEditMenuHandler && gEditMenuHandler->canPaste(); + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canPaste(); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -4497,9 +4513,9 @@ class LLEditPaste : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if( gEditMenuHandler ) + if( LLEditMenuHandler::gEditMenuHandler ) { - gEditMenuHandler->paste(); + LLEditMenuHandler::gEditMenuHandler->paste(); } return true; } @@ -4509,7 +4525,7 @@ class LLEditEnableDelete : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool new_value = gEditMenuHandler && gEditMenuHandler->canDoDelete(); + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete(); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -4521,9 +4537,9 @@ class LLEditDelete : public view_listener_t { // If a text field can do a deletion, it gets precedence over deleting // an object in the world. - if( gEditMenuHandler && gEditMenuHandler->canDoDelete()) + if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete()) { - gEditMenuHandler->doDelete(); + LLEditMenuHandler::gEditMenuHandler->doDelete(); } // and close any pie/context menus when done @@ -4603,7 +4619,7 @@ class LLEditEnableDeselect : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool new_value = gEditMenuHandler && gEditMenuHandler->canDeselect(); + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDeselect(); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -4613,9 +4629,9 @@ class LLEditDeselect : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if( gEditMenuHandler ) + if( LLEditMenuHandler::gEditMenuHandler ) { - gEditMenuHandler->deselect(); + LLEditMenuHandler::gEditMenuHandler->deselect(); } return true; } @@ -4625,7 +4641,7 @@ class LLEditEnableSelectAll : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool new_value = gEditMenuHandler && gEditMenuHandler->canSelectAll(); + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canSelectAll(); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -4636,9 +4652,9 @@ class LLEditSelectAll : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if( gEditMenuHandler ) + if( LLEditMenuHandler::gEditMenuHandler ) { - gEditMenuHandler->selectAll(); + LLEditMenuHandler::gEditMenuHandler->selectAll(); } return true; } @@ -4649,7 +4665,7 @@ class LLEditEnableUndo : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool new_value = gEditMenuHandler && gEditMenuHandler->canUndo(); + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo(); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -4659,9 +4675,9 @@ class LLEditUndo : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if( gEditMenuHandler && gEditMenuHandler->canUndo() ) + if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo() ) { - gEditMenuHandler->undo(); + LLEditMenuHandler::gEditMenuHandler->undo(); } return true; } @@ -4671,7 +4687,7 @@ class LLEditEnableRedo : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool new_value = gEditMenuHandler && gEditMenuHandler->canRedo(); + bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo(); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -4681,9 +4697,9 @@ class LLEditRedo : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if( gEditMenuHandler && gEditMenuHandler->canRedo() ) + if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo() ) { - gEditMenuHandler->redo(); + LLEditMenuHandler::gEditMenuHandler->redo(); } return true; } @@ -4729,8 +4745,12 @@ void show_debug_menus() gMenuBarView->setItemVisible(CLIENT_MENU_NAME, debug); gMenuBarView->setItemEnabled(CLIENT_MENU_NAME, debug); - gMenuBarView->setItemVisible(SERVER_MENU_NAME, debug); - gMenuBarView->setItemEnabled(SERVER_MENU_NAME, debug); + + // Server ('Admin') menu hidden when not in godmode. + const bool show_server_menu = debug && (gAgent.getGodLevel() > GOD_NOT); + gMenuBarView->setItemVisible(SERVER_MENU_NAME, show_server_menu); + gMenuBarView->setItemEnabled(SERVER_MENU_NAME, show_server_menu); + //gMenuBarView->setItemVisible(LLString("DebugOptions"), visible); //gMenuBarView->setItemVisible(LLString(AVI_TOOLS), visible); }; @@ -5199,40 +5219,6 @@ void handle_force_unlock(void*) gSelectMgr->getSelection()->applyToObjects(&func); } -class LLWorldForceSun : public view_listener_t -{ - bool handleEvent(LLPointer event, const LLSD& userdata) - { - LLString tod = userdata.asString(); - LLVector3 sun_direction; - if (tod == "sunrise") - { - sun_direction.setVec(1.0f, 0.f, 0.2f); - } - else if (tod == "noon") - { - sun_direction.setVec(0.0f, 0.3f, 1.0f); - } - else if (tod == "sunset") - { - sun_direction.setVec(-1.0f, 0.f, 0.2f); - } - else if (tod == "midnight") - { - sun_direction.setVec(0.0f, 0.3f, -1.0f); - } - else - { - gSky.setOverrideSun(FALSE); - return true; - } - sun_direction.normVec(); - gSky.setOverrideSun(TRUE); - gSky.setSunDirection( sun_direction, LLVector3(0.f, 0.f, 0.f)); - return true; - } -}; - void handle_dump_followcam(void*) { LLFollowCamMgr::dump(); @@ -5339,7 +5325,7 @@ class LLShowFloater : public view_listener_t gParcelMgr->selectParcelAt(gAgent.getPositionGlobal()); } - LLFloaterLand::show(); + LLFloaterLand::showInstance(); } else if (floater_name == "buy land") { @@ -5364,25 +5350,7 @@ class LLShowFloater : public view_listener_t } else if (floater_name == "help f1") { -#if LL_LIBXUL_ENABLED - gViewerHtmlHelp.show( gSavedSettings.getString("HelpHomeURL") ); -#endif - } - else if (floater_name == "help in-world") - { -#if LL_LIBXUL_ENABLED - const bool open_app_slurls = true; - LLFloaterHtml::getInstance()->show( - "in-world_help", open_app_slurls ); -#endif - } - else if (floater_name == "help additional") - { -#if LL_LIBXUL_ENABLED - const bool open_app_slurls = true; - LLFloaterHtml::getInstance()->show( - "additional_help", open_app_slurls ); -#endif + gViewerHtmlHelp.show(); } else if (floater_name == "complaint reporter") { @@ -5440,7 +5408,7 @@ class LLFloaterVisible : public view_listener_t } else if (floater_name == "chat history") { - new_value = LLFloaterChat::visible(NULL); + new_value = LLFloaterChat::instanceVisible(); } else if (floater_name == "im") { @@ -5699,9 +5667,9 @@ private: if (selectedObject) { S32 index = userdata.asInteger(); - LLViewerJointAttachment* attachment_point = index > 0 ? - gAgent.getAvatarObject()->mAttachmentPoints[index] : - NULL; + LLViewerJointAttachment* attachment_point = NULL; + if (index > 0) + attachment_point = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL); confirm_replace_attachment(0, attachment_point); } return true; @@ -5719,10 +5687,18 @@ void near_attach_object(BOOL success, void *user_data) { LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; - U8 attachment_id; + U8 attachment_id = 0; if (attachment) { - attachment_id = gAgent.getAvatarObject()->mAttachmentPoints.reverseLookup(attachment); + for (LLVOAvatar::attachment_map_t::iterator iter = gAgent.getAvatarObject()->mAttachmentPoints.begin(); + iter != gAgent.getAvatarObject()->mAttachmentPoints.end(); ++iter) + { + if (iter->second == attachment) + { + attachment_id = iter->first; + break; + } + } } else { @@ -5958,7 +5934,7 @@ class LLAttachmentEnableDrop : public view_listener_t if ( object ) { S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getState()); - attachment_pt = gAgent.getAvatarObject()->mAttachmentPoints.getIfThere(attachmentID); + attachment_pt = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL); if ( attachment_pt ) { @@ -6326,11 +6302,12 @@ void handle_dump_attachments(void*) return; } - for( LLViewerJointAttachment* attachment = avatar->mAttachmentPoints.getFirstData(); - attachment; - attachment = avatar->mAttachmentPoints.getNextData() ) + for (LLVOAvatar::attachment_map_t::iterator iter = avatar->mAttachmentPoints.begin(); + iter != avatar->mAttachmentPoints.end(); ) { - S32 key = avatar->mAttachmentPoints.getCurrentKeyWithoutIncrement(); + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + S32 key = curiter->first; BOOL visible = (attachment->getObject() != NULL && attachment->getObject()->mDrawable.notNull() && !attachment->getObject()->mDrawable->isRenderType(0)); @@ -7107,12 +7084,12 @@ BOOL LLViewerMenuHolderGL::hideMenus() return handled; } -void LLViewerMenuHolderGL::setParcelSelection(LLHandle selection) +void LLViewerMenuHolderGL::setParcelSelection(LLSafeHandle selection) { mParcelSelection = selection; } -void LLViewerMenuHolderGL::setObjectSelection(LLHandle selection) +void LLViewerMenuHolderGL::setObjectSelection(LLSafeHandle selection) { mObjectSelection = selection; } @@ -7120,7 +7097,7 @@ void LLViewerMenuHolderGL::setObjectSelection(LLHandle select const LLRect LLViewerMenuHolderGL::getMenuRect() const { - return LLRect(0, mRect.getHeight() - MENU_BAR_HEIGHT, mRect.getWidth(), STATUS_BAR_HEIGHT); + return LLRect(0, getRect().getHeight() - MENU_BAR_HEIGHT, getRect().getWidth(), STATUS_BAR_HEIGHT); } void handle_save_to_xml(void*) @@ -7163,8 +7140,9 @@ void handle_load_from_xml(void*) void handle_slurl_test(void*) { - LLFloaterHtml::getInstance()->show( - "http://secondlife.com/app/search/slurls.html", "SLURL Test", true); + bool open_app_slurls = true; + bool open_links_externally = false; + LLFloaterHtml::getInstance()->show("http://secondlife.com/app/search/slurls.html", "SLURL Test", open_app_slurls, open_links_externally); } void handle_rebake_textures(void*) @@ -7229,6 +7207,33 @@ class LLViewCheckHighlightTransparent : public view_listener_t } }; +class LLViewBeaconWidth : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLString width = userdata.asString(); + if(width == "1") + { + gSavedSettings.setS32("DebugBeaconLineWidth", 1); + } + else if(width == "4") + { + gSavedSettings.setS32("DebugBeaconLineWidth", 4); + } + else if(width == "16") + { + gSavedSettings.setS32("DebugBeaconLineWidth", 16); + } + else if(width == "32") + { + gSavedSettings.setS32("DebugBeaconLineWidth", 32); + } + + return true; + } +}; + + class LLViewToggleBeacon : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -7535,6 +7540,125 @@ class LLToolsSelectTool : public view_listener_t } }; +/// WINDLIGHT callbacks +class LLWorldEnvSettings : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLString tod = userdata.asString(); + LLVector3 sun_direction; + + if (tod == "editor") + { + // if not there or is hidden, show it + if( !LLFloaterEnvSettings::isOpen() || + !LLFloaterEnvSettings::instance()->getVisible()) { + LLFloaterEnvSettings::show(); + + // otherwise, close it button acts like a toggle + } + else + { + LLFloaterEnvSettings::instance()->close(); + } + return true; + } + + if (tod == "sunrise") + { + // set the value, turn off animation + LLWLParamManager::instance()->mAnimator.setDayTime(0.25); + LLWLParamManager::instance()->mAnimator.mIsRunning = false; + LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + + // then call update once + LLWLParamManager::instance()->mAnimator.update( + LLWLParamManager::instance()->mCurParams); + } + else if (tod == "noon") + { + // set the value, turn off animation + LLWLParamManager::instance()->mAnimator.setDayTime(0.567); + LLWLParamManager::instance()->mAnimator.mIsRunning = false; + LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + + // then call update once + LLWLParamManager::instance()->mAnimator.update( + LLWLParamManager::instance()->mCurParams); + } + else if (tod == "sunset") + { + // set the value, turn off animation + LLWLParamManager::instance()->mAnimator.setDayTime(0.75); + LLWLParamManager::instance()->mAnimator.mIsRunning = false; + LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + + // then call update once + LLWLParamManager::instance()->mAnimator.update( + LLWLParamManager::instance()->mCurParams); + } + else if (tod == "midnight") + { + // set the value, turn off animation + LLWLParamManager::instance()->mAnimator.setDayTime(0.0); + LLWLParamManager::instance()->mAnimator.mIsRunning = false; + LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; + + // then call update once + LLWLParamManager::instance()->mAnimator.update( + LLWLParamManager::instance()->mCurParams); + } + else + { + LLWLParamManager::instance()->mAnimator.mIsRunning = true; + LLWLParamManager::instance()->mAnimator.mUseLindenTime = true; + } + return true; + } +}; + +/// Water Menu callbacks +class LLWorldWaterSettings : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + // if not there or is hidden, show it + if( !LLFloaterWater::isOpen() || + !LLFloaterWater::instance()->getVisible()) { + LLFloaterWater::show(); + + // otherwise, close it button acts like a toggle + } + else + { + LLFloaterWater::instance()->close(); + } + return true; + } +}; + +/// Post-Process callbacks +class LLWorldPostProcess : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFloaterPostProcess::show(); + return true; + } +}; + +/// Day Cycle callbacks +class LLWorldDayCycle : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFloaterDayCycle::show(); + return true; + } +}; + + + static void addMenu(view_listener_t *menu, const char *name) { sMenus.push_back(menu); @@ -7579,6 +7703,7 @@ void initialize_menus() addMenu(new LLViewShowHoverTips(), "View.ShowHoverTips"); addMenu(new LLViewHighlightTransparent(), "View.HighlightTransparent"); addMenu(new LLViewToggleBeacon(), "View.ToggleBeacon"); + addMenu(new LLViewBeaconWidth(), "View.BeaconWidth"); addMenu(new LLViewToggleRenderType(), "View.ToggleRenderType"); addMenu(new LLViewShowHUDAttachments(), "View.ShowHUDAttachments"); addMenu(new LLViewZoomOut(), "View.ZoomOut"); @@ -7614,8 +7739,11 @@ void initialize_menus() addMenu(new LLWorldEnableBuyLand(), "World.EnableBuyLand"); addMenu(new LLWorldCheckAlwaysRun(), "World.CheckAlwaysRun"); - - addMenu(new LLWorldForceSun(), "World.ForceSun"); + + (new LLWorldEnvSettings())->registerListener(gMenuHolder, "World.EnvSettings"); + (new LLWorldWaterSettings())->registerListener(gMenuHolder, "World.WaterSettings"); + (new LLWorldPostProcess())->registerListener(gMenuHolder, "World.PostProcess"); + (new LLWorldDayCycle())->registerListener(gMenuHolder, "World.DayCycle"); // Tools menu addMenu(new LLToolsSelectTool(), "Tools.SelectTool"); diff --git a/linden/indra/newview/llviewermenu.h b/linden/indra/newview/llviewermenu.h index f548182..5565c7f 100644 --- a/linden/indra/newview/llviewermenu.h +++ b/linden/indra/newview/llviewermenu.h @@ -126,14 +126,14 @@ public: virtual BOOL hideMenus(); - void setParcelSelection(LLHandle selection); - void setObjectSelection(LLHandle selection); + void setParcelSelection(LLSafeHandle selection); + void setObjectSelection(LLSafeHandle selection); virtual const LLRect getMenuRect() const; protected: - LLHandle mParcelSelection; - LLHandle mObjectSelection; + LLSafeHandle mParcelSelection; + LLSafeHandle mObjectSelection; }; extern const LLString SAVE_INTO_INVENTORY; diff --git a/linden/indra/newview/llviewermenufile.cpp b/linden/indra/newview/llviewermenufile.cpp index 231da59..a4c55f7 100644 --- a/linden/indra/newview/llviewermenufile.cpp +++ b/linden/indra/newview/llviewermenufile.cpp @@ -39,7 +39,6 @@ #include "llfloateranimpreview.h" #include "llfloaterbuycurrency.h" #include "llfloaterimagepreview.h" -#include "llfloaterimport.h" #include "llfloaternamedesc.h" #include "llfloatersnapshot.h" #include "llinventorymodel.h" // gInventory @@ -53,6 +52,7 @@ #include "llviewerstats.h" #include "llviewerwindow.h" #include "llappviewer.h" +#include "lluploaddialog.h" // linden libraries @@ -210,18 +210,6 @@ const char* upload_pick(void* data) return filename; } -/* -void handle_upload_object(void* data) -{ - const char* filename = upload_pick(data); - if (filename) - { - // start the import - LLFloaterImport* floaterp = new LLFloaterImport(filename); - gUICtrlFactory->buildFloater(floaterp, "floater_import.xml"); - } -}*/ - class LLFileUploadImage : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -410,6 +398,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t width, height, TRUE, + FALSE, gSavedSettings.getBOOL("RenderUIInSnapshot"), FALSE)) { diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index fcebe70..37bd350 100644 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp @@ -47,7 +47,6 @@ #include "lldbstrings.h" #include "lleconomy.h" #include "llfilepicker.h" -#include "llfloaterimport.h" #include "llfocusmgr.h" #include "llfollowcamparams.h" #include "llfloaterreleasemsg.h" @@ -919,37 +918,25 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id, gFloaterMute->selectMute(blocked_id); } - // purge the offer queue of any previously queued inventory offers from the same source. - LLView::child_list_t notification_queue(*(gNotifyBoxView->getChildList())); - for(LLView::child_list_iter_t iter = notification_queue.begin(); - iter != notification_queue.end(); - iter++) + // purge the message queue of any previously queued inventory offers from the same source. + class OfferMatcher : public LLNotifyBoxView::Matcher { - LLNotifyBox* notification = (LLNotifyBox*)*iter; - // scan for other inventory offers (i.e. ignore other types of notifications). - // we can tell by looking for the associated callback they were created with. - if(notification->getNotifyCallback() == inventory_offer_callback) + public: + OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {} + BOOL matches(LLNotifyBox::notify_callback_t callback, void* cb_data) const { - // found one. - // safe to downcast user data because we know it's associated with offer callback. - LLOfferInfo* offer_data = (LLOfferInfo*)notification->getUserData(); - if(offer_data == user_data) - { - continue; // don't remove the msg triggering us. it will be dequeued normally. - } - if(offer_data->mFromID == blocked_id) - { - gNotifyBoxView->removeChild(notification); - } + return callback == inventory_offer_callback && ((LLOfferInfo*)cb_data)->mFromID == blocked_id; } - } + private: + const LLUUID& blocked_id; + }; + gNotifyBoxView->purgeMessagesMatching(OfferMatcher(blocked_id)); } void inventory_offer_callback(S32 button, void* user_data) { LLChat chat; LLString log_message; - LLOfferInfo* info = (LLOfferInfo*)user_data; if(!info) return; @@ -997,7 +984,7 @@ void inventory_offer_callback(S32 button, void* user_data) { if (info->mFromGroup) { - char group_name[MAX_STRING]; /* Flawfinder: ignore */ + std::string group_name; if (gCacheName->getGroupName(info->mFromID, group_name)) { from_string = LLString("An object named '") + info->mFromName + "' owned by the group '" + group_name + "'"; @@ -1011,8 +998,7 @@ void inventory_offer_callback(S32 button, void* user_data) } else { - char first_name[MAX_STRING]; /* Flawfinder: ignore */ - char last_name[MAX_STRING]; /* Flawfinder: ignore */ + std::string first_name, last_name; if (gCacheName->getName(info->mFromID, first_name, last_name)) { from_string = LLString("An object named '") + info->mFromName + "' owned by " + first_name + " " + last_name; @@ -1194,8 +1180,8 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) LLString::format_map_t args; args["[OBJECTNAME]"] = info->mDesc; // must protect against a NULL return from lookupHumanReadable() - const char* typestr = LLAssetType::lookupHumanReadable(info->mType); - if (typestr) + std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType)); + if (!typestr.empty()) { args["[OBJECTTYPE]"] = typestr; } @@ -1213,19 +1199,19 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) // Name cache callbacks don't store userdata, so can't save // off the LLOfferInfo. Argh. JC BOOL name_found = FALSE; - char first_name[MAX_STRING]; /* Flawfinder: ignore */ - char last_name[MAX_STRING]; /* Flawfinder: ignore */ if (info->mFromGroup) { - if (gCacheName->getGroupName(info->mFromID, first_name)) + std::string group_name; + if (gCacheName->getGroupName(info->mFromID, group_name)) { - args["[FIRST]"] = first_name; + args["[FIRST]"] = group_name; args["[LAST]"] = ""; name_found = TRUE; } } else { + std::string first_name, last_name; if (gCacheName->getName(info->mFromID, first_name, last_name)) { args["[FIRST]"] = first_name; @@ -4134,7 +4120,7 @@ void process_alert_core(const std::string& message, BOOL modal) } } -LLLinkedList gMeanCollisionList; +mean_collision_list_t gMeanCollisionList; time_t gLastDisplayedTime = 0; void handle_show_mean_events(void *) @@ -4154,15 +4140,19 @@ void mean_name_callback(const LLUUID &id, const char *first, const char *last, B return; } - while(gMeanCollisionList.getLength() > 20) + static const int max_collision_list_size = 20; + if (gMeanCollisionList.size() > max_collision_list_size) { - gMeanCollisionList.getLastData(); - gMeanCollisionList.deleteCurrentData(); + mean_collision_list_t::iterator iter = gMeanCollisionList.begin(); + for (S32 i=0; imPerp == id) { strncpy(mcd->mFirstName, first, DB_FIRST_NAME_BUF_SIZE -1); /* Flawfinder: ignore */ @@ -4203,12 +4193,12 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use type = (EMeanCollisionType)u8type; - LLMeanCollisionData *mcd; - BOOL b_found = FALSE; - for (mcd = gMeanCollisionList.getFirstData(); mcd; mcd = gMeanCollisionList.getNextData()) + for (mean_collision_list_t::iterator iter = gMeanCollisionList.begin(); + iter != gMeanCollisionList.end(); ++iter) { + LLMeanCollisionData *mcd = *iter; if ((mcd->mPerp == perp) && (mcd->mType == type)) { mcd->mTime = time; @@ -4221,7 +4211,7 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use if (!b_found) { LLMeanCollisionData *mcd = new LLMeanCollisionData(gAgentID, perp, time, type, mag); - gMeanCollisionList.addData(mcd); + gMeanCollisionList.push_front(mcd); const BOOL is_group = FALSE; gCacheName->get(perp, is_group, mean_name_callback); } @@ -4423,9 +4413,23 @@ void script_question_cb(S32 option, void* user_data) notify_cautioned_script_question(cbdata, orig, allowed); } - if ( option == 2 ) + if ( option == 2 ) // mute { gMuteListp->add(LLMute(cbdata->mItemID, cbdata->mObjectName, LLMute::OBJECT)); + + // purge the message queue of any previously queued requests from the same source. DEV-4879 + class OfferMatcher : public LLNotifyBoxView::Matcher + { + public: + OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {} + BOOL matches(LLNotifyBox::notify_callback_t callback, void* cb_data) const + { + return callback == script_question_cb && ((LLScriptQuestionCBData*)cb_data)->mItemID == blocked_id; + } + private: + const LLUUID& blocked_id; + }; + gNotifyBoxView->purgeMessagesMatching(OfferMatcher(cbdata->mItemID)); } delete cbdata; } @@ -5049,7 +5053,7 @@ void callback_load_url(S32 option, void* data) if (0 == option) { - LLWeb::loadURL(infop->mUrl); + LLWeb::loadURL(infop->mUrl); } delete infop; diff --git a/linden/indra/newview/llviewermessage.h b/linden/indra/newview/llviewermessage.h index c271de7..5abd9d1 100644 --- a/linden/indra/newview/llviewermessage.h +++ b/linden/indra/newview/llviewermessage.h @@ -111,6 +111,9 @@ void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data); void process_alert_core(const std::string& message, BOOL modal); // "Mean" or player-vs-player abuse +typedef std::list mean_collision_list_t; +extern mean_collision_list_t gMeanCollisionList; + void handle_show_mean_events(void *); void process_mean_collision_alert_message(LLMessageSystem* msg, void**); diff --git a/linden/indra/newview/llviewerobject.cpp b/linden/indra/newview/llviewerobject.cpp index 50ab57c..056475b 100644 --- a/linden/indra/newview/llviewerobject.cpp +++ b/linden/indra/newview/llviewerobject.cpp @@ -86,7 +86,6 @@ #include "llvolumemessage.h" #include "llvopartgroup.h" #include "llvosky.h" -#include "llvostars.h" #include "llvosurfacepatch.h" #include "llvotextbubble.h" #include "llvotree.h" @@ -96,6 +95,7 @@ #include "llui.h" #include "pipeline.h" #include "llappviewer.h" +#include "llvowlsky.h" //#define DEBUG_UPDATE_TYPE @@ -143,14 +143,14 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco res = new LLVOSurfacePatch(id, pcode, regionp); break; case LL_VO_SKY: res = new LLVOSky(id, pcode, regionp); break; - case LL_VO_STARS: - res = new LLVOStars(id, pcode, regionp); break; case LL_VO_WATER: res = new LLVOWater(id, pcode, regionp); break; case LL_VO_GROUND: res = new LLVOGround(id, pcode, regionp); break; case LL_VO_PART_GROUP: res = new LLVOPartGroup(id, pcode, regionp); break; + case LL_VO_WL_SKY: + res = new LLVOWLSky(id, pcode, regionp); break; default: llwarns << "Unknown object pcode " << (S32)pcode << llendl; res = NULL; break; @@ -193,7 +193,6 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mOnMap(FALSE), mStatic(FALSE), mNumFaces(0), - mLastUpdateFrame(0), mTimeDilation(1.f), mRotTime(0.f), mJointInfo(NULL), @@ -631,17 +630,19 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp) BOOL ret = mDrawable->mXform.setParent(parentp ? &parentp->mXform : NULL); gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); - if (old_parent || (parentp && parentp->isActive())) + if( old_parent != parentp && + old_parent || (parentp && parentp->isActive())) { + // *TODO we should not be relying on setDrawable parent to call markMoved gPipeline.markMoved(mDrawable, FALSE); } - else + else if (!mDrawable->isAvatar()) { mDrawable->updateXform(TRUE); - if (!mDrawable->getSpatialGroup()) + /*if (!mDrawable->getSpatialGroup()) { mDrawable->movePartition(); - } + }*/ } return ret; @@ -677,7 +678,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, LLDataPacker *dp) { LLMemType mt(LLMemType::MTYPE_OBJECT); - U32 retval = 0x0; // Coordinates of objects on simulators are region-local. @@ -2292,7 +2292,7 @@ void LLViewerObject::dirtyInventory() // If there aren't any LLVOInventoryListeners, we won't be // able to update our mInventory when it comes back from the // simulator, so we should not clear the inventory either. - if(mInventory && !mInventoryCallbacks.isEmpty()) + if(mInventory && !mInventoryCallbacks.empty()) { mInventory->clear(); // will deref and delete entries delete mInventory; @@ -2308,20 +2308,22 @@ void LLViewerObject::registerInventoryListener(LLVOInventoryListener* listener, LLInventoryCallbackInfo* info = new LLInventoryCallbackInfo; info->mListener = listener; info->mInventoryData = user_data; - mInventoryCallbacks.addData(info); + mInventoryCallbacks.push_front(info); } void LLViewerObject::removeInventoryListener(LLVOInventoryListener* listener) { - if (listener == NULL) return; - LLInventoryCallbackInfo* info; - for (info = mInventoryCallbacks.getFirstData(); - info; - info = mInventoryCallbacks.getNextData() ) + if (listener == NULL) + return; + for (callback_list_t::iterator iter = mInventoryCallbacks.begin(); + iter != mInventoryCallbacks.end(); ) { + callback_list_t::iterator curiter = iter++; + LLInventoryCallbackInfo* info = *curiter; if (info->mListener == listener) { - mInventoryCallbacks.deleteCurrentData(); + delete info; + mInventoryCallbacks.erase(curiter); break; } } @@ -2329,7 +2331,8 @@ void LLViewerObject::removeInventoryListener(LLVOInventoryListener* listener) void LLViewerObject::clearInventoryListeners() { - mInventoryCallbacks.deleteAllData(); + for_each(mInventoryCallbacks.begin(), mInventoryCallbacks.end(), DeletePointer()); + mInventoryCallbacks.clear(); } void LLViewerObject::requestInventory() @@ -2518,10 +2521,11 @@ void LLViewerObject::loadTaskInvFile(const char* filename) void LLViewerObject::doInventoryCallback() { - for(LLInventoryCallbackInfo* info = mInventoryCallbacks.getFirstData(); - info != NULL; - info = mInventoryCallbacks.getNextData()) + for (callback_list_t::iterator iter = mInventoryCallbacks.begin(); + iter != mInventoryCallbacks.end(); ) { + callback_list_t::iterator curiter = iter++; + LLInventoryCallbackInfo* info = *curiter; if (info->mListener != NULL) { info->mListener->inventoryChanged(this, @@ -2532,7 +2536,8 @@ void LLViewerObject::doInventoryCallback() else { llinfos << "LLViewerObject::doInventoryCallback() deleting bad listener entry." << llendl; - mInventoryCallbacks.deleteCurrentData(); + delete info; + mInventoryCallbacks.erase(curiter); } } mInventoryPending = FALSE; @@ -3063,6 +3068,11 @@ const LLVector3 &LLViewerObject::getPositionRegion() const LLViewerObject *parent = (LLViewerObject *)getParent(); mPositionRegion = parent->getPositionRegion() + (getPosition() * parent->getRotation()); } + else + { + mPositionRegion = getPosition(); + } + return mPositionRegion; } @@ -3088,18 +3098,6 @@ const LLVector3 LLViewerObject::getRenderPosition() const } else { - if (isAvatar()) - { - if (isRoot()) - { - return mDrawable->getPositionAgent(); - } - else - { - return getPosition() * mDrawable->getParent()->getRenderMatrix(); - } - } - return mDrawable->getPositionAgent(); } } @@ -3771,6 +3769,26 @@ S32 LLViewerObject::setTEMediaFlags(const U8 te, const U8 media_flags) return retval; } +S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow) +{ + S32 retval = 0; + const LLTextureEntry *tep = getTE(te); + if (!tep) + { + llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl; + } + else if (glow != tep->getGlow()) + { + retval = LLPrimitive::setTEGlow(te, glow); + setChanged(TEXTURE); + if (mDrawable.notNull() && retval) + { + gPipeline.markTextured(mDrawable); + } + } + return retval; +} + S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t) { @@ -4166,10 +4184,8 @@ void LLViewerObject::updateDrawable(BOOL force_damped) { if (mDrawable.notNull() && !mDrawable->isState(LLDrawable::ON_MOVE_LIST) && - isChanged(MOVED) && - !isAvatar()) + isChanged(MOVED)) { - mLastUpdateFrame = LLFrameTimer::getFrameCount(); BOOL damped_motion = !isChanged(SHIFTED) && // not shifted between regions this frame and... (force_damped || // ...forced into damped motion by application logic or... @@ -4826,12 +4842,31 @@ void LLViewerObject::resetRot() U32 LLViewerObject::getPartitionType() const { - return LLPipeline::PARTITION_NONE; + return LLViewerRegion::PARTITION_NONE; } -BOOL LLAlphaObject::isParticle() +void LLViewerObject::dirtySpatialGroup() const { - return FALSE; + if (mDrawable) + { + LLSpatialGroup* group = mDrawable->getSpatialGroup(); + if (group) + { + group->dirtyGeom(); + } + } +} + +void LLViewerObject::dirtyMesh() const +{ + if (mDrawable) + { + LLSpatialGroup* group = mDrawable->getSpatialGroup(); + if (group) + { + group->dirtyMesh(); + } + } } F32 LLAlphaObject::getPartSize(S32 idx) diff --git a/linden/indra/newview/llviewerobject.h b/linden/indra/newview/llviewerobject.h index 36c6a21..798edf8 100644 --- a/linden/indra/newview/llviewerobject.h +++ b/linden/indra/newview/llviewerobject.h @@ -34,7 +34,6 @@ #include -#include "linked_lists.h" #include "llassetstorage.h" #include "lldarrayptr.h" #include "llhudtext.h" @@ -156,8 +155,6 @@ public: // Return codes for processUpdateMessage enum { MEDIA_URL_REMOVED = 0x1, MEDIA_URL_ADDED = 0x2, MEDIA_URL_UPDATED = 0x4 }; - enum { CLICK_ACTION_TOUCH = 0, CLICK_ACTION_SIT = 1, CLICK_ACTION_BUY = 2 }; - virtual U32 processUpdateMessage(LLMessageSystem *mesgsys, void **user_data, U32 block_num, @@ -196,7 +193,6 @@ public: virtual void updateFaceSize(S32 idx); virtual BOOL updateLOD(); virtual BOOL setDrawableParent(LLDrawable* parentp); - virtual BOOL updateLighting(BOOL do_lighting) { return TRUE; }; F32 getRotTime() { return mRotTime; } void resetRot(); void applyAngularVelocity(F32 dt); @@ -250,11 +246,11 @@ public: //closest to start. virtual BOOL lineSegmentIntersect(const LLVector3& start, LLVector3& end) const; - const LLVector3d getPositionGlobal() const; - const LLVector3 &getPositionRegion() const; - const LLVector3 getPositionEdit() const; - const LLVector3 &getPositionAgent() const; - const LLVector3 getRenderPosition() const; + virtual const LLVector3d getPositionGlobal() const; + virtual const LLVector3 &getPositionRegion() const; + virtual const LLVector3 getPositionEdit() const; + virtual const LLVector3 &getPositionAgent() const; + virtual const LLVector3 getRenderPosition() const; virtual const LLVector3 getPivotPositionAgent() const; // Usually = to getPositionAgent, unless like flex objects it's not @@ -297,6 +293,7 @@ public: /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny ); /*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*/ BOOL setMaterial(const U8 material); virtual void setTEImage(const U8 te, LLViewerImage *imagep); // Not derived from LLPrimitive LLViewerImage *getTEImage(const U8 te) const; @@ -325,6 +322,7 @@ public: // Create if necessary LLAudioSource *getAudioSource(const LLUUID& owner_id); + bool isAudioSource() {return mAudioSourcep != NULL;} U8 getMediaType() const; void setMediaType(U8 media_type); @@ -454,6 +452,8 @@ public: virtual S32 getLOD() const { return 3; } virtual U32 getPartitionType() const; + virtual void dirtySpatialGroup() const; + virtual void dirtyMesh() const; virtual LLNetworkData* getParameterEntry(U16 param_type) const; virtual bool setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin); @@ -480,13 +480,14 @@ public: { LL_VO_CLOUDS = LL_PCODE_APP | 0x20, LL_VO_SURFACE_PATCH = LL_PCODE_APP | 0x30, - LL_VO_STARS = LL_PCODE_APP | 0x40, + //LL_VO_STARS = LL_PCODE_APP | 0x40, LL_VO_SQUARE_TORUS = LL_PCODE_APP | 0x50, LL_VO_SKY = LL_PCODE_APP | 0x60, LL_VO_WATER = LL_PCODE_APP | 0x70, LL_VO_GROUND = LL_PCODE_APP | 0x80, LL_VO_PART_GROUP = LL_PCODE_APP | 0x90, LL_VO_TRIANGLE_TORUS = LL_PCODE_APP | 0xa0, + LL_VO_WL_SKY = LL_PCODE_APP | 0xb0, // should this be moved to 0x40? } EVOType; child_list_t mChildList; @@ -589,7 +590,8 @@ protected: LLVOInventoryListener* mListener; void* mInventoryData; }; - LLLinkedList mInventoryCallbacks; + typedef std::list callback_list_t; + callback_list_t mInventoryCallbacks; S16 mInventorySerialNum; LLViewerRegion *mRegionp; // Region that this object belongs to. @@ -603,9 +605,6 @@ protected: BOOL mStatic; // Object doesn't move. S32 mNumFaces; - S32 mLastUpdateFrame; // frames in which an object had last moved for smart coalescing of drawables - // (child objects not moving relative to parent) - F32 mTimeDilation; // Time dilation sent with the object. F32 mRotTime; // Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega) LLQuaternion mLastRot; // last rotation received from the simulator @@ -671,14 +670,13 @@ public: : LLViewerObject(id,type,regionp) { mDepth = 0.f; } - virtual BOOL isParticle(); virtual F32 getPartSize(S32 idx); virtual void getGeometry(S32 idx, LLStrider& verticesp, LLStrider& normalsp, LLStrider& texcoordsp, LLStrider& colorsp, - LLStrider& indicesp) = 0; + LLStrider& indicesp) = 0; F32 mDepth; }; diff --git a/linden/indra/newview/llviewerobjectlist.cpp b/linden/indra/newview/llviewerobjectlist.cpp index df90954..612baf1 100644 --- a/linden/indra/newview/llviewerobjectlist.cpp +++ b/linden/indra/newview/llviewerobjectlist.cpp @@ -36,6 +36,7 @@ #include "message.h" #include "timing.h" #include "llfasttimer.h" +#include "llglimmediate.h" #include "llviewercontrol.h" #include "llface.h" @@ -45,6 +46,7 @@ #include "llnetmap.h" #include "llagent.h" #include "pipeline.h" +#include "llspatialpartition.h" #include "llhoverview.h" #include "llworld.h" #include "llstring.h" @@ -206,30 +208,28 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, // ignore returned flags objectp->processUpdateMessage(msg, user_data, i, update_type, dpp); - + if (objectp->isDead()) { // The update failed return; } - updateActive(objectp); - - // Also sets the approx. pixel area - objectp->setPixelAreaAndAngle(gAgent); - // Update the image levels of textures for this object. - objectp->updateTextures(gAgent); + updateActive(objectp); if (just_created) { gPipeline.addObject(objectp); } + // Also sets the approx. pixel area + objectp->setPixelAreaAndAngle(gAgent); + // RN: this must be called after we have a drawable // (from gPipeline.addObject) // so that the drawable parent is set properly findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort()); - + // If we're just wandering around, don't create new objects selected. if (just_created && update_type != OUT_TERSE_IMPROVED @@ -528,18 +528,6 @@ void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys, processObjectUpdate(mesgsys, user_data, update_type, true, false); } -void LLViewerObjectList::relightAllObjects() -{ - for (S32 i = 0; i < mObjects.count(); i++) - { - LLDrawable *drawable = mObjects[i]->mDrawable; - if (drawable) - { - gPipeline.markRelight(drawable); - } - } -} - void LLViewerObjectList::dirtyAllObjectInventory() { S32 count = mObjects.count(); @@ -1008,7 +996,7 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) } gPipeline.shiftObjects(offset); - gWorldPointer->mPartSim.shift(offset); + gWorldp->shiftRegions(offset); } void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap) @@ -1109,12 +1097,17 @@ U32 LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, BOOL pick_parce std::vector pick_drawables; - for (i = 0; i < LLPipeline::NUM_PARTITIONS-1; i++) + for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); + iter != gWorldp->getRegionList().end(); ++iter) { - LLSpatialPartition* part = gPipeline.getSpatialPartition(i); - if (part) + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { - part->cull(camera, &pick_drawables, TRUE); + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->cull(camera, &pick_drawables, TRUE); + } } } @@ -1157,11 +1150,11 @@ U32 LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, BOOL pick_parce LLVOAvatar* avatarp = gAgent.getAvatarObject(); if (avatarp) { - LLViewerJointAttachment* attachmentp; - for (attachmentp = avatarp->mAttachmentPoints.getFirstData(); - attachmentp; - attachmentp = avatarp->mAttachmentPoints.getNextData()) + for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); + iter != avatarp->mAttachmentPoints.end(); ) { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachmentp = curiter->second; if (attachmentp->getIsHUDAttachment()) { LLViewerObject* objectp = attachmentp->getObject(); @@ -1213,10 +1206,12 @@ U32 LLViewerObjectList::renderObjectsForSelect(LLCamera &camera, BOOL pick_parce // // Render pass for selected objects // + gGL.start(); gViewerWindow->renderSelections( TRUE, pick_parcel_wall, FALSE ); // render pickable ui elements, like names, etc. LLHUDObject::renderAllForSelect(); + gGL.stop(); gRenderForSelect = FALSE; diff --git a/linden/indra/newview/llviewerobjectlist.h b/linden/indra/newview/llviewerobjectlist.h index d08dc9c..a8fb245 100644 --- a/linden/indra/newview/llviewerobjectlist.h +++ b/linden/indra/newview/llviewerobjectlist.h @@ -36,10 +36,8 @@ #include // common includes -#include "doublelinkedlist.h" #include "llstat.h" #include "lldarrayptr.h" -#include "llskipmap.h" #include "llstring.h" // project includes @@ -104,7 +102,6 @@ public: void renderObjectBeacons(); void resetObjectBeacons(); - void relightAllObjects(); void dirtyAllObjectInventory(); void updateActive(LLViewerObject *objectp); diff --git a/linden/indra/newview/llviewerparcelmedia.cpp b/linden/indra/newview/llviewerparcelmedia.cpp new file mode 100644 index 0000000..cd0197c --- /dev/null +++ b/linden/indra/newview/llviewerparcelmedia.cpp @@ -0,0 +1,363 @@ +/** + * @file llviewerparcelmedia.cpp + * @brief Handlers for multimedia on a per-parcel basis + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llviewerparcelmedia.h" + +#include "llagent.h" +#include "llviewercontrol.h" +#include "llviewermedia.h" +#include "llviewerregion.h" +#include "llparcel.h" +#include "llviewerparcelmgr.h" +#include "lluuid.h" +#include "message.h" +#include "llviewerparcelmediaautoplay.h" +#include "llfirstuse.h" + +// Static Variables + +S32 LLViewerParcelMedia::sMediaParcelLocalID = 0; +LLUUID LLViewerParcelMedia::sMediaRegionID; + +// Move this to its own file. +// helper class that tries to download a URL from a web site and calls a method +// on the Panel Land Media and to discover the MIME type +class LLMimeDiscoveryResponder : public LLHTTPClient::Responder +{ +public: + LLMimeDiscoveryResponder( ) + {} + + + + virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content) + { + std::string media_type = content["content-type"].asString(); + std::string::size_type idx1 = media_type.find_first_of(";"); + std::string mime_type = media_type.substr(0, idx1); + completeAny(status, mime_type); + } + + virtual void error( U32 status, const std::string& reason ) + { + completeAny(status, "none/none"); + } + + void completeAny(U32 status, const std::string& mime_type) + { + LLViewerMedia::setMimeType(mime_type); + } +}; + +// static +void LLViewerParcelMedia::initClass() +{ + LLMessageSystem* msg = gMessageSystem; + msg->setHandlerFunc("ParcelMediaCommandMessage", processParcelMediaCommandMessage ); + msg->setHandlerFunc("ParcelMediaUpdate", processParcelMediaUpdate ); + LLViewerParcelMediaAutoPlay::initClass(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerParcelMedia::update(LLParcel* parcel) +{ + if (/*LLViewerMedia::hasMedia()*/ true) + { + // we have a player + if (parcel) + { + // we're in a parcel + bool new_parcel = false; + S32 parcelid = parcel->getLocalID(); + LLUUID regionid = gAgent.getRegion()->getRegionID(); + if (parcelid != sMediaParcelLocalID || regionid != sMediaRegionID) + { + sMediaParcelLocalID = parcelid; + sMediaRegionID = regionid; + new_parcel = true; + } + + std::string mediaUrl = std::string ( parcel->getMediaURL () ); + LLString::trim(mediaUrl); + + // has something changed? + if ( ( LLViewerMedia::getMediaURL() != mediaUrl ) + || ( LLViewerMedia::getMediaTextureID() != parcel->getMediaID () ) ) + { + bool video_was_playing = FALSE; + bool same_media_id = LLViewerMedia::getMediaTextureID() == parcel->getMediaID (); + + if (LLViewerMedia::isMediaPlaying()) + { + video_was_playing = TRUE; + } + + if ( !mediaUrl.empty() && same_media_id && ! new_parcel) + { + // Someone has "changed the channel", changing the URL of a video + // you were already watching. Automatically play provided the texture ID is the same + if (video_was_playing) + { + // Poke the mime type in before calling play. + // This is necessary because in this instance we are not waiting + // for the results of a header curl. In order to change the channel + // a mime type MUST be provided. + LLViewerMedia::setMimeType(parcel->getMediaType()); + play(parcel); + } + } + else + { + stop(); + } + + // Discover the MIME type + // Disabled for the time being. Get the mime type from the parcel. + if(gSavedSettings.getBOOL("AutoMimeDiscovery")) + { + LLHTTPClient::getHeaderOnly( mediaUrl, new LLMimeDiscoveryResponder()); + } + else + { + LLViewerMedia::setMimeType(parcel->getMediaType()); + } + + } + } + else + { + stop(); + } + } + /* + else + { + // no audio player, do a first use dialog if their is media here + if (parcel) + { + std::string mediaUrl = std::string ( parcel->getMediaURL () ); + if (!mediaUrl.empty ()) + { + if (gSavedSettings.getWarning("QuickTimeInstalled")) + { + gSavedSettings.setWarning("QuickTimeInstalled", FALSE); + + LLNotifyBox::showXml("NoQuickTime" ); + }; + } + } + } + */ +} + +// static +void LLViewerParcelMedia::play(LLParcel* parcel) +{ + lldebugs << "LLViewerParcelMedia::play" << llendl; + + if (!parcel) return; + + if (!gSavedSettings.getBOOL("AudioStreamingVideo")) + return; + + std::string media_url = parcel->getMediaURL(); + std::string mime_type = parcel->getMediaType(); + LLUUID placeholder_texture_id = parcel->getMediaID(); + U8 media_auto_scale = parcel->getMediaAutoScale(); + U8 media_loop = parcel->getMediaLoop(); + S32 media_width = parcel->getMediaWidth(); + S32 media_height = parcel->getMediaHeight(); + LLViewerMedia::play(media_url, mime_type, placeholder_texture_id, + media_width, media_height, media_auto_scale, + media_loop); + LLFirstUse::useMedia(); + + LLViewerParcelMediaAutoPlay::playStarted(); +} + +// static +void LLViewerParcelMedia::stop() +{ + + LLViewerMedia::stop(); +} + +// static +void LLViewerParcelMedia::pause() +{ + LLViewerMedia::pause(); +} + +// static +void LLViewerParcelMedia::start() +{ + LLViewerMedia::start(); + LLFirstUse::useMedia(); + + LLViewerParcelMediaAutoPlay::playStarted(); +} + +// static +void LLViewerParcelMedia::seek(F32 time) +{ + LLViewerMedia::seek(time); +} + + +// static +LLMediaBase::EStatus LLViewerParcelMedia::getStatus() +{ + return LLViewerMedia::getStatus(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg, void ** ) +{ + // extract the agent id + // LLUUID agent_id; + // msg->getUUID( agent_id ); + + U32 flags; + U32 command; + F32 time; + msg->getU32( "CommandBlock", "Flags", flags ); + msg->getU32( "CommandBlock", "Command", command); + msg->getF32( "CommandBlock", "Time", time ); + + if (flags &( (1<getAgentParcel(); + play(parcel); + } + } + else + // loop + if( command == PARCEL_MEDIA_COMMAND_LOOP ) + { + //llinfos << ">>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl; + + // huh? what is play? + //convertImageAndLoadUrl( play ); + //convertImageAndLoadUrl( true, false, std::string() ); + } + else + // unload + if( command == PARCEL_MEDIA_COMMAND_UNLOAD ) + { + stop(); + } + } + + if (flags & (1<getAgentParcel(); + play(parcel); + } + seek(time); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void ** ) +{ + LLUUID media_id; + std::string media_url; + std::string media_type; + S32 media_width = 0; + S32 media_height = 0; + U8 media_auto_scale = FALSE; + U8 media_loop = FALSE; + + msg->getUUID( "DataBlock", "MediaID", media_id ); + char media_url_buffer[257]; + msg->getString( "DataBlock", "MediaURL", 255, media_url_buffer ); + media_url = media_url_buffer; + msg->getU8("DataBlock", "MediaAutoScale", media_auto_scale); + + if (msg->getNumberOfBlocks("DataBlockExtended")) // do we have the extended data? + { + char media_type_buffer[257]; + msg->getString("DataBlockExtended", "MediaType", 255, media_type_buffer); + media_type = media_type_buffer; + msg->getU8("DataBlockExtended", "MediaLoop", media_loop); + msg->getS32("DataBlockExtended", "MediaWidth", media_width); + msg->getS32("DataBlockExtended", "MediaHeight", media_height); + } + + LLParcel *parcel = gParcelMgr->getAgentParcel(); + BOOL same = FALSE; + if (parcel) + { + same = ((parcel->getMediaURL() == media_url) && + (parcel->getMediaType() == media_type) && + (parcel->getMediaID() == media_id) && + (parcel->getMediaWidth() == media_width) && + (parcel->getMediaHeight() == media_height) && + (parcel->getMediaAutoScale() == media_auto_scale) && + (parcel->getMediaLoop() == media_loop)); + } + + if (!same) + LLViewerMedia::play(media_url, media_type, media_id, + media_auto_scale, media_width, media_height, + media_loop); +} diff --git a/linden/indra/newview/llviewerparcelmedia.h b/linden/indra/newview/llviewerparcelmedia.h new file mode 100644 index 0000000..70888ab --- /dev/null +++ b/linden/indra/newview/llviewerparcelmedia.h @@ -0,0 +1,75 @@ +/** + * @file llviewerparcelmedia.h + * @brief Handlers for multimedia on a per-parcel basis + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLVIEWERPARCELMEDIA_H +#define LLVIEWERPARCELMEDIA_H + +#include "llmediabase.h" + +class LLMessageSystem; +class LLParcel; + +// This class understands land parcels, network traffic, LSL media +// transport commands, and talks to the LLViewerMedia class to actually +// do playback. It allows us to remove code from LLViewerParcelMgr. +class LLViewerParcelMedia +{ + public: + static void initClass(); + + static void update(LLParcel* parcel); + // called when the agent's parcel has a new URL, or the agent has + // walked on to a new parcel with media + + static void play(LLParcel* parcel); + // user clicked play button in media transport controls + + static void stop(); + // user clicked stop button in media transport controls + + static void pause(); + static void start(); + // restart after pause - no need for all the setup + + static void seek(F32 time); + // jump to timecode time + + static LLMediaBase::EStatus getStatus(); + + static void processParcelMediaCommandMessage( LLMessageSystem *msg, void ** ); + static void processParcelMediaUpdate( LLMessageSystem *msg, void ** ); + + public: + static S32 sMediaParcelLocalID; + static LLUUID sMediaRegionID; +}; + +#endif diff --git a/linden/indra/newview/llviewerparcelmediaautoplay.cpp b/linden/indra/newview/llviewerparcelmediaautoplay.cpp new file mode 100644 index 0000000..854ba24 --- /dev/null +++ b/linden/indra/newview/llviewerparcelmediaautoplay.cpp @@ -0,0 +1,151 @@ +/** + * @file llviewerparcelmediaautoplay.cpp + * @brief timer to automatically play media in a parcel + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llviewerparcelmediaautoplay.h" +#include "llviewerparcelmedia.h" +#include "llviewercontrol.h" +#include "llviewermedia.h" +#include "llparcel.h" +#include "llviewerparcelmgr.h" +#include "lluuid.h" +#include "message.h" +#include "llviewerimagelist.h" // for texture stats +#include "llagent.h" + +const F32 AUTOPLAY_TIME = 5; // how many seconds before we autoplay +const F32 AUTOPLAY_SIZE = 24*24; // how big the texture must be (pixel area) before we autoplay +const F32 AUTOPLAY_SPEED = 0.1f; // how slow should the agent be moving to autoplay + +LLViewerParcelMediaAutoPlay::LLViewerParcelMediaAutoPlay() : + LLEventTimer(1), + mPlayed(FALSE), + mTimeInParcel(0) +{ +} + +static LLViewerParcelMediaAutoPlay *sAutoPlay = NULL; + +// static +void LLViewerParcelMediaAutoPlay::initClass() +{ + if (!sAutoPlay) + sAutoPlay = new LLViewerParcelMediaAutoPlay; +} + +// static +void LLViewerParcelMediaAutoPlay::cleanupClass() +{ + if (sAutoPlay) + delete sAutoPlay; +} + +// static +void LLViewerParcelMediaAutoPlay::playStarted() +{ + if (sAutoPlay) + { + sAutoPlay->mPlayed = TRUE; + } +} + +BOOL LLViewerParcelMediaAutoPlay::tick() +{ + LLParcel *this_parcel = NULL; + std::string this_media_url; + LLUUID this_media_texture_id; + S32 this_parcel_id = 0; + + if (gParcelMgr) + { + this_parcel = gParcelMgr->getAgentParcel(); + } + + if (this_parcel) + { + this_media_url = std::string(this_parcel->getMediaURL()); + + this_media_texture_id = this_parcel->getMediaID(); + + this_parcel_id = this_parcel->getLocalID(); + } + + if (this_parcel_id != mLastParcelID) + { + // we've entered a new parcel + mPlayed = FALSE; // we haven't autoplayed yet + mTimeInParcel = 0; // reset our timer + mLastParcelID = this_parcel_id; + } + + mTimeInParcel += mPeriod; // increase mTimeInParcel by the amount of time between ticks + + if ((!mPlayed) && // if we've never played + (mTimeInParcel > AUTOPLAY_TIME) && // and if we've been here for so many seconds + (this_media_url.size() != 0) && // and if the parcel has media + (!LLViewerMedia::isMediaPlaying())) // and if the media is not already playing + { + if (this_media_texture_id.notNull()) // and if the media texture is good + { + LLViewerImage *image = gImageList.getImage(this_media_texture_id, FALSE); + + F32 image_size = 0; + + if (image) + { + image_size = image->mMaxVirtualSize; + } + + if (gAgent.getVelocity().magVec() < AUTOPLAY_SPEED) // and if the agent is stopped (slow enough) + { + if (image_size > AUTOPLAY_SIZE) // and if the target texture is big enough on screen + { + if (this_parcel) + { + if (gSavedSettings.getBOOL("ParcelMediaAutoPlayEnable")) + { + // and last but not least, only play when autoplay is enabled + LLViewerParcelMedia::play(this_parcel); + } + } + + mPlayed = TRUE; + } + } + } + } + + + return FALSE; // continue ticking forever please. +} + + + diff --git a/linden/indra/newview/llviewerparcelmediaautoplay.h b/linden/indra/newview/llviewerparcelmediaautoplay.h new file mode 100644 index 0000000..48d3a36 --- /dev/null +++ b/linden/indra/newview/llviewerparcelmediaautoplay.h @@ -0,0 +1,55 @@ +/** + * @file llviewerparcelmediaautoplay.h + * @brief timer to automatically play media in a parcel + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLVIEWERPARCELMEDIAAUTOPLAY_H +#define LLVIEWERPARCELMEDIAAUTOPLAY_H + +#include "llmediabase.h" +#include "lltimer.h" + +// timer to automatically play media +class LLViewerParcelMediaAutoPlay : LLEventTimer +{ + public: + LLViewerParcelMediaAutoPlay(); + virtual BOOL tick(); + static void initClass(); + static void cleanupClass(); + static void playStarted(); + + private: + S32 mLastParcelID; + BOOL mPlayed; + F32 mTimeInParcel; +}; + + +#endif // LLVIEWERPARCELMEDIAAUTOPLAY_H diff --git a/linden/indra/newview/llviewerparcelmgr.cpp b/linden/indra/newview/llviewerparcelmgr.cpp index 4730799..de88ac0 100644 --- a/linden/indra/newview/llviewerparcelmgr.cpp +++ b/linden/indra/newview/llviewerparcelmgr.cpp @@ -38,7 +38,6 @@ #include "indra_constants.h" #include "llcachename.h" #include "llgl.h" -#include "llmediaengine.h" #include "llparcel.h" #include "llsecondlifeurls.h" #include "message.h" @@ -55,14 +54,17 @@ #include "llfloatersellland.h" #include "llfloatertools.h" #include "llnotify.h" +#include "llparcelselection.h" #include "llresmgr.h" +#include "llsdutil.h" #include "llstatusbar.h" #include "llui.h" +#include "llviewerimage.h" #include "llviewerimagelist.h" #include "llviewermenu.h" +#include "llviewerparcelmedia.h" #include "llviewerparceloverlay.h" #include "llviewerregion.h" -//#include "llwebbrowserctrl.h" #include "llworld.h" #include "lloverlaybar.h" #include "roles_constants.h" @@ -78,11 +80,8 @@ U8* LLViewerParcelMgr::sPackedOverlay = NULL; LLUUID gCurrentMovieID = LLUUID::null; -static LLParcelSelection* get_null_parcel_selection(); -template<> - const LLHandle::NullFunc - LLHandle::sNullFunc = get_null_parcel_selection; - +LLPointer sBlockedImage; +LLPointer sPassImage; // Local functions void optionally_start_music(const LLString& music_url); @@ -141,10 +140,10 @@ LLViewerParcelMgr::LLViewerParcelMgr() resetSegments(mCollisionSegments); mBlockedImageID.set(gViewerArt.getString("noentrylines.tga")); - mBlockedImage = gImageList.getImage(mBlockedImageID, TRUE, TRUE); + sBlockedImage = gImageList.getImage(mBlockedImageID, TRUE, TRUE); mPassImageID.set(gViewerArt.getString("noentrypasslines.tga")); - mPassImage = gImageList.getImage(mPassImageID, TRUE, TRUE); + sPassImage = gImageList.getImage(mPassImageID, TRUE, TRUE); S32 overlay_size = mParcelsPerEdge * mParcelsPerEdge / PARCEL_OVERLAY_CHUNKS; sPackedOverlay = new U8[overlay_size]; @@ -189,6 +188,9 @@ LLViewerParcelMgr::~LLViewerParcelMgr() delete[] mAgentParcelOverlay; mAgentParcelOverlay = NULL; + + sBlockedImage = NULL; + sPassImage = NULL; } void LLViewerParcelMgr::dump() @@ -1255,30 +1257,46 @@ const LLString& LLViewerParcelMgr::getAgentParcelName() const } -void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel) +void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region) { if (!parcel) return; if(!gWorldp) return; - LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion *region = use_agent_region ? gAgent.getRegion() : gWorldp->getRegionFromPosGlobal( mWestSouth ); if (!region) return; - LLMessageSystem *msg = gMessageSystem; + LLSD body; + std::string url = gAgent.getRegion()->getCapability("ParcelPropertiesUpdate"); + if (!url.empty()) + { + U32 message_flags = 0x01; + // request new properties update from simulator + body["flags"] = ll_sd_from_U32(message_flags); + parcel->packMessage(body); - msg->newMessageFast(_PREHASH_ParcelPropertiesUpdate); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ParcelData); - msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID() ); + llinfos << "Sending parcel properties update via capability to:" << url << llendl; - U32 flags = 0x0; - // request new properties update from simulator - flags |= 0x01; - msg->addU32("Flags", flags); + LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); + } + else + { + LLMessageSystem *msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_ParcelPropertiesUpdate); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ParcelData); + msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID() ); + + U32 message_flags = 0x01; + msg->addU32("Flags", message_flags); + + parcel->packMessage(msg); + + msg->sendReliable( region->getHost() ); + } - parcel->packMessage(msg); - msg->sendReliable( region->getHost() ); } @@ -1363,7 +1381,6 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user) } } - // static void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **user) { @@ -1657,19 +1674,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } else { - // It's the agent parcel - BOOL new_parcel = parcel ? FALSE : TRUE; - if (parcel) - { - S32 parcelid = parcel->getLocalID(); - U64 regionid = gAgent.getRegion()->getHandle(); - if (parcelid != gParcelMgr->mMediaParcelId || regionid != gParcelMgr->mMediaRegionId) - { - gParcelMgr->mMediaParcelId = parcelid; - gParcelMgr->mMediaRegionId = regionid; - new_parcel = TRUE; - } - } // look for music. if (gAudiop) { @@ -1714,75 +1718,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use }//if gAudiop // now check for video - if (LLMediaEngine::getInstance ()->isAvailable ()) - { - // we have a player - if (parcel) - { - // we're in a parcel - std::string mediaUrl = std::string ( parcel->getMediaURL () ); - LLString::trim(mediaUrl); - - // clean spaces and whatnot - mediaUrl = LLWeb::escapeURL(mediaUrl); - - - // something changed - LLMediaEngine* me = LLMediaEngine::getInstance(); - if ( ( me->getUrl () != mediaUrl ) - || ( me->getImageUUID () != parcel->getMediaID () ) - || ( me->isAutoScaled () != parcel->getMediaAutoScale () ) ) - { - BOOL video_was_playing = FALSE; - LLMediaBase* renderer = me->getMediaRenderer(); - if (renderer && (renderer->isPlaying() || renderer->isLooping())) - { - video_was_playing = TRUE; - } - - stop_video(); - - if ( !mediaUrl.empty () ) - { - // Someone has "changed the channel", changing the URL of a video - // you were already watching. Do we want to automatically start playing? JC - if (!new_parcel - && gSavedSettings.getBOOL("AudioStreamingVideo") - && video_was_playing) - { - start_video(parcel); - } - else - { - // "Prepare" the media engine, but don't auto-play. JC - optionally_prepare_video(parcel); - } - } - } - } - else - { - stop_video(); - } - } - else - { - // no audio player, do a first use dialog if their is media here - if (parcel) - { - std::string mediaUrl = std::string ( parcel->getMediaURL () ); - if (!mediaUrl.empty ()) - { - if (gSavedSettings.getWarning("QuickTimeInstalled")) - { - gSavedSettings.setWarning("QuickTimeInstalled", FALSE); - - LLNotifyBox::showXml("NoQuickTime" ); - }; - } - } - } - + LLViewerParcelMedia::update( parcel ); }; } @@ -1835,94 +1771,6 @@ void callback_start_music(S32 option, void* data) music_url = NULL; } -void prepare_video(const LLParcel *parcel) -{ - std::string mediaUrl; - if (parcel->getParcelFlag(PF_URL_RAW_HTML)) - { - mediaUrl = std::string("data:"); - mediaUrl.append(parcel->getMediaURL()); - } - else - { - mediaUrl = std::string ( parcel->getMediaURL () ); - } - - // clean spaces and whatnot - mediaUrl = LLWeb::escapeURL(mediaUrl); - - LLMediaEngine::getInstance ()->setUrl ( mediaUrl ); - LLMediaEngine::getInstance ()->setImageUUID ( parcel->getMediaID () ); - LLMediaEngine::getInstance ()->setAutoScaled ( parcel->getMediaAutoScale () ? TRUE : FALSE ); // (U8 instead of BOOL for future expansion) -} - -void start_video(const LLParcel *parcel) -{ - prepare_video(parcel); - std::string path( "" ); - LLMediaEngine::getInstance ()->convertImageAndLoadUrl ( true, false, path); -} - -void stop_video() -{ - // set up remote control so stop is selected - LLMediaEngine::getInstance ()->stop (); - if (gOverlayBar) - { - gOverlayBar->refresh (); - } - - if (LLMediaEngine::getInstance ()->isLoaded()) - { - LLMediaEngine::getInstance ()->unload (); - - gImageList.updateMovieImage(LLUUID::null, FALSE); - gCurrentMovieID.setNull(); - } - - LLMediaEngine::getInstance ()->setUrl ( "" ); - LLMediaEngine::getInstance ()->setImageUUID ( LLUUID::null ); - -} - -void optionally_prepare_video(const LLParcel *parcelp) -{ - if (gSavedSettings.getWarning("FirstStreamingVideo")) - { - gViewerWindow->alertXml("ParcelCanPlayMedia", - callback_prepare_video, - (void*)parcelp); - } - else - { - llinfos << "Entering parcel " << parcelp->getLocalID() << " with video " << parcelp->getMediaURL() << llendl; - prepare_video(parcelp); - } -} - - -void callback_prepare_video(S32 option, void* data) -{ - const LLParcel *parcelp = (const LLParcel *)data; - - if (0 == option) - { - gSavedSettings.setBOOL("AudioStreamingVideo", TRUE); - llinfos << "Starting parcel video " << parcelp->getMediaURL() << " on parcel " << parcelp->getLocalID() << llendl; - gMessageSystem->setHandlerFunc("ParcelMediaCommandMessage", LLMediaEngine::process_parcel_media); - gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", LLMediaEngine::process_parcel_media_update ); - prepare_video(parcelp); - } - else - { - gMessageSystem->setHandlerFunc("ParcelMediaCommandMessage", null_message_callback); - gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", null_message_callback ); - gSavedSettings.setBOOL("AudioStreamingVideo", FALSE); - } - - gSavedSettings.setWarning("FirstStreamingVideo", FALSE); -} - // static void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void **user) { @@ -2123,17 +1971,14 @@ void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 which) void LLViewerParcelMgr::deedLandToGroup() { - char group_name[MAX_STRING]; /* Flawfinder: ignore */ + std::string group_name; gCacheName->getGroupName(mCurrentParcel->getGroupID(), group_name); LLString::format_map_t args; args["[AREA]"] = llformat("%d", mCurrentParcel->getArea()); args["[GROUP_NAME]"] = group_name; if(mCurrentParcel->getContributeWithDeed()) { - char first_name[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - first_name[0] = '\0'; - char last_name[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - last_name[0] = '\0'; + std::string first_name, last_name; gCacheName->getName(mCurrentParcel->getOwnerID(), first_name, last_name); args["[FIRST_NAME]"] = first_name; args["[LAST_NAME]"] = last_name; @@ -2551,71 +2396,20 @@ void sanitize_corners(const LLVector3d &corner1, east_north_top.mdV[VZ] = llmax( corner1.mdV[VZ], corner2.mdV[VZ] ); } -// -// LLParcelSelection -// -LLParcelSelection::LLParcelSelection() : - mParcel(NULL), - mSelectedMultipleOwners(FALSE), - mWholeParcelSelected(FALSE), - mSelectedSelfCount(0), - mSelectedOtherCount(0), - mSelectedPublicCount(0) -{ -} - -LLParcelSelection::LLParcelSelection(LLParcel* parcel) : - mParcel(parcel), - mSelectedMultipleOwners(FALSE), - mWholeParcelSelected(FALSE), - mSelectedSelfCount(0), - mSelectedOtherCount(0), - mSelectedPublicCount(0) -{ -} -LLParcelSelection::~LLParcelSelection() -{ -} - -BOOL LLParcelSelection::getMultipleOwners() const -{ - return mSelectedMultipleOwners; -} - - -BOOL LLParcelSelection::getWholeParcelSelected() const -{ - return mWholeParcelSelected; -} - - -S32 LLParcelSelection::getClaimableArea() const -{ - const S32 UNIT_AREA = S32( PARCEL_GRID_STEP_METERS * PARCEL_GRID_STEP_METERS ); - return mSelectedPublicCount * UNIT_AREA; -} - -bool LLParcelSelection::hasOthersSelected() const +void LLViewerParcelMgr::cleanupGlobals() { - return mSelectedOtherCount != 0; + delete gParcelMgr; + gParcelMgr = NULL; + LLParcelSelection::sNullSelection = NULL; } -static LLPointer sNullSelection; - -LLParcelSelection* get_null_parcel_selection() +LLViewerImage* LLViewerParcelMgr::getBlockedImage() const { - if (sNullSelection.isNull()) - { - sNullSelection = new LLParcelSelection; - } - - return sNullSelection; + return sBlockedImage; } -void LLViewerParcelMgr::cleanupGlobals() +LLViewerImage* LLViewerParcelMgr::getPassImage() const { - delete gParcelMgr; - gParcelMgr = NULL; - sNullSelection = NULL; + return sPassImage; } diff --git a/linden/indra/newview/llviewerparcelmgr.h b/linden/indra/newview/llviewerparcelmgr.h index 88652d6..5847343 100644 --- a/linden/indra/newview/llviewerparcelmgr.h +++ b/linden/indra/newview/llviewerparcelmgr.h @@ -36,11 +36,12 @@ #include "lldarray.h" #include "llframetimer.h" #include "llmemory.h" -#include "llviewerimage.h" +#include "llparcelselection.h" class LLUUID; class LLMessageSystem; class LLParcel; +class LLViewerImage; class LLViewerRegion; // Constants for sendLandOwner @@ -72,49 +73,6 @@ public: virtual void changed() = 0; }; -class LLParcelSelection : public LLRefCount -{ - friend class LLViewerParcelMgr; - -protected: - ~LLParcelSelection(); - -public: - LLParcelSelection(LLParcel* parcel); - LLParcelSelection(); - - // this can return NULL at any time, as parcel selection - // might have been invalidated. - LLParcel* getParcel() { return mParcel; } - - // Return the number of grid units that are owned by you within - // the selection (computed by server). - S32 getSelfCount() const { return mSelectedSelfCount; } - - // Returns area that will actually be claimed in meters squared. - S32 getClaimableArea() const; - bool hasOthersSelected() const; - - // Does the selection have multiple land owners in it? - BOOL getMultipleOwners() const; - - // Is the entire parcel selected, or just a part? - BOOL getWholeParcelSelected() const; - -protected: - void setParcel(LLParcel* parcel) { mParcel = parcel; } - -protected: - - LLParcel* mParcel; - BOOL mSelectedMultipleOwners; - BOOL mWholeParcelSelected; - S32 mSelectedSelfCount; - S32 mSelectedOtherCount; - S32 mSelectedPublicCount; -}; - -typedef LLHandle LLParcelSelectionHandle; class LLViewerParcelMgr { @@ -152,7 +110,7 @@ public: void selectCollisionParcel(); // Select the parcel at a specific point - LLHandle selectParcelAt(const LLVector3d& pos_global); + LLSafeHandle selectParcelAt(const LLVector3d& pos_global); // Take the current rectangle select, and select the parcel contained // within it. @@ -231,7 +189,7 @@ public: // containing the southwest corner of the selection. // If want_reply_to_update, simulator will send back a ParcelProperties // message. - void sendParcelPropertiesUpdate(LLParcel* parcel); + void sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region = false); // Takes an Access List flag, like AL_ACCESS or AL_BAN void sendParcelAccessListUpdate(U32 which); @@ -300,7 +258,7 @@ public: static BOOL isParcelOwnedByAgent(const LLParcel* parcelp, U64 group_proxy_power); static BOOL isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power); -protected: +private: static void releaseAlertCB(S32 option, void *data); // If the user is claiming land and the current selection @@ -322,6 +280,8 @@ protected: static void callbackJoinLand(S32 option, void* data); //void finishClaim(BOOL user_to_user_sale, U32 join); + LLViewerImage* getBlockedImage() const; + LLViewerImage* getPassImage() const; private: BOOL mSelected; @@ -367,8 +327,6 @@ private: LLFrameTimer mCollisionTimer; LLUUID mBlockedImageID; LLUUID mPassImageID; - LLPointer mBlockedImage; - LLPointer mPassImage; // Media S32 mMediaParcelId; diff --git a/linden/indra/newview/llviewerparceloverlay.cpp b/linden/indra/newview/llviewerparceloverlay.cpp index e1373d0..281b644 100644 --- a/linden/indra/newview/llviewerparceloverlay.cpp +++ b/linden/indra/newview/llviewerparceloverlay.cpp @@ -36,6 +36,7 @@ // indra includes #include "llparcel.h" #include "llgl.h" +#include "llglimmediate.h" #include "v4color.h" #include "v2math.h" @@ -829,14 +830,12 @@ S32 LLViewerParcelOverlay::renderPropertyLines () continue; } - glBegin(GL_TRIANGLE_STRIP); + gGL.begin(GL_TRIANGLE_STRIP); for (j = 0; j < vertex_per_edge; j++) { - // JC - This doesn't work - //glTexCoord2fv(mTexCoordArray + FLOATS_PER_TEX_COORD*offset); - glColor4ubv(colorp); - glVertex3fv(vertexp); + gGL.color4ubv(colorp); + gGL.vertex3fv(vertexp); colorp += BYTES_PER_COLOR; vertexp += FLOATS_PER_VERTEX; @@ -844,7 +843,34 @@ S32 LLViewerParcelOverlay::renderPropertyLines () drawn += vertex_per_edge; - glEnd(); + gGL.end(); + + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); + + colorp = mColorArray + BYTES_PER_COLOR * i; + vertexp = mVertexArray + FLOATS_PER_VERTEX * i; + + gGL.begin(GL_TRIANGLE_STRIP); + + for (j = 0; j < vertex_per_edge; j++) + { + U8 color[4]; + color[0] = colorp[0]; + color[1] = colorp[1]; + color[2] = colorp[2]; + color[3] = colorp[3]/4; + + gGL.color4ubv(color); + gGL.vertex3fv(vertexp); + + colorp += BYTES_PER_COLOR; + vertexp += FLOATS_PER_VERTEX; + } + + drawn += vertex_per_edge; + + gGL.end(); + } glPopMatrix(); diff --git a/linden/indra/newview/llviewerpartsim.cpp b/linden/indra/newview/llviewerpartsim.cpp index 571e0b4..0766a01 100644 --- a/linden/indra/newview/llviewerpartsim.cpp +++ b/linden/indra/newview/llviewerpartsim.cpp @@ -43,8 +43,7 @@ #include "llvopartgroup.h" #include "llworld.h" #include "pipeline.h" - -const S32 MAX_PART_COUNT = 8192; // VWR-1105 +#include "llspatialpartition.h" const F32 PART_SIM_BOX_SIDE = 16.f; const F32 PART_SIM_BOX_OFFSET = 0.5f*PART_SIM_BOX_SIDE; @@ -53,6 +52,18 @@ const F32 PART_SIM_BOX_RAD = 0.5f*F_SQRT3*PART_SIM_BOX_SIDE; //static S32 LLViewerPartSim::sMaxParticleCount = 0; S32 LLViewerPartSim::sParticleCount = 0; +// This controls how greedy individual particle burst sources are allowed to be, and adapts according to how near the particle-count limit we are. +F32 LLViewerPartSim::sParticleAdaptiveRate = 0.0625f; +F32 LLViewerPartSim::sParticleBurstRate = 0.5f; + +//static +const S32 LLViewerPartSim::MAX_PART_COUNT = 8192; +const F32 LLViewerPartSim::PART_THROTTLE_THRESHOLD = 0.9f; +const F32 LLViewerPartSim::PART_ADAPT_RATE_MULT = 2.0f; + +//static +const F32 LLViewerPartSim::PART_THROTTLE_RESCALE = PART_THROTTLE_THRESHOLD / (1.0f-PART_THROTTLE_THRESHOLD); +const F32 LLViewerPartSim::PART_ADAPT_RATE_MULT_RECIP = 1.0f/PART_ADAPT_RATE_MULT; U32 LLViewerPart::sNextPartID = 1; @@ -76,36 +87,6 @@ LLViewerPart::~LLViewerPart() mPartSourcep = NULL; } -LLViewerPart &LLViewerPart::operator=(const LLViewerPart &part) -{ - LLMemType mt(LLMemType::MTYPE_PARTICLES); - mPartID = part.mPartID; - mFlags = part.mFlags; - mMaxAge = part.mMaxAge; - - mStartColor = part.mStartColor; - mEndColor = part.mEndColor; - mStartScale = part.mStartScale; - mEndScale = part.mEndScale; - - mPosOffset = part.mPosOffset; - mParameter = part.mParameter; - - mLastUpdateTime = part.mLastUpdateTime; - mVPCallback = part.mVPCallback; - mPartSourcep = part.mPartSourcep; - - mImagep = part.mImagep; - mPosAgent = part.mPosAgent; - mVelocity = part.mVelocity; - mAccel = part.mAccel; - mColor = part.mColor; - mScale = part.mScale; - - - return *this; -} - void LLViewerPart::init(LLPointer sourcep, LLViewerImage *imagep, LLVPCallback cb) { LLMemType mt(LLMemType::MTYPE_PARTICLES); @@ -114,6 +95,7 @@ void LLViewerPart::init(LLPointer sourcep, LLViewerImage *im mFlags = 0x00f; mLastUpdateTime = 0.f; mMaxAge = 10.f; + mSkipOffset = 0.0f; mVPCallback = cb; mPartSourcep = sourcep; @@ -155,11 +137,23 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo LLSpatialGroup* group = mVOPartGroupp->mDrawable->getSpatialGroup(); - LLVector3 center(group->mOctreeNode->getCenter()); - LLVector3 size(group->mOctreeNode->getSize()); - size += LLVector3(0.01f, 0.01f, 0.01f); - mMinObjPos = center - size; - mMaxObjPos = center + size; + if (group != NULL) + { + LLVector3 center(group->mOctreeNode->getCenter()); + LLVector3 size(group->mOctreeNode->getSize()); + size += LLVector3(0.01f, 0.01f, 0.01f); + mMinObjPos = center - size; + mMaxObjPos = center + size; + } + else + { + // Not sure what else to set the obj bounds to when the drawable has no spatial group. + LLVector3 extents(mBoxRadius, mBoxRadius, mBoxRadius); + mMinObjPos = center_agent - extents; + mMaxObjPos = center_agent + extents; + } + + mSkippedTime = 0.f; static U32 id_seed = 0; mID = ++id_seed; @@ -233,27 +227,17 @@ BOOL LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size) gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); mParticles.push_back(part); + part->mSkipOffset=mSkippedTime; LLViewerPartSim::incPartCount(1); return TRUE; } -void LLViewerPartGroup::removePart(const S32 part_num) -{ - LLMemType mt(LLMemType::MTYPE_PARTICLES); - // Remove the entry for the particle we just deleted. - mParticles.erase(mParticles.begin() + part_num); - if (mVOPartGroupp.notNull()) - { - gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); - } - LLViewerPartSim::decPartCount(1); -} - -void LLViewerPartGroup::updateParticles(const F32 dt) +void LLViewerPartGroup::updateParticles(const F32 lastdt) { LLMemType mt(LLMemType::MTYPE_PARTICLES); S32 i; + F32 dt; LLVector3 gravity(0.f, 0.f, -9.8f); @@ -264,6 +248,9 @@ void LLViewerPartGroup::updateParticles(const F32 dt) LLVector3 a(0.f, 0.f, 0.f); LLViewerPart& part = *((LLViewerPart*) mParticles[i]); + dt=lastdt+mSkippedTime-part.mSkipOffset; + part.mSkipOffset=0.f; + // Update current time const F32 cur_time = part.mLastUpdateTime + dt; const F32 frac = cur_time/part.mMaxAge; @@ -347,10 +334,11 @@ void LLViewerPartGroup::updateParticles(const F32 dt) if (part.mFlags & LLPartData::LL_PART_INTERP_COLOR_MASK) { part.mColor.setVec(part.mStartColor); - part.mColor *= 1.f - frac; - part.mColor.mV[3] *= (1.f - frac)*part.mStartColor.mV[3]; - part.mColor += frac*part.mEndColor; - part.mColor.mV[3] += frac*part.mEndColor.mV[3]; + // note: LLColor4's v%k means multiply-alpha-only, + // LLColor4's v*k means multiply-rgb-only + part.mColor *= 1.f - frac; // rgb*k + part.mColor %= 1.f - frac; // alpha*k + part.mColor += frac%(frac*part.mEndColor); // rgb,alpha } // Do scale interpolation @@ -370,6 +358,8 @@ void LLViewerPartGroup::updateParticles(const F32 dt) { end--; LLPointer::swap(mParticles[i], mParticles[end]); + // be sure to process the particle we just swapped-in + i--; } else { @@ -380,6 +370,8 @@ void LLViewerPartGroup::updateParticles(const F32 dt) gWorldPointer->mPartSim.put(&part); end--; LLPointer::swap(mParticles[i], mParticles[end]); + // be sure to process the particle we just swapped-in + i--; } } } @@ -470,12 +462,12 @@ LLViewerPartSim::~LLViewerPartSim() BOOL LLViewerPartSim::shouldAddPart() { LLMemType mt(LLMemType::MTYPE_PARTICLES); - if (sParticleCount > 0.75f*sMaxParticleCount) + if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount) { F32 frac = (F32)sParticleCount/(F32)sMaxParticleCount; - frac -= 0.75; - frac *= 3.f; + frac -= PART_THROTTLE_THRESHOLD; + frac *= PART_THROTTLE_RESCALE; if (ll_frand() < frac) { // Skip... @@ -573,21 +565,13 @@ void LLViewerPartSim::shift(const LLVector3 &offset) } } -S32 dist_rate_func(F32 distance) -{ - //S32 dist = (S32) sqrtf(distance); - //dist /= 2; - //return llmax(dist,1); - return 1; -} - void LLViewerPartSim::updateSimulation() { LLMemType mt(LLMemType::MTYPE_PARTICLES); static LLFrameTimer update_timer; - const F32 dt = update_timer.getElapsedTimeAndResetF32(); + const F32 dt = llmin(update_timer.getElapsedTimeAndResetF32(), 0.1f); if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES))) { @@ -605,9 +589,11 @@ void LLViewerPartSim::updateSimulation() S32 count = (S32) mViewerPartSources.size(); S32 start = (S32)ll_frand((F32)count); S32 dir = 1; + S32 deldir = 0; if (ll_frand() > 0.5f) { dir = -1; + deldir = -1; } S32 num_updates = 0; @@ -624,25 +610,14 @@ void LLViewerPartSim::updateSimulation() if (!mViewerPartSources[i]->isDead()) { - LLViewerObject* source_object = mViewerPartSources[i]->mSourceObjectp; - if (source_object && source_object->mDrawable.notNull()) - { - S32 dist = dist_rate_func(source_object->mDrawable->mDistanceWRTCamera); - if ((LLDrawable::getCurrentFrame()+mViewerPartSources[i]->mID)%dist == 0) - { - mViewerPartSources[i]->update(dt*dist); - } - } - else - { - mViewerPartSources[i]->update(dt); - } + mViewerPartSources[i]->update(dt); } if (mViewerPartSources[i]->isDead()) { mViewerPartSources.erase(mViewerPartSources.begin() + i); count--; + i+=deldir; } else { @@ -657,24 +632,24 @@ void LLViewerPartSim::updateSimulation() { LLViewerObject* vobj = mViewerPartGroups[i]->mVOPartGroupp; - S32 dist = vobj && !vobj->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) ? - dist_rate_func(vobj->mDrawable->mDistanceWRTCamera) : 1; + S32 visirate = 1; if (vobj) { LLSpatialGroup* group = vobj->mDrawable->getSpatialGroup(); if (group && !group->isVisible()) // && !group->isState(LLSpatialGroup::OBJECT_DIRTY)) { - dist *= 8; + visirate = 8; } } - if ((LLDrawable::getCurrentFrame()+mViewerPartGroups[i]->mID)%dist == 0) + if ((LLDrawable::getCurrentFrame()+mViewerPartGroups[i]->mID)%visirate == 0) { if (vobj) { gPipeline.markRebuild(vobj->mDrawable, LLDrawable::REBUILD_ALL, TRUE); } - mViewerPartGroups[i]->updateParticles(dt*dist); + mViewerPartGroups[i]->updateParticles(dt * visirate); + mViewerPartGroups[i]->mSkippedTime=0.0f; if (!mViewerPartGroups[i]->getCount()) { delete mViewerPartGroups[i]; @@ -683,10 +658,64 @@ void LLViewerPartSim::updateSimulation() count--; } } + else + { + mViewerPartGroups[i]->mSkippedTime+=dt; + } + + } + if (LLDrawable::getCurrentFrame()%16==0) + { + if (sParticleCount > sMaxParticleCount * 0.875f + && sParticleAdaptiveRate < 2.0f) + { + sParticleAdaptiveRate *= PART_ADAPT_RATE_MULT; + } + else + { + if (sParticleCount < sMaxParticleCount * 0.5f + && sParticleAdaptiveRate > 0.03125f) + { + sParticleAdaptiveRate *= PART_ADAPT_RATE_MULT_RECIP; + } + } } - //llinfos << "Particles: " << sParticleCount << llendl; + + updatePartBurstRate() ; + + //llinfos << "Particles: " << sParticleCount << " Adaptive Rate: " << sParticleAdaptiveRate << llendl; } +void LLViewerPartSim::updatePartBurstRate() +{ + if (!(LLDrawable::getCurrentFrame() & 0xf)) + { + if (sParticleCount >= MAX_PART_COUNT) //set rate to zero + { + sParticleBurstRate = 0.0f ; + } + else if(sParticleCount > 0) + { + if(sParticleBurstRate > 0.0000001f) + { + F32 total_particles = sParticleCount / sParticleBurstRate ; //estimated + F32 new_rate = llclamp(0.9f * sMaxParticleCount / total_particles, 0.0f, 1.0f) ; + F32 delta_rate_threshold = llmin(0.1f * llmax(new_rate, sParticleBurstRate), 0.1f) ; + F32 delta_rate = llclamp(new_rate - sParticleBurstRate, -1.0f * delta_rate_threshold, delta_rate_threshold) ; + + sParticleBurstRate = llclamp(sParticleBurstRate + 0.5f * delta_rate, 0.0f, 1.0f) ; + } + else + { + sParticleBurstRate += 0.0000001f ; + } + } + else + { + sParticleBurstRate += 0.00125f ; + } + } +} void LLViewerPartSim::addPartSource(LLPointer sourcep) { @@ -696,6 +725,7 @@ void LLViewerPartSim::addPartSource(LLPointer sourcep) llwarns << "Null part source!" << llendl; return; } + sourcep->setStart() ; mViewerPartSources.push_back(sourcep); } diff --git a/linden/indra/newview/llviewerpartsim.h b/linden/indra/newview/llviewerpartsim.h index dbc0fce..42d3fd7 100644 --- a/linden/indra/newview/llviewerpartsim.h +++ b/linden/indra/newview/llviewerpartsim.h @@ -33,7 +33,6 @@ #define LL_LLVIEWERPARTSIM_H #include "lldarrayptr.h" -#include "llskiplist.h" #include "llframetimer.h" #include "llmemory.h" @@ -61,13 +60,12 @@ protected: public: LLViewerPart(); - LLViewerPart &operator=(const LLViewerPart &part); void init(LLPointer sourcep, LLViewerImage *imagep, LLVPCallback cb); U32 mPartID; // Particle ID used primarily for moving between groups F32 mLastUpdateTime; // Last time the particle was updated - + F32 mSkipOffset; // Offset against current group mSkippedTime LLVPCallback mVPCallback; // Callback function for more complicated behaviors LLPointer mPartSourcep; // Particle source used for this object @@ -97,7 +95,7 @@ public: BOOL addPart(LLViewerPart* part, const F32 desired_size = -1.f); - void updateParticles(const F32 dt); + void updateParticles(const F32 lastdt); BOOL posInGroup(const LLVector3 &pos, const F32 desired_size = -1.f); @@ -117,8 +115,7 @@ public: BOOL mUniformParticles; U32 mID; -protected: - void removePart(const S32 part_num); + F32 mSkippedTime; protected: LLVector3 mCenterAgent; @@ -131,7 +128,6 @@ protected: class LLViewerPartSim { - public: LLViewerPartSim(); virtual ~LLViewerPartSim(); @@ -148,7 +144,22 @@ public: void cleanupRegion(LLViewerRegion *regionp); BOOL shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping) + F32 maxRate() // Return maximum particle generation rate + { + if (sParticleCount >= MAX_PART_COUNT) + { + return 1.f; + } + if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount) + { + return (((F32)sParticleCount/(F32)sMaxParticleCount)-PART_THROTTLE_THRESHOLD)*PART_THROTTLE_RESCALE; + } + return 0.f; + } + F32 getRefRate() { return sParticleAdaptiveRate; } + F32 getBurstRate() {return sParticleBurstRate; } void addPart(LLViewerPart* part); + void updatePartBurstRate() ; void clearParticlesByID(const U32 system_id); void clearParticlesByOwnerID(const LLUUID& task_id); void removeLastCreatedSource(); @@ -170,12 +181,20 @@ protected: LLViewerPartGroup *createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size); LLViewerPartGroup *put(LLViewerPart* part); -protected: group_list_t mViewerPartGroups; source_list_t mViewerPartSources; LLFrameTimer mSimulationTimer; + static S32 sMaxParticleCount; static S32 sParticleCount; + static F32 sParticleAdaptiveRate; + static F32 sParticleBurstRate; + + static const S32 MAX_PART_COUNT; + static const F32 PART_THROTTLE_THRESHOLD; + static const F32 PART_THROTTLE_RESCALE; + static const F32 PART_ADAPT_RATE_MULT; + static const F32 PART_ADAPT_RATE_MULT_RECIP; }; #endif // LL_LLVIEWERPARTSIM_H diff --git a/linden/indra/newview/llviewerpartsource.cpp b/linden/indra/newview/llviewerpartsource.cpp index 6c93e75..f54495a 100644 --- a/linden/indra/newview/llviewerpartsource.cpp +++ b/linden/indra/newview/llviewerpartsource.cpp @@ -36,6 +36,7 @@ #include "llagent.h" #include "lldrawable.h" +#include "llviewercamera.h" #include "llviewerimagelist.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -53,6 +54,8 @@ LLViewerPartSource::LLViewerPartSource(const U32 type) : mIsSuspended = FALSE; static U32 id_seed = 0; mID = ++id_seed; + + mDelay = 0 ; } void LLViewerPartSource::setDead() @@ -79,6 +82,10 @@ LLUUID LLViewerPartSource::getImageUUID() const } return LLUUID::null; } +void LLViewerPartSource::setStart() +{ + mDelay = 99 ; +} LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp) : LLViewerPartSource(LL_PART_SOURCE_SCRIPT) @@ -111,6 +118,8 @@ void LLViewerPartSourceScript::update(const F32 dt) LLMemType mt(LLMemType::MTYPE_PARTICLES); F32 old_update_time = mLastUpdateTime; mLastUpdateTime += dt; + + F32 ref_rate_travelspeed = llmin(gWorldPointer->mPartSim.getRefRate(), 1.f); F32 dt_update = mLastUpdateTime - mLastPartTime; @@ -199,21 +208,71 @@ void LLViewerPartSourceScript::update(const F32 dt) // No angular velocity. Reset our rotation. mRotation.setQuat(0, 0, 0); } - + if (gWorldPointer->mPartSim.aboveParticleLimit()) { // Don't bother doing any more updates if we're above the particle limit, // just give up. mLastPartTime = mLastUpdateTime; + break; + + } + + // find the greatest length that the shortest side of a system + // particle is expected to have + F32 max_short_side = + llmax( + llmax(llmin(mPartSysData.mPartData.mStartScale[0], + mPartSysData.mPartData.mStartScale[1]), + llmin(mPartSysData.mPartData.mEndScale[0], + mPartSysData.mPartData.mEndScale[1])), + llmin((mPartSysData.mPartData.mStartScale[0] + + mPartSysData.mPartData.mEndScale[0])/2, + (mPartSysData.mPartData.mStartScale[1] + + mPartSysData.mPartData.mEndScale[1])/2)); + + F32 pixel_meter_ratio = gCamera->getPixelMeterRatio(); + + // Maximum distance at which spawned particles will be viewable + F32 max_dist = max_short_side * pixel_meter_ratio; + + if (max_dist < 0.25f) + { + // < 1 pixel wide at a distance of >=25cm. Particles + // this tiny are useless and mostly spawned by buggy + // sources + mLastPartTime = mLastUpdateTime; break; } + // Distance from camera + F32 dist = (mPosAgent - gCamera->getOrigin()).magVec(); + + // Particle size vs distance vs maxage throttling + + F32 limited_rate=0.f; + if (dist - max_dist > 0.f) + { + if((dist - max_dist) * ref_rate_travelspeed > mPartSysData.mPartData.mMaxAge - 0.2f ) + { + // You need to travel faster than 1 divided by reference rate m/s directly towards these particles to see them at least 0.2s + mLastPartTime = mLastUpdateTime; + break; + } + limited_rate = ((dist - max_dist) * ref_rate_travelspeed) / mPartSysData.mPartData.mMaxAge; + } + + if(mDelay) + { + limited_rate = llmax(limited_rate, 0.01f * mDelay--) ; + } + S32 i; for (i = 0; i < mPartSysData.mBurstPartCount; i++) { - if (!gWorldPointer->mPartSim.shouldAddPart()) + if (ll_frand() < llmax(1.0f - gWorldPointer->mPartSim.getBurstRate(), limited_rate)) { - // Particle simulation says we have too many particles, skip all this + // Limit particle generation continue; } diff --git a/linden/indra/newview/llviewerpartsource.h b/linden/indra/newview/llviewerpartsource.h index cb12517..cda81a0 100644 --- a/linden/indra/newview/llviewerpartsource.h +++ b/linden/indra/newview/llviewerpartsource.h @@ -73,6 +73,7 @@ public: LLUUID getOwnerUUID() const { return mOwnerUUID; } U32 getID() const { return mID; } LLUUID getImageUUID() const; + void setStart() ; LLVector3 mPosAgent; // Location of the particle source LLVector3 mTargetPosAgent; // Location of the target position @@ -91,6 +92,7 @@ protected: // Particle information U32 mPartFlags; // Flags for the particle + U32 mDelay ; //delay to start particles }; diff --git a/linden/indra/newview/llviewerprecompiledheaders.h b/linden/indra/newview/llviewerprecompiledheaders.h index db7baaa..711f8e7 100644 --- a/linden/indra/newview/llviewerprecompiledheaders.h +++ b/linden/indra/newview/llviewerprecompiledheaders.h @@ -68,21 +68,17 @@ // Library headers from llcommon project: #include "bitpack.h" -#include "doublelinkedlist.h" #include "imageids.h" #include "indra_constants.h" //#include "linden_common.h" //#include "llpreprocessor.h" -#include "linked_lists.h" #include "llapp.h" #include "llapr.h" -#include "llassoclist.h" #include "llcriticaldamp.h" #include "lldarray.h" #include "lldarrayptr.h" #include "lldefs.h" #include "lldepthstack.h" -#include "lldlinked.h" #include "lldqueueptr.h" #include "llendianswizzle.h" #include "llerror.h" @@ -90,18 +86,13 @@ #include "llfixedbuffer.h" #include "llframetimer.h" #include "llhash.h" -#include "lllinkedqueue.h" #include "lllocalidhashmap.h" #include "llmap.h" #include "llmemory.h" #include "llnametable.h" #include "llpriqueuemap.h" #include "llprocessor.h" -#include "llptrskiplist.h" -#include "llptrskipmap.h" //#include "llsecondlifeurls.h" -#include "llskiplist.h" -#include "llskipmap.h" #include "llstack.h" #include "llstat.h" #include "llstl.h" @@ -163,7 +154,6 @@ // Library includes from llmessage project //#include "llassetstorage.h" #include "llcachename.h" -#include "llcallbacklisth.h" #include "llcircuit.h" #include "lldatapacker.h" #include "lldbstrings.h" diff --git a/linden/indra/newview/llviewerregion.cpp b/linden/indra/newview/llviewerregion.cpp index f8b8f76..1cc6d42 100644 --- a/linden/indra/newview/llviewerregion.cpp +++ b/linden/indra/newview/llviewerregion.cpp @@ -64,6 +64,7 @@ #include "llvocache.h" #include "llvoclouds.h" #include "llworld.h" +#include "llspatialpartition.h" // Viewer object cache version, change if object update // format changes. JC @@ -97,7 +98,6 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mBillableFactor(1.0), mMaxTasks(MAX_TASKS_PER_REGION), mCacheLoaded(FALSE), - mCacheMap(), mCacheEntriesCount(0), mCacheID(), mEventPoll(NULL) @@ -105,6 +105,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mWidth = region_width_meters; mOriginGlobal = from_region_handle(handle); + updateRenderMatrix(); mLandp = new LLSurface('l', NULL); if (!gNoRender) @@ -138,6 +139,19 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mCacheStart.append(mCacheEnd); + //create object partitions + //MUST MATCH declaration of eObjectPartitions + mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD + mObjectPartition.push_back(new LLTerrainPartition()); //PARTITION_TERRAIN + mObjectPartition.push_back(new LLWaterPartition()); //PARTITION_WATER + mObjectPartition.push_back(new LLTreePartition()); //PARTITION_TREE + mObjectPartition.push_back(new LLParticlePartition()); //PARTITION_PARTICLE + mObjectPartition.push_back(new LLCloudPartition()); //PARTITION_CLOUD + mObjectPartition.push_back(new LLGrassPartition()); //PARTITION_GRASS + mObjectPartition.push_back(new LLVolumePartition()); //PARTITION_VOLUME + mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE + mObjectPartition.push_back(NULL); //PARTITION_NONE + } @@ -176,6 +190,8 @@ LLViewerRegion::~LLViewerRegion() LLHTTPSender::clearSender(mHost); saveCache(); + + std::for_each(mObjectPartition.begin(), mObjectPartition.end(), DeletePointer()); } @@ -326,7 +342,7 @@ void LLViewerRegion::saveCache() entry->writeToFile(fp); } - mCacheMap.removeAllData(); + mCacheMap.clear(); mCacheEnd.unlink(); mCacheEnd.init(); mCacheStart.deleteAll(); @@ -381,12 +397,17 @@ void LLViewerRegion::setRegionFlags(U32 flags) void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global) { mOriginGlobal = origin_global; + updateRenderMatrix(); mLandp->setOriginGlobal(origin_global); mWind.setOriginGlobal(origin_global); mCloudLayer.setOriginGlobal(origin_global); calculateCenterGlobal(); } +void LLViewerRegion::updateRenderMatrix() +{ + mRenderMatrix.setTranslation(getOriginAgent()); +} void LLViewerRegion::setTimeDilation(F32 time_dilation) { @@ -952,8 +973,7 @@ void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg) // << " Z: " << (S32)(z_pos * 4) // << llendl; - // treat the target specially for the map, and don't add you - // or the target + // treat the target specially for the map if(i == target_index) { LLVector3d global_pos(mOriginGlobal); @@ -962,7 +982,9 @@ void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg) global_pos.mdV[VZ] += (F64)(z_pos) * 4.0; LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos); } - else if( i != agent_index) + + //don't add you + if( i != agent_index) { pos = 0x0; pos |= x_pos; @@ -990,7 +1012,7 @@ void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinary U32 local_id = objectp->getLocalID(); U32 crc = objectp->getCRC(); - LLVOCacheEntry *entry = mCacheMap.getIfThere(local_id); + LLVOCacheEntry* entry = get_if_there(mCacheMap, local_id, (LLVOCacheEntry*)NULL); if (entry) { @@ -1003,7 +1025,7 @@ void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinary else { // Update the cache entry - mCacheMap.removeData(local_id); + mCacheMap.erase(local_id); delete entry; entry = new LLVOCacheEntry(local_id, crc, dp); mCacheEnd.insert(*entry); @@ -1018,7 +1040,7 @@ void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinary if (mCacheEntriesCount > MAX_OBJECT_CACHE_ENTRIES) { entry = mCacheStart.getNext(); - mCacheMap.removeData(entry->getLocalID()); + mCacheMap.erase(entry->getLocalID()); delete entry; mCacheEntriesCount--; } @@ -1037,7 +1059,7 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc) { llassert(mCacheLoaded); - LLVOCacheEntry *entry = mCacheMap.getIfThere(local_id); + LLVOCacheEntry* entry = get_if_there(mCacheMap, local_id, (LLVOCacheEntry*)NULL); if (entry) { @@ -1353,12 +1375,15 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("ChatSessionRequest"); capabilityNames.append("CopyInventoryFromNotecard"); capabilityNames.append("DispatchRegionInfo"); + capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); + capabilityNames.append("FetchInventoryDescendents"); capabilityNames.append("GroupProposalBallot"); capabilityNames.append("MapLayer"); capabilityNames.append("MapLayerGod"); capabilityNames.append("NewFileAgentInventory"); capabilityNames.append("ParcelGodReserveForNewbie"); + capabilityNames.append("ParcelPropertiesUpdate"); capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); capabilityNames.append("RemoteParcelRequest"); @@ -1429,4 +1454,12 @@ void LLViewerRegion::logActiveCapabilities() const llinfos << "Dumped " << count << " entries." << llendl; } +LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type) +{ + if (type < mObjectPartition.size()) + { + return mObjectPartition[type]; + } + return NULL; +} diff --git a/linden/indra/newview/llviewerregion.h b/linden/indra/newview/llviewerregion.h index b8e19cc..d4032cf 100644 --- a/linden/indra/newview/llviewerregion.h +++ b/linden/indra/newview/llviewerregion.h @@ -44,7 +44,6 @@ #include "llhost.h" #include "llstring.h" #include "llregionflags.h" -#include "llptrskipmap.h" #include "lluuid.h" #include "lldatapacker.h" #include "llvocache.h" @@ -64,10 +63,27 @@ class LLViewerParcelOverlay; class LLSurface; class LLVOCache; class LLVOCacheEntry; +class LLSpatialPartition; class LLViewerRegion { public: + //MUST MATCH THE ORDER OF DECLARATION IN CONSTRUCTOR + typedef enum + { + PARTITION_HUD=0, + PARTITION_TERRAIN, + PARTITION_WATER, + PARTITION_TREE, + PARTITION_PARTICLE, + PARTITION_CLOUD, + PARTITION_GRASS, + PARTITION_VOLUME, + PARTITION_BRIDGE, + PARTITION_NONE, + NUM_PARTITIONS + } eObjectPartitions; + LLViewerRegion(const U64 &handle, const LLHost &host, const U32 surface_grid_width, @@ -84,7 +100,8 @@ public: void sendReliableMessage(); // Send the current message to this region's simulator void setOriginGlobal(const LLVector3d &origin); - void setAgentOffset(const LLVector3d &offset); + //void setAgentOffset(const LLVector3d &offset); + void updateRenderMatrix(); void setAllowDamage(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_DAMAGE); } void setAllowLandmark(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_LANDMARK); } @@ -245,6 +262,7 @@ public: // used by LCD to get details for debug screen U32 getNetDetailsForLCD(); + LLSpatialPartition* getSpatialPartition(U32 type); public: struct CompareDistance { @@ -270,6 +288,8 @@ public: LLStat mPacketsStat; LLStat mPacketsLostStat; + LLMatrix4 mRenderMatrix; + // These arrays are maintained in parallel. Ideally they'd be combined into a // single array of an aggrigate data type but for compatibility with the old // messaging system in which the previous message only sends and parses the @@ -331,7 +351,8 @@ protected: // Regions can have order 10,000 objects, so assume // a structure of size 2^14 = 16,000 BOOL mCacheLoaded; - LLPtrSkipMap mCacheMap; + typedef std::map cache_map_t; + cache_map_t mCacheMap; LLVOCacheEntry mCacheStart; LLVOCacheEntry mCacheEnd; U32 mCacheEntriesCount; @@ -348,6 +369,10 @@ protected: CapabilityMap mCapabilities; LLEventPoll* mEventPoll; + +private: + //spatial partitions for objects in this region + std::vector mObjectPartition; }; inline BOOL LLViewerRegion::getAllowDamage() const diff --git a/linden/indra/newview/llviewerstats.cpp b/linden/indra/newview/llviewerstats.cpp index ea24d9e..dabc971 100644 --- a/linden/indra/newview/llviewerstats.cpp +++ b/linden/indra/newview/llviewerstats.cpp @@ -537,7 +537,7 @@ void update_statistics(U32 frame_count) gViewerStats->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs); gViewerStats->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs); gViewerStats->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IMAGE_UPDATE)); - gViewerStats->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_REBUILD)); + gViewerStats->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_STATESORT )); gViewerStats->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_RENDER_GEOMETRY)); LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); @@ -704,11 +704,11 @@ void send_stats() std::string gpu_desc = llformat( "%-6s Class %d ", gGLManager.mGLVendorShort.substr(0,6).c_str(), - gFeatureManagerp->getGPUClass()) + (S32)gFeatureManagerp->getGPUClass()) + gFeatureManagerp->getGPUString(); system["gpu"] = gpu_desc; - system["gpu_class"] = gFeatureManagerp->getGPUClass(); + system["gpu_class"] = (S32)gFeatureManagerp->getGPUClass(); system["gpu_vendor"] = gGLManager.mGLVendorShort; system["gpu_version"] = gGLManager.mDriverVersionVendorString; diff --git a/linden/indra/newview/llviewertexteditor.cpp b/linden/indra/newview/llviewertexteditor.cpp index fcc73b4..15085ac 100644 --- a/linden/indra/newview/llviewertexteditor.cpp +++ b/linden/indra/newview/llviewertexteditor.cpp @@ -1,6 +1,6 @@ /** * @file llviewertexteditor.cpp - * @brief Text editor widget to let users enter a a multi-line ASCII document. + * @brief Text editor widget to let users enter a multi-line document. * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -145,8 +145,8 @@ public: // return true if there are no embedded items. bool empty(); - void bindEmbeddedChars(const LLFontGL* font); - void unbindEmbeddedChars(const LLFontGL* font); + void bindEmbeddedChars(LLFontGL* font) const; + void unbindEmbeddedChars(LLFontGL* font) const; BOOL insertEmbeddedItem(LLInventoryItem* item, llwchar* value, bool is_new); BOOL removeEmbeddedItem( llwchar ext_char ); @@ -167,12 +167,13 @@ public: static LLInventoryItem* getEmbeddedItem(llwchar ext_char); // returns item from static list static BOOL getEmbeddedItemSaved(llwchar ext_char); // returns whether item from static list is saved +private: + struct embedded_info_t { LLPointer mItem; BOOL mSaved; }; -private: typedef std::map item_map_t; static item_map_t sEntries; static std::stack sFreeEntries; @@ -227,14 +228,14 @@ BOOL LLEmbeddedItems::insertEmbeddedItem( LLInventoryItem* item, llwchar* ext_ch } else if (sEntries.empty()) { - wc_emb = FIRST_EMBEDDED_CHAR; + wc_emb = LLTextEditor::FIRST_EMBEDDED_CHAR; } else { item_map_t::iterator last = sEntries.end(); --last; wc_emb = last->first; - if (wc_emb >= LAST_EMBEDDED_CHAR) + if (wc_emb >= LLTextEditor::LAST_EMBEDDED_CHAR) { return FALSE; } @@ -265,7 +266,7 @@ BOOL LLEmbeddedItems::removeEmbeddedItem( llwchar ext_char ) // static LLInventoryItem* LLEmbeddedItems::getEmbeddedItem(llwchar ext_char) { - if( ext_char >= FIRST_EMBEDDED_CHAR && ext_char <= LAST_EMBEDDED_CHAR ) + if( ext_char >= LLTextEditor::FIRST_EMBEDDED_CHAR && ext_char <= LLTextEditor::LAST_EMBEDDED_CHAR ) { item_map_t::iterator iter = sEntries.find(ext_char); if (iter != sEntries.end()) @@ -279,7 +280,7 @@ LLInventoryItem* LLEmbeddedItems::getEmbeddedItem(llwchar ext_char) // static BOOL LLEmbeddedItems::getEmbeddedItemSaved(llwchar ext_char) { - if( ext_char >= FIRST_EMBEDDED_CHAR && ext_char <= LAST_EMBEDDED_CHAR ) + if( ext_char >= LLTextEditor::FIRST_EMBEDDED_CHAR && ext_char <= LLTextEditor::LAST_EMBEDDED_CHAR ) { item_map_t::iterator iter = sEntries.find(ext_char); if (iter != sEntries.end()) @@ -307,7 +308,7 @@ void LLEmbeddedItems::removeUnusedChars() for (S32 i=0; i<(S32)wtext.size(); i++) { llwchar wc = wtext[i]; - if( wc >= FIRST_EMBEDDED_CHAR && wc <= LAST_EMBEDDED_CHAR ) + if( wc >= LLTextEditor::FIRST_EMBEDDED_CHAR && wc <= LLTextEditor::LAST_EMBEDDED_CHAR ) { used.erase(wc); } @@ -365,14 +366,14 @@ BOOL LLEmbeddedItems::hasEmbeddedItem(llwchar ext_char) return FALSE; } -void LLEmbeddedItems::bindEmbeddedChars( const LLFontGL* font ) +void LLEmbeddedItems::bindEmbeddedChars( LLFontGL* font ) const { if( sEntries.empty() ) { return; } - for (std::set::iterator iter1 = mEmbeddedUsedChars.begin(); iter1 != mEmbeddedUsedChars.end(); ++iter1) + for (std::set::const_iterator iter1 = mEmbeddedUsedChars.begin(); iter1 != mEmbeddedUsedChars.end(); ++iter1) { llwchar wch = *iter1; item_map_t::iterator iter2 = sEntries.find(wch); @@ -431,20 +432,20 @@ void LLEmbeddedItems::bindEmbeddedChars( const LLFontGL* font ) LLViewerImage* image = gImageList.getImage(LLUUID(gViewerArt.getString(img_name)), MIPMAP_FALSE, TRUE); - ((LLFontGL*)font)->addEmbeddedChar( wch, image, item->getName() ); + font->addEmbeddedChar( wch, image, item->getName() ); } } -void LLEmbeddedItems::unbindEmbeddedChars( const LLFontGL* font ) +void LLEmbeddedItems::unbindEmbeddedChars( LLFontGL* font ) const { if( sEntries.empty() ) { return; } - for (std::set::iterator iter1 = mEmbeddedUsedChars.begin(); iter1 != mEmbeddedUsedChars.end(); ++iter1) + for (std::set::const_iterator iter1 = mEmbeddedUsedChars.begin(); iter1 != mEmbeddedUsedChars.end(); ++iter1) { - ((LLFontGL*)font)->removeEmbeddedChar(*iter1); + font->removeEmbeddedChar(*iter1); } } @@ -490,7 +491,7 @@ void LLEmbeddedItems::markSaved() /////////////////////////////////////////////////////////////////// -class LLTextCmdInsertEmbeddedItem : public LLTextCmd +class LLViewerTextEditor::LLTextCmdInsertEmbeddedItem : public LLTextEditor::LLTextCmd { public: LLTextCmdInsertEmbeddedItem( S32 pos, LLInventoryItem* item ) @@ -509,7 +510,7 @@ public: { LLWString ws; ws.assign(1, mExtCharValue); - *delta = insert(editor, mPos, ws ); + *delta = insert(editor, getPosition(), ws ); return (*delta != 0); } return FALSE; @@ -517,18 +518,18 @@ public: virtual S32 undo( LLTextEditor* editor ) { - remove(editor, mPos, 1); - return mPos; + remove(editor, getPosition(), 1); + return getPosition(); } virtual S32 redo( LLTextEditor* editor ) { LLWString ws; ws += mExtCharValue; - insert(editor, mPos, ws ); - return mPos + 1; + insert(editor, getPosition(), ws ); + return getPosition() + 1; } - virtual BOOL hasExtCharValue( llwchar value ) + virtual BOOL hasExtCharValue( llwchar value ) const { return (value == mExtCharValue); } @@ -571,17 +572,17 @@ LLViewerTextEditor::LLViewerTextEditor(const LLString& name, mEmbeddedItemList = new LLEmbeddedItems(this); mInventoryCallback->setEditor(this); + // *TODO: Add right click menus for SLURLs // Build the right click menu // make the popup menu available - - LLMenuGL* menu = gUICtrlFactory->buildMenu("menu_slurl.xml", this); - if (!menu) - { - menu = new LLMenuGL(""); - } - menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor")); - // menu->setVisible(FALSE); - mPopupMenuHandle = menu->mViewHandle; + //LLMenuGL* menu = gUICtrlFactory->buildMenu("menu_slurl.xml", this); + //if (!menu) + //{ + // menu = new LLMenuGL(""); + //} + //menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor")); + //// menu->setVisible(FALSE); + //mPopupMenuHandle = menu->getHandle(); } LLViewerTextEditor::~LLViewerTextEditor() @@ -623,7 +624,7 @@ BOOL LLViewerTextEditor::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* stic return TRUE; } - LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); + const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); if( cur_segment ) { BOOL has_tool_tip = FALSE; @@ -674,13 +675,13 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) } BOOL start_select = TRUE; - if( mAllowEmbeddedItems ) + if( allowsEmbeddedItems() ) { setCursorAtLocalPos( x, y, FALSE ); llwchar wc = 0; if (mCursorPos < getLength()) { - wc = mWText[mCursorPos]; + wc = getWChar(mCursorPos); } LLInventoryItem* item_at_pos = LLEmbeddedItems::getEmbeddedItem(wc); if (item_at_pos) @@ -763,7 +764,7 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) } // Delay cursor flashing - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); return handled; } @@ -790,12 +791,12 @@ BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask) mLastSelectionY = y; } - if( y > mTextRect.mTop ) + if( y > getTextRect().mTop ) { mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 ); } else - if( y < mTextRect.mBottom ) + if( y < getTextRect().mBottom ) { mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 ); } @@ -817,7 +818,7 @@ BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask) LLAssetType::lookupDragAndDropType( mDragItem->getType() ), mDragItem->getUUID(), LLToolDragAndDrop::SOURCE_NOTECARD, - mSourceID, mObjectID); + getSourceID(), mObjectID); return gToolDragAndDrop->handleHover( x, y, mask ); } @@ -837,7 +838,7 @@ BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask) if( handled ) { // Delay cursor flashing - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); } // Opaque @@ -846,7 +847,7 @@ BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask) // Check to see if we're over an HTML-style link if( !mSegments.empty() ) { - LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); + const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); if( cur_segment ) { if(cur_segment->getStyle().isLink()) @@ -870,7 +871,7 @@ BOOL LLViewerTextEditor::handleHover(S32 x, S32 y, MASK mask) if( !handled ) { lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << " (inactive)" << llendl; - if (!mScrollbar->getVisible() || x < mRect.getWidth() - SCROLLBAR_SIZE) + if (!mScrollbar->getVisible() || x < getRect().getWidth() - SCROLLBAR_SIZE) { getWindow()->setCursor(UI_CURSOR_IBEAM); } @@ -894,7 +895,7 @@ BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) // let scrollbar have first dibs handled = LLView::childrenHandleMouseUp(x, y, mask) != NULL; - // enable I Agree checkbox if the user scrolled through entire text + // Used to enable I Agree checkbox if the user scrolled through entire text BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); if (mOnScrollEndCallback && was_scrolled_to_bottom) { @@ -906,12 +907,12 @@ BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) if( mIsSelecting ) { // Finish selection - if( y > mTextRect.mTop ) + if( y > getTextRect().mTop ) { mScrollbar->setDocPos( mScrollbar->getDocPos() - 1 ); } else - if( y < mTextRect.mBottom ) + if( y < getTextRect().mBottom ) { mScrollbar->setDocPos( mScrollbar->getDocPos() + 1 ); } @@ -931,7 +932,7 @@ BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) } // Delay cursor flashing - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); if( hasMouseCapture() ) { @@ -942,7 +943,13 @@ BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) S32 dy = y - mMouseDownY; if (-2 < dx && dx < 2 && -2 < dy && dy < 2) { - openEmbeddedItem(mDragItem, mDragItemSaved); + if(mDragItemSaved) + { + openEmbeddedItem(mDragItem); + }else + { + showUnsavedAlertDialog(mDragItem); + } } } mDragItem = NULL; @@ -959,34 +966,35 @@ BOOL LLViewerTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask) BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL; - if(! handled) - { - LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); - if( cur_segment ) - { - if(cur_segment->getStyle().isLink()) - { - handled = TRUE; - mHTML = cur_segment->getStyle().getLinkHREF(); - } - } - } - LLMenuGL* menu = (LLMenuGL*)LLView::getViewByHandle(mPopupMenuHandle); - if(handled && menu && mParseHTML && mHTML.length() > 0) - { - menu->setVisible(TRUE); - menu->arrange(); - menu->updateParent(LLMenuGL::sMenuContainer); - LLMenuGL::showPopup(this, menu, x, y); - mHTML = ""; - } - else - { - if(menu && menu->getVisible()) - { - menu->setVisible(FALSE); - } - } + // *TODO: Add right click menus for SLURLs +// if(! handled) +// { +// const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); +// if( cur_segment ) +// { +// if(cur_segment->getStyle().isLink()) +// { +// handled = TRUE; +// mHTML = cur_segment->getStyle().getLinkHREF(); +// } +// } +// } +// LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); +// if(handled && menu && mParseHTML && mHTML.length() > 0) +// { +// menu->setVisible(TRUE); +// menu->arrange(); +// menu->updateParent(LLMenuGL::sMenuContainer); +// LLMenuGL::showPopup(this, menu, x, y); +// mHTML = ""; +// } +// else +// { +// if(menu && menu->getVisible()) +// { +// menu->setVisible(FALSE); +// } +// } return handled; } @@ -999,9 +1007,9 @@ BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) if( !handled && mTakesNonScrollClicks) { - if( mAllowEmbeddedItems ) + if( allowsEmbeddedItems() ) { - LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); + const LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y ); if( cur_segment && cur_segment->getStyle().getIsEmbeddedItem() ) { if( openEmbeddedItemAtPos( cur_segment->getStart() ) ) @@ -1048,7 +1056,7 @@ BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) mIsSelecting = FALSE; // delay cursor flashing - mKeystrokeTimer.reset(); + resetKeystrokeTimer(); handled = TRUE; } @@ -1068,12 +1076,12 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, if (mTakesNonScrollClicks) { - if (getEnabled() && !mReadOnly) + if (getEnabled() && acceptsTextInput()) { switch( cargo_type ) { case DAD_CALLINGCARD: - if(mAcceptCallingCardNames) + if(acceptsCallingCardNames()) { if (drop) { @@ -1101,7 +1109,7 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, case DAD_GESTURE: { LLInventoryItem *item = (LLInventoryItem *)cargo_data; - if( mAllowEmbeddedItems ) + if( allowsEmbeddedItems() ) { U32 mask_next = item->getPermissions().getMaskNextOwner(); if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) @@ -1202,9 +1210,9 @@ LLString LLViewerTextEditor::getEmbeddedText() // New version (Version 2) mEmbeddedItemList->copyUsedCharsToIndexed(); LLWString outtextw; - for (S32 i=0; i<(S32)mWText.size(); i++) + for (S32 i=0; i<(S32)getWText().size(); i++) { - llwchar wch = mWText[i]; + llwchar wch = getWChar(i); if( wch >= FIRST_EMBEDDED_CHAR && wch <= LAST_EMBEDDED_CHAR ) { S32 index = mEmbeddedItemList->getIndexFromEmbeddedChar(wch); @@ -1276,21 +1284,21 @@ llwchar LLViewerTextEditor::pasteEmbeddedItem(llwchar ext_char) return LL_UNKNOWN_CHAR; // item not found or list full } -void LLViewerTextEditor::bindEmbeddedChars(const LLFontGL* font) +void LLViewerTextEditor::bindEmbeddedChars(LLFontGL* font) const { mEmbeddedItemList->bindEmbeddedChars( font ); } -void LLViewerTextEditor::unbindEmbeddedChars(const LLFontGL* font) +void LLViewerTextEditor::unbindEmbeddedChars(LLFontGL* font) const { mEmbeddedItemList->unbindEmbeddedChars( font ); } -BOOL LLViewerTextEditor::getEmbeddedItemToolTipAtPos(S32 pos, LLWString &msg) +BOOL LLViewerTextEditor::getEmbeddedItemToolTipAtPos(S32 pos, LLWString &msg) const { if (pos < getLength()) { - LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem(mWText[pos]); + LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem(getWChar(pos)); if( item ) { msg = utf8str_to_wstring(item->getName()); @@ -1307,19 +1315,27 @@ BOOL LLViewerTextEditor::openEmbeddedItemAtPos(S32 pos) { if( pos < getLength()) { - LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem( mWText[pos] ); + LLInventoryItem* item = LLEmbeddedItems::getEmbeddedItem( getWChar(pos) ); if( item ) { - BOOL saved = LLEmbeddedItems::getEmbeddedItemSaved( mWText[pos] ); - return openEmbeddedItem(item, saved); + BOOL saved = LLEmbeddedItems::getEmbeddedItemSaved( getWChar(pos) ); + if (saved) + { + return openEmbeddedItem(item); + } + else + { + showUnsavedAlertDialog(item); + } } } return FALSE; } -BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, BOOL saved) +BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item) { + switch( item->getType() ) { case LLAssetType::AT_TEXTURE: @@ -1329,15 +1345,15 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, BOOL saved) case LLAssetType::AT_SOUND: openEmbeddedSound( item ); return TRUE; - + case LLAssetType::AT_NOTECARD: - openEmbeddedNotecard( item, saved ); + openEmbeddedNotecard( item ); return TRUE; case LLAssetType::AT_LANDMARK: openEmbeddedLandmark( item ); return TRUE; - + case LLAssetType::AT_LSL_TEXT: case LLAssetType::AT_CLOTHING: case LLAssetType::AT_OBJECT: @@ -1345,10 +1361,11 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item, BOOL saved) case LLAssetType::AT_ANIMATION: case LLAssetType::AT_GESTURE: showCopyToInvDialog( item ); - return TRUE; + return TRUE; default: return FALSE; } + } @@ -1401,23 +1418,30 @@ void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item ) open_landmark((LLViewerInventoryItem*)item, title, FALSE, item->getUUID(), TRUE); } -void LLViewerTextEditor::openEmbeddedNotecard( LLInventoryItem* item, BOOL saved ) +void LLViewerTextEditor::openEmbeddedNotecard( LLInventoryItem* item ) { - if (saved) - { + //if (saved) + //{ // An LLInventoryItem needs to be in an inventory to be opened. // This will give the item to the viewer's agent. // The callback will attempt to open it if its not already opened. - copyInventory(item, gInventoryCallbacks.registerCB(mInventoryCallback)); - } - else - { - LLNotecardCopyInfo *info = new LLNotecardCopyInfo(this, item); - gViewerWindow->alertXml("ConfirmNotecardSave", - LLViewerTextEditor::onNotecardDialog, (void*)info); - } + copyInventory(item, gInventoryCallbacks.registerCB(mInventoryCallback)); + + //} + //else + //{ + // LLNotecardCopyInfo *info = new LLNotecardCopyInfo(this, item); + // gViewerWindow->alertXml("ConfirmNotecardSave", + // LLViewerTextEditor::onNotecardDialog, (void*)info); + //} } +void LLViewerTextEditor::showUnsavedAlertDialog( LLInventoryItem* item ) +{ + LLNotecardCopyInfo *info = new LLNotecardCopyInfo(this, item); + gViewerWindow->alertXml( "ConfirmNotecardSave", + LLViewerTextEditor::onNotecardDialog, (void*)info); +} // static void LLViewerTextEditor::onNotecardDialog( S32 option, void* userdata ) { @@ -1468,7 +1492,7 @@ bool LLViewerTextEditor::importStream(std::istream& str) const std::vector >& items = nc.getItems(); mEmbeddedItemList->addItems(items); // Actually set the text - if (mAllowEmbeddedItems) + if (allowsEmbeddedItems()) { if (nc.getVersion() == 1) setASCIIEmbeddedText( nc.getText() ); @@ -1492,7 +1516,7 @@ void LLViewerTextEditor::copyInventory(const LLInventoryItem* item, U32 callback bool LLViewerTextEditor::hasEmbeddedInventory() { - return (!(mEmbeddedItemList->empty())); + return ! mEmbeddedItemList->empty(); } //////////////////////////////////////////////////////////////////////////// @@ -1555,11 +1579,9 @@ LLView* LLViewerTextEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlF font, allow_embedded_items); - BOOL ignore_tabs = text_editor->mTabToNextField; + BOOL ignore_tabs = text_editor->tabsToNextField(); node->getAttributeBOOL("ignore_tab", ignore_tabs); - - text_editor->setTabToNextField(ignore_tabs); - + text_editor->setTabsToNextField(ignore_tabs); text_editor->setTextEditorParameters(node); @@ -1567,7 +1589,7 @@ LLView* LLViewerTextEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlF node->getAttributeBOOL("hide_scrollbar",hide_scrollbar); text_editor->setHideScrollbarForShortDocs(hide_scrollbar); - BOOL hide_border = !text_editor->mBorder->getVisible(); + BOOL hide_border = !text_editor->isBorderVisible(); node->getAttributeBOOL("hide_border", hide_border); text_editor->setBorderVisible(!hide_border); diff --git a/linden/indra/newview/llviewertexteditor.h b/linden/indra/newview/llviewertexteditor.h index b09e92e..9b9bd2f 100644 --- a/linden/indra/newview/llviewertexteditor.h +++ b/linden/indra/newview/llviewertexteditor.h @@ -1,6 +1,6 @@ /** * @file llviewertexteditor.h - * @brief Text editor widget to let users enter a a multi-line document// + * @brief Text editor widget to let users enter a multi-line document// * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -34,17 +34,12 @@ #include "lltexteditor.h" -class LLInventoryItem; -class LLEmbeddedItems; -class LLEmbeddedNotecardOpener; // // Classes // class LLViewerTextEditor : public LLTextEditor { - friend class LLEmbeddedItems; - friend class LLTextCmdInsertEmbeddedItem; public: LLViewerTextEditor(const LLString& name, @@ -72,7 +67,7 @@ public: BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, LLString& tooltip_msg); - const LLInventoryItem* getDragItem() { return mDragItem; } + const class LLInventoryItem* getDragItem() const { return mDragItem; } virtual BOOL importBuffer(const LLString& buffer); virtual bool importStream(std::istream& str); virtual BOOL exportBuffer(LLString& buffer); @@ -86,9 +81,9 @@ public: void setEmbeddedText(const LLString& instr); LLString getEmbeddedText(); + // Appends Second Life time, small font, grey. + // If this starts a line, you need to prepend a newline. LLString appendTime(bool prepend_newline); - // Appends Second Life time, small font, grey - // If this starts a line, you need to prepend a newline. void copyInventory(const LLInventoryItem* item, U32 callback_id = 0); @@ -99,38 +94,46 @@ public: // rather than checking if a re-load is necessary. Phoenix 2007-02-27 bool hasEmbeddedInventory(); -protected: +private: // Embedded object operations virtual llwchar pasteEmbeddedItem(llwchar ext_char); - virtual void bindEmbeddedChars(const LLFontGL* font); - virtual void unbindEmbeddedChars(const LLFontGL* font); + virtual void bindEmbeddedChars(LLFontGL* font) const; + virtual void unbindEmbeddedChars(LLFontGL* font) const; - BOOL getEmbeddedItemToolTipAtPos(S32 pos, LLWString &wmsg); + BOOL getEmbeddedItemToolTipAtPos(S32 pos, LLWString &wmsg) const; BOOL openEmbeddedItemAtPos( S32 pos ); - BOOL openEmbeddedItem(LLInventoryItem* item, BOOL saved); + BOOL openEmbeddedItem(LLInventoryItem* item); S32 insertEmbeddedItem(S32 pos, LLInventoryItem* item); void openEmbeddedTexture( LLInventoryItem* item ); void openEmbeddedSound( LLInventoryItem* item ); void openEmbeddedLandmark( LLInventoryItem* item ); - void openEmbeddedNotecard( LLInventoryItem* item, BOOL saved ); + void openEmbeddedNotecard( LLInventoryItem* item); void showCopyToInvDialog( LLInventoryItem* item ); + void showUnsavedAlertDialog( LLInventoryItem* item ); static void onCopyToInvDialog( S32 option, void* userdata ); static void onNotecardDialog( S32 option, void* userdata ); -protected: LLPointer mDragItem; BOOL mDragItemSaved; - LLEmbeddedItems* mEmbeddedItemList; + class LLEmbeddedItems* mEmbeddedItemList; LLUUID mObjectID; LLUUID mNotecardInventoryID; - LLPointer mInventoryCallback; + LLPointer mInventoryCallback; + + // *TODO: Add right click menus for SLURLs + //LLHandle mPopupMenuHandle; + + // + // Inner classes + // + + class LLTextCmdInsertEmbeddedItem; - LLViewHandle mPopupMenuHandle; }; #endif // LL_VIEWERTEXTEDITOR_H diff --git a/linden/indra/newview/llvieweruictrlfactory.cpp b/linden/indra/newview/llvieweruictrlfactory.cpp index e3162b1..3a4df1c 100644 --- a/linden/indra/newview/llvieweruictrlfactory.cpp +++ b/linden/indra/newview/llvieweruictrlfactory.cpp @@ -65,9 +65,7 @@ LLViewerUICtrlFactory::LLViewerUICtrlFactory() LLUICtrlCreator::registerCreator(LL_NAME_LIST_CTRL_TAG, this); LLUICtrlCreator::registerCreator(LL_NAME_EDITOR_TAG, this); LLUICtrlCreator::registerCreator(LL_INVENTORY_PANEL_TAG, this); -#if LL_LIBXUL_ENABLED LLUICtrlCreator::registerCreator(LL_WEB_BROWSER_CTRL_TAG, this); -#endif LLUICtrlCreator::registerCreator(LL_JOYSTICK_SLIDE, this); LLUICtrlCreator::registerCreator(LL_JOYSTICK_TURN, this); LLUICtrlCreator::registerCreator(LL_MEDIA_REMOTE_CTRL_TAG, this); @@ -86,45 +84,45 @@ LLViewerUICtrlFactory::~LLViewerUICtrlFactory() LLColorSwatchCtrl* LLViewerUICtrlFactory::getColorSwatchByName(LLPanel* panelp, const LLString& name) { - return (LLColorSwatchCtrl*) panelp->getCtrlByNameAndType(name, WIDGET_TYPE_COLOR_SWATCH); + return panelp->getChild(name); } LLNameListCtrl* LLViewerUICtrlFactory::getNameListByName(LLPanel* panelp, const LLString& name) { - return (LLNameListCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_NAME_LIST); + return panelp->getChild(name); } LLTextureCtrl* LLViewerUICtrlFactory::getTexturePickerByName(LLPanel* panelp, const LLString& name) { - return (LLTextureCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_TEXTURE_PICKER); + return panelp->getChild(name); } LLWebBrowserCtrl* LLViewerUICtrlFactory::getWebBrowserByName(LLPanel* panelp, const LLString& name) { - return (LLWebBrowserCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_WEBBROWSER); + return panelp->getChild(name); } LLViewerTextEditor* LLViewerUICtrlFactory::getViewerTextEditorByName(LLPanel* panelp, const LLString& name) { - return (LLViewerTextEditor*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_TEXT_EDITOR); + return panelp->getChild(name); } LLNameEditor* LLViewerUICtrlFactory::getNameEditorByName(LLPanel* panelp, const LLString& name) { - return (LLNameEditor*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_NAME_EDITOR); + return panelp->getChild(name); } LLMediaRemoteCtrl* LLViewerUICtrlFactory::getMediaRemoteByName(LLPanel* panelp, const LLString& name) { - return (LLMediaRemoteCtrl*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_MEDIA_REMOTE); + return panelp->getChild(name); } LLJoystickAgentTurn* LLViewerUICtrlFactory::getJoystickAgentTurnByName(LLPanel* panelp, const LLString& name) { - return (LLJoystickAgentTurn*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_JOYSTICK_TURN); + return panelp->getChild(name); } LLJoystickAgentSlide* LLViewerUICtrlFactory::getJoystickAgentSlideByName(LLPanel* panelp, const LLString& name) { - return (LLJoystickAgentSlide*)panelp->getCtrlByNameAndType(name, WIDGET_TYPE_JOYSTICK_SLIDE); + return panelp->getChild(name); } diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp index b0577e6..eaaa4d2 100644 --- a/linden/indra/newview/llviewerwindow.cpp +++ b/linden/indra/newview/llviewerwindow.cpp @@ -42,7 +42,7 @@ #include "llviewquery.h" #include "llxmltree.h" //#include "llviewercamera.h" -//#include "imdebug.h" +#include "llglimmediate.h" #include "llvoiceclient.h" // for push-to-talk button handling @@ -57,10 +57,8 @@ // linden library includes #include "audioengine.h" // mute on minimize #include "indra_constants.h" -#include "linked_lists.h" #include "llassetstorage.h" #include "llfontgl.h" -#include "llmediaengine.h" // mute on minimize #include "llrect.h" #include "llsky.h" #include "llstring.h" @@ -184,6 +182,7 @@ #include "llappviewer.h" #include "llurlsimstring.h" #include "llviewerdisplay.h" +#include "llspatialpartition.h" #if LL_WINDOWS #include "llwindebug.h" @@ -193,11 +192,13 @@ // // Globals // - +void render_ui_and_swap_if_needed(); +void render_ui_and_swap(); LLBottomPanel* gBottomPanel = NULL; extern BOOL gDebugClicks; extern BOOL gDisplaySwapBuffers; +extern BOOL gResizeScreenTexture; extern S32 gJamesInt; LLViewerWindow *gViewerWindow = NULL; @@ -532,13 +533,68 @@ public: addText(xpos, ypos, llformat("%d MB Vertex Data", LLVertexBuffer::sAllocatedBytes/(1024*1024))); ypos += y_inc; - addText(xpos, ypos, llformat("%d Pending Lock", LLVertexBuffer::sLockedList.size())); + addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount)); ypos += y_inc; - addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount)); + addText(xpos, ypos, llformat("%d Mapped Buffers", LLVertexBuffer::sMappedCount)); + ypos += y_inc; + + addText(xpos, ypos, llformat("%d Vertex Buffer Binds", LLVertexBuffer::sBindCount)); + ypos += y_inc; + + addText(xpos, ypos, llformat("%d Vertex Buffer Sets", LLVertexBuffer::sSetCount)); + ypos += y_inc; + + addText(xpos, ypos, llformat("%d Texture Binds", LLImageGL::sBindCount)); ypos += y_inc; - } + addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount)); + ypos += y_inc; + + addText(xpos, ypos, llformat("%d Render Calls", gPipeline.mBatchCount)); + ypos += y_inc; + + addText(xpos, ypos, llformat("%d Matrix Ops", gPipeline.mMatrixOpCount)); + ypos += y_inc; + + addText(xpos, ypos, llformat("%d Texture Matrix Ops", gPipeline.mTextureMatrixOps)); + ypos += y_inc; + + gPipeline.mTextureMatrixOps = 0; + gPipeline.mMatrixOpCount = 0; + + if (gPipeline.mBatchCount > 0) + { + addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", gPipeline.mMinBatchSize, gPipeline.mMaxBatchSize, + gPipeline.mMeanBatchSize)); + + gPipeline.mMinBatchSize = gPipeline.mMaxBatchSize; + gPipeline.mMaxBatchSize = 0; + gPipeline.mBatchCount = 0; + } + ypos += y_inc; + + addText(xpos,ypos, llformat("%d/%d Nodes visible", gPipeline.mNumVisibleNodes, LLSpatialGroup::sNodeCount)); + + ypos += y_inc; + + + addText(xpos,ypos, llformat("%d Avatars visible", LLVOAvatar::sNumVisibleAvatars)); + + ypos += y_inc; + + LLVertexBuffer::sBindCount = LLImageGL::sBindCount = + LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount = + gPipeline.mNumVisibleNodes = 0; + } + if (gSavedSettings.getBOOL("DebugShowColor")) + { + U8 color[4]; + LLCoordGL coord = gViewerWindow->getCurrentMouse(); + glReadPixels(coord.mX, coord.mY, 1,1,GL_RGBA, GL_UNSIGNED_BYTE, color); + addText(xpos, ypos, llformat("%d %d %d %d", color[0], color[1], color[2], color[3])); + ypos += y_inc; + } // only display these messages if we are actually rendering beacons at this moment if (LLPipeline::getRenderBeacons(NULL) && LLPipeline::getProcessBeacons(NULL)) { @@ -608,6 +664,8 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask x = llround((F32)x / mDisplayScale.mV[VX]); y = llround((F32)y / mDisplayScale.mV[VY]); + LLView::sMouseHandlerMessage = ""; + if (gDebugClicks) { llinfos << "ViewerWindow left mouse down at " << x << "," << y << llendl; @@ -685,7 +743,6 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask if (LLView::sDebugMouseHandling) { llinfos << "Left Mouse Down" << LLView::sMouseHandlerMessage << llendl; - LLView::sMouseHandlerMessage = ""; } return TRUE; } @@ -721,6 +778,8 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma x = llround((F32)x / mDisplayScale.mV[VX]); y = llround((F32)y / mDisplayScale.mV[VY]); + LLView::sMouseHandlerMessage = ""; + if (gDebugClicks) { llinfos << "ViewerWindow left mouse double-click at " << x << "," << y << llendl; @@ -769,7 +828,6 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma if (LLView::sDebugMouseHandling) { llinfos << "Left Mouse Down" << LLView::sMouseHandlerMessage << llendl; - LLView::sMouseHandlerMessage = ""; } return TRUE; } @@ -803,6 +861,8 @@ BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) x = llround((F32)x / mDisplayScale.mV[VX]); y = llround((F32)y / mDisplayScale.mV[VY]); + LLView::sMouseHandlerMessage = ""; + if (gDebugClicks) { llinfos << "ViewerWindow left mouse up" << llendl; @@ -869,7 +929,6 @@ BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) if (handled) { llinfos << "Left Mouse Up" << LLView::sMouseHandlerMessage << llendl; - LLView::sMouseHandlerMessage = ""; } else { @@ -897,6 +956,8 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK x = llround((F32)x / mDisplayScale.mV[VX]); y = llround((F32)y / mDisplayScale.mV[VY]); + LLView::sMouseHandlerMessage = ""; + if (gDebugClicks) { llinfos << "ViewerWindow right mouse down at " << x << "," << y << llendl; @@ -967,7 +1028,6 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK if (LLView::sDebugMouseHandling) { llinfos << "Right Mouse Down" << LLView::sMouseHandlerMessage << llendl; - LLView::sMouseHandlerMessage = ""; } return TRUE; } @@ -1009,6 +1069,8 @@ BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK m x = llround((F32)x / mDisplayScale.mV[VX]); y = llround((F32)y / mDisplayScale.mV[VY]); + LLView::sMouseHandlerMessage = ""; + // Don't care about caps lock for mouse events. if (gDebugClicks) { @@ -1075,7 +1137,6 @@ BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK m if (handled) { llinfos << "Right Mouse Up" << LLView::sMouseHandlerMessage << llendl; - LLView::sMouseHandlerMessage = ""; } else { @@ -1505,63 +1566,39 @@ LLViewerWindow::LLViewerWindow( LLFontManager::initClass(); - // Initialize OpenGL Renderer + // + // We want to set this stuff up BEFORE we initialize the pipeline, so we can turn off + // stuff like AGP if we think that it'll crash the viewer. + // + llinfos << "Loading feature tables." << llendl; + + gFeatureManagerp->init(); - if (!gFeatureManagerp->isFeatureAvailable("RenderVBO") || + // Initialize OpenGL Renderer + if (!gFeatureManagerp->isFeatureAvailable("RenderVBOEnable") || !gGLManager.mHasVertexBufferObject) { gSavedSettings.setBOOL("RenderVBOEnable", FALSE); } LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable")); - // - // We want to set this stuff up BEFORE we initialize the pipeline, so we can turn off - // stuff like AGP if we think that it'll crash the viewer. - // - gFeatureManagerp->initGraphicsFeatureMasks(); if (gFeatureManagerp->isSafe() - || (gSavedSettings.getS32("LastFeatureVersion") != gFeatureManagerp->getVersion())) - { - gFeatureManagerp->applyRecommendedFeatures(); - } - - S32 idx = gSavedSettings.getS32("GraphicsCardMemorySetting"); - // -1 indicates use default (max) - if (idx == -1) + || (gSavedSettings.getS32("LastFeatureVersion") != gFeatureManagerp->getVersion()) + || (gSavedSettings.getBOOL("ProbeHardwareOnStartup"))) { - idx = LLViewerImageList::getMaxVideoRamSetting(-2); // get max recommended setting - gSavedSettings.setS32("GraphicsCardMemorySetting", idx); + gFeatureManagerp->applyRecommendedSettings(); + gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE); } // If we crashed while initializng GL stuff last time, disable certain features if (gSavedSettings.getBOOL("RenderInitError")) { mInitAlert = "DisplaySettingsNoShaders"; - gSavedSettings.setBOOL("VertexShaderEnable", FALSE); - } + gFeatureManagerp->setGraphicsLevel(0, false); + gSavedSettings.setU32("RenderQualityPerformance", 0); - if (!gNoRender) - { - // - // Initialize GL stuff - // - - // Set this flag in case we crash while initializing GL - gSavedSettings.setBOOL("RenderInitError", TRUE); - gSavedSettings.saveToFile( gSettingsFileName, TRUE ); - - gPipeline.init(); - stop_glerror(); - initGLDefaults(); - - gSavedSettings.setBOOL("RenderInitError", FALSE); - gSavedSettings.saveToFile( gSettingsFileName, TRUE ); } - - // - // Done initing GL stuff. - // - + // set callbacks mWindow->setCallbacks(this); @@ -1605,11 +1642,7 @@ LLViewerWindow::LLViewerWindow( void LLViewerWindow::initGLDefaults() { - //LLGLState::reset(); - //gGLSDefault.set(); - //LLGLState::verify(TRUE); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); F32 ambient[4] = {0.f,0.f,0.f,0.f }; @@ -1620,10 +1653,14 @@ void LLViewerWindow::initGLDefaults() glPixelStorei(GL_PACK_ALIGNMENT,1); glPixelStorei(GL_UNPACK_ALIGNMENT,1); + glEnable(GL_TEXTURE_2D); + // lights for objects glShadeModel( GL_SMOOTH ); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glCullFace(GL_BACK); @@ -1632,8 +1669,6 @@ void LLViewerWindow::initGLDefaults() gBox.prerender(); gSphere.prerender(); gCylinder.prerender(); - - LLVOAvatar::initVertexPrograms(); } void LLViewerWindow::initBase() @@ -1782,18 +1817,23 @@ void adjust_rect_bottom_center(const LLString& control, const LLRect& window) } } - -void update_saved_window_size(const LLString& control,S32 delta_width, S32 delta_height) +void adjust_rect_centered_partial_zoom(const LLString& control, + const LLRect& window) { - if (delta_width || delta_height ) - { - LLRect mXMLRect = gSavedSettings.getRect(control); - //hard code it all follows the right and top - mXMLRect.mRight += delta_width; - mXMLRect.mTop += delta_height; - mXMLRect.mLeft = llmax (0, mXMLRect.mLeft+delta_width); - mXMLRect.mBottom = llmax(0,mXMLRect.mBottom+delta_height); - gSavedSettings.setRect(control,mXMLRect); + LLRect rect = gSavedSettings.getRect(control); + // Only adjust on first use + if (rect.mLeft == 0 && rect.mBottom == 0) + { + S32 width = window.getWidth(); + S32 height = window.getHeight(); + rect.set(0, height-STATUS_BAR_HEIGHT, width, TOOL_BAR_HEIGHT); + // Make floater fill 80% of window, leaving 20% padding on + // the sides. + const F32 ZOOM_FRACTION = 0.8f; + S32 dx = (S32)(width * (1.f - ZOOM_FRACTION)); + S32 dy = (S32)(height * (1.f - ZOOM_FRACTION)); + rect.stretch(-dx/2, -dy/2); + gSavedSettings.setRect(control, rect); } } @@ -1816,7 +1856,7 @@ void LLViewerWindow::adjustRectanglesForFirstUse(const LLRect& window) adjust_rect_top_left("FloaterGestureRect", window); - adjust_rect_top_right("FloaterMapRect", window); + adjust_rect_top_right("FloaterMiniMapRect", window); adjust_rect_top_right("FloaterLagMeter", window); @@ -1885,17 +1925,8 @@ void LLViewerWindow::initWorldUI() LLWorldMapView::initClass(); - LLRect world_map_rect = gSavedSettings.getRect("FloaterWorldMapRect"); - // if 0,0,0,0 then use fullscreen - if (world_map_rect.mTop == 0 - && world_map_rect.mLeft == 0 - && world_map_rect.mRight == 0 - && world_map_rect.mBottom == 0) - { - world_map_rect.set(0, height-TOOL_BAR_HEIGHT, width, STATUS_BAR_HEIGHT); - world_map_rect.stretch(-4); - gSavedSettings.setRect("FloaterWorldMapRect", world_map_rect); - } + adjust_rect_centered_partial_zoom("FloaterWorldMapRect2", full_window); + gFloaterWorldMap = new LLFloaterWorldMap(); gFloaterWorldMap->setVisible(FALSE); @@ -2089,9 +2120,6 @@ void LLViewerWindow::reshape(S32 width, S32 height) } } - // changes in window's width and hight - S32 delta_width = width - mWindowRect.getWidth(); - S32 delta_height = height - mWindowRect.getHeight(); // update our window rectangle mWindowRect.mRight = mWindowRect.mLeft + width; mWindowRect.mTop = mWindowRect.mBottom + height; @@ -2142,17 +2170,12 @@ void LLViewerWindow::reshape(S32 width, S32 height) { gSavedSettings.setS32("WindowWidth", window_size.mX); gSavedSettings.setS32("WindowHeight", window_size.mY); - if (!gFloaterMap) - { - update_saved_window_size("FloaterWorldMapRect",delta_width, delta_height); - update_saved_window_size("FloaterMapRect",delta_width, delta_height); - } - } } gViewerStats->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width); gViewerStats->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height); + gResizeScreenTexture = TRUE; } } @@ -2218,11 +2241,20 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid) void LLViewerWindow::drawDebugText() { - mDebugText->draw(); + gGL.start(); + gGL.pushMatrix(); + { + // scale view by UI global scale factor and aspect ratio correction factor + glScalef(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); + mDebugText->draw(); + } + gGL.popMatrix(); + gGL.stop(); } void LLViewerWindow::draw() { + #if LL_DEBUG LLView::sIsDrawing = TRUE; #endif @@ -2264,7 +2296,7 @@ void LLViewerWindow::draw() // Draw all nested UI views. // No translation needed, this view is glued to 0,0 - glPushMatrix(); + gGL.pushMatrix(); { // scale view by UI global scale factor and aspect ratio correction factor glScalef(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); @@ -2289,11 +2321,6 @@ void LLViewerWindow::draw() } } - { - LLGLSTexture gls_texture; - drawDebugText(); - } - if (gToolMgr) { // Draw tool specific overlay on world @@ -2354,7 +2381,6 @@ void LLViewerWindow::draw() { // Used for special titles such as "Second Life - Special E3 2003 Beta" const S32 DIST_FROM_TOP = 20; - LLGLSTexture gls_texture; LLFontGL::sSansSerifBig->renderUTF8( mOverlayTitle, 0, llround( gViewerWindow->getWindowWidth() * 0.5f), @@ -2365,8 +2391,7 @@ void LLViewerWindow::draw() LLUI::sGLScaleFactor = old_scale_factor; } - glPopMatrix(); - + gGL.popMatrix(); #if LL_DEBUG LLView::sIsDrawing = FALSE; @@ -2642,6 +2667,8 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask) void LLViewerWindow::handleScrollWheel(S32 clicks) { + LLView::sMouseHandlerMessage = ""; + gMouseIdleTimer.reset(); // Hide tooltips @@ -2678,7 +2705,6 @@ void LLViewerWindow::handleScrollWheel(S32 clicks) if (LLView::sDebugMouseHandling) { llinfos << "Scroll Wheel" << LLView::sMouseHandlerMessage << llendl; - LLView::sMouseHandlerMessage = ""; } return; } @@ -2720,6 +2746,8 @@ BOOL LLViewerWindow::handlePerFrameHover() { static std::string last_handle_msg; + LLView::sMouseHandlerMessage = ""; + //RN: fix for asynchronous notification of mouse leaving window not working LLCoordWindow mouse_pos; mWindow->getCursorPosition(&mouse_pos); @@ -2777,23 +2805,23 @@ BOOL LLViewerWindow::handlePerFrameHover() { gFocusMgr.releaseFocusIfNeeded(cur_focus); - LLView* parent = cur_focus->getParent(); - LLView* focus_root = cur_focus->findRootMostFocusRoot(); + LLUICtrl* parent = cur_focus->getParentUICtrl(); + const LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot(); while(parent) { if (parent->isCtrl() && - (((LLUICtrl*)parent)->hasTabStop() || parent == focus_root) && - !((LLUICtrl*)parent)->getIsChrome() && + (parent->hasTabStop() || parent == focus_root) && + !parent->getIsChrome() && parent->isInVisibleChain() && parent->isInEnabledChain()) { if (!parent->focusFirstItem()) { - ((LLUICtrl*)parent)->setFocus(TRUE); + parent->setFocus(TRUE); } break; } - parent = parent->getParent(); + parent = parent->getParentUICtrl(); } } else if (cur_focus->isFocusRoot()) @@ -2855,7 +2883,6 @@ BOOL LLViewerWindow::handlePerFrameHover() last_handle_msg = LLView::sMouseHandlerMessage; llinfos << "Hover" << LLView::sMouseHandlerMessage << llendl; } - LLView::sMouseHandlerMessage = ""; handled = TRUE; } else if (LLView::sDebugMouseHandling) @@ -3021,7 +3048,7 @@ BOOL LLViewerWindow::handlePerFrameHover() } // snap floaters to top of chat bar/button strip - LLView* chatbar_and_buttons = gOverlayBar->getChildByName("chatbar_and_buttons", TRUE); + LLView* chatbar_and_buttons = gOverlayBar->getChild("chatbar_and_buttons", TRUE); // find top of chatbar and strate buttons, if either are visible if (chatbar_and_buttons && !chatbar_and_buttons->getLocalBoundingRect().isNull()) { @@ -3061,9 +3088,9 @@ BOOL LLViewerWindow::handlePerFrameHover() mLastMousePoint = mCurrentMousePoint; // last ditch force of edit menu to selection manager - if (gEditMenuHandler == NULL && gSelectMgr && gSelectMgr->getSelection()->getObjectCount()) + if (LLEditMenuHandler::gEditMenuHandler == NULL && gSelectMgr && gSelectMgr->getSelection()->getObjectCount()) { - gEditMenuHandler = gSelectMgr; + LLEditMenuHandler::gEditMenuHandler = gSelectMgr; } if (gFloaterView->getCycleMode()) @@ -3195,11 +3222,12 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, } // Render light for editing - if (LLSelectMgr::sRenderLightRadius) + if (LLSelectMgr::sRenderLightRadius && gToolMgr->inEdit()) { + LLImageGL::unbindTexture(0); LLGLEnable gls_blend(GL_BLEND); LLGLEnable gls_cull(GL_CULL_FACE); - LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); glMatrixMode(GL_MODELVIEW); glPushMatrix(); if (selection->getSelectType() == SELECT_TYPE_HUD) @@ -3362,6 +3390,10 @@ void LLViewerWindow::hitObjectOrLandGlobalAsync(S32 x, S32 y_from_bot, MASK mask { return; } + + render_ui_and_swap_if_needed(); + glClear(GL_DEPTH_BUFFER_BIT); + gDisplaySwapBuffers = FALSE; S32 scaled_x = llround((F32)x * mDisplayScale.mV[VX]); S32 scaled_y = llround((F32)y_from_bot * mDisplayScale.mV[VY]); @@ -3402,6 +3434,8 @@ void LLViewerWindow::hitObjectOrLandGlobalAsync(S32 x, S32 y_from_bot, MASK mask pick_camera.setAspect(1.f); // save our drawing state + // *TODO: should we be saving using the new method here using + // glh_get_current_projection/glh_set_current_projection? -brad glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); @@ -3415,13 +3449,18 @@ void LLViewerWindow::hitObjectOrLandGlobalAsync(S32 x, S32 y_from_bot, MASK mask // Don't limit the select distance for this pick. // make viewport big enough to handle antialiased frame buffers gCamera->setPerspective(FOR_SELECTION, scaled_x - (PICK_HALF_WIDTH + 2), scaled_y - (PICK_HALF_WIDTH + 2), PICK_DIAMETER + 4, PICK_DIAMETER + 4, FALSE); - pick_camera.calcAgentFrustumPlanes(gCamera->mAgentFrustum); // make viewport big enough to handle antialiased frame buffers - glViewport(scaled_x - (PICK_HALF_WIDTH + 2), scaled_y - (PICK_HALF_WIDTH + 2), PICK_DIAMETER + 4, PICK_DIAMETER + 4); + gGLViewport[0] = scaled_x - (PICK_HALF_WIDTH + 2); + gGLViewport[1] = scaled_y - (PICK_HALF_WIDTH + 2); + gGLViewport[2] = PICK_DIAMETER + 4; + gGLViewport[3] = PICK_DIAMETER + 4; + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + LLViewerCamera::updateFrustumPlanes(pick_camera); stop_glerror(); glClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + //glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Draw the objects so the user can select them. // The starting ID is 1, since land is zero. @@ -4279,7 +4318,7 @@ BOOL LLViewerWindow::saveSnapshot( const LLString& filepath, S32 image_width, S3 llinfos << "Saving snapshot to: " << filepath << llendl; LLPointer raw = new LLImageRaw; - BOOL success = rawSnapshot(raw, image_width, image_height, TRUE, show_ui, do_rebuild); + BOOL success = rawSnapshot(raw, image_width, image_height, TRUE, FALSE, show_ui, do_rebuild); if (success) { @@ -4312,10 +4351,10 @@ void LLViewerWindow::playSnapshotAnimAndSound() // Saves the image from the screen to the specified filename and path. BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, - BOOL keep_window_aspect, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) + BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, ESnapshotType type, S32 max_size) { - F32 image_aspect_ratio = ((F32)image_width) / ((F32)image_height); - F32 window_aspect_ratio = ((F32)getWindowWidth()) / ((F32)getWindowHeight()); + //F32 image_aspect_ratio = ((F32)image_width) / ((F32)image_height); + //F32 window_aspect_ratio = ((F32)getWindowWidth()) / ((F32)getWindowHeight()); if ((!gWorldPointer) || (!raw)) @@ -4324,7 +4363,9 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei } // PRE SNAPSHOT - + render_ui_and_swap_if_needed(); + gDisplaySwapBuffers = FALSE; + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); setCursor(UI_CURSOR_WAIT); @@ -4336,7 +4377,6 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); } - BOOL hide_hud = !gSavedSettings.getBOOL("RenderHUDInSnapshot") && LLPipeline::sShowHUDAttachments; if (hide_hud) { @@ -4348,20 +4388,81 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei // from window S32 snapshot_width = mWindowRect.getWidth(); S32 snapshot_height = mWindowRect.getHeight(); - if (!keep_window_aspect) + F32 scale_factor = 1.0f ; + if (keep_window_aspect || is_texture) //map the entire window to snapshot + { + } + else //scale or crop { - if (image_aspect_ratio > window_aspect_ratio) + if(snapshot_width > image_width) //crop { - snapshot_height = llround((F32)snapshot_width / image_aspect_ratio); + snapshot_width = image_width ; } - else if (image_aspect_ratio < window_aspect_ratio) + if(snapshot_height > image_height)//crop { - snapshot_width = llround((F32)snapshot_height * image_aspect_ratio); + snapshot_height = image_height ; } + + //if (image_aspect_ratio > window_aspect_ratio) + //{ + // snapshot_height = llround((F32)snapshot_width / image_aspect_ratio); + //} + //else if (image_aspect_ratio < window_aspect_ratio) + //{ + // snapshot_width = llround((F32)snapshot_height * image_aspect_ratio); + //} } - F32 scale_factor = llmax(1.f, (F32)image_width / snapshot_width, (F32)image_height / snapshot_height); - raw->resize(llfloor(snapshot_width*scale_factor), llfloor(snapshot_height *scale_factor), type == SNAPSHOT_TYPE_DEPTH ? 4 : 3); + LLRenderTarget target; + + scale_factor = llmax(1.f, (F32)image_width / snapshot_width, (F32)image_height / snapshot_height); + + // SNAPSHOT + S32 window_width = mWindowRect.getWidth(); + S32 window_height = mWindowRect.getHeight(); + + LLRect window_rect = mWindowRect; + + BOOL use_fbo = FALSE; + + if (gGLManager.mHasFramebufferObject && + (image_width > window_width || + image_height > window_height) && + !show_ui && + keep_window_aspect) + { + GLint max_size = 0; + glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &max_size); + + if (image_width <= max_size && image_height <= max_size) + { + use_fbo = TRUE; + + snapshot_width = image_width; + snapshot_height = image_height; + target.allocate(snapshot_width, snapshot_height, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB, TRUE); + window_width = snapshot_width; + window_height = snapshot_height; + scale_factor = 1.f; + mWindowRect.set(0, 0, snapshot_width, snapshot_height); + target.bindTarget(); + + + } + } + + S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f); + S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f); + + S32 image_buffer_x = llfloor(snapshot_width*scale_factor) ; + S32 image_buffer_y = llfloor(snapshot_height *scale_factor) ; + if(image_buffer_x > max_size || image_buffer_y > max_size) //boundary check to avoid memory overflow + { + scale_factor *= llmin((F32)max_size / image_buffer_x, (F32)max_size / image_buffer_y) ; + image_buffer_x = llfloor(snapshot_width*scale_factor) ; + image_buffer_y = llfloor(snapshot_height *scale_factor) ; + } + raw->resize(image_buffer_x, image_buffer_y, type == SNAPSHOT_TYPE_DEPTH ? 4 : 3); BOOL high_res = scale_factor > 1.f; if (high_res) @@ -4372,12 +4473,6 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei LLHUDText::reshape(); } - // SNAPSHOT - S32 window_width = mWindowRect.getWidth(); - S32 window_height = mWindowRect.getHeight(); - S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f); - S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f); - S32 output_buffer_offset_y = 0; F32 depth_conversion_factor_1 = (gCamera->getFar() + gCamera->getNear()) / (2.f * gCamera->getFar() * gCamera->getNear()); @@ -4408,9 +4503,10 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei } else { - display(do_rebuild, scale_factor, subimage_x+(subimage_y*llceil(scale_factor))); + display(do_rebuild, scale_factor, subimage_x+(subimage_y*llceil(scale_factor)), use_fbo); + render_ui_and_swap(); } - glFlush(); + S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width); // handle fractional rows U32 read_width = llmax(0, (window_width - subimage_x_offset) - @@ -4469,6 +4565,14 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei output_buffer_offset_y += subimage_y_offset; } + if (use_fbo) + { + mWindowRect = window_rect; + target.flush(); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } + gDisplaySwapBuffers = FALSE; + // POST SNAPSHOT if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { @@ -4486,14 +4590,20 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei LLHUDText::reshape(); } - gDisplaySwapBuffers = TRUE; - // Pre-pad image to number of pixels such that the line length is a multiple of 4 bytes (for BMP encoding) - // Note: this formula depends on the number of components being 3. Not obvious, but it's correct. - image_width += (image_width * (type == SNAPSHOT_TYPE_DEPTH ? 4 : 3)) % 4; + // Note: this formula depends on the number of components being 3. Not obvious, but it's correct. + image_width += (image_width * (type == SNAPSHOT_TYPE_DEPTH ? 4 : 3)) % 4 ; // Resize image - raw->scale( image_width, image_height ); + if(llabs(image_width - image_buffer_x) > 4 || llabs(image_height - image_buffer_y) > 4) + { + raw->scale( image_width, image_height ); + } + else if(image_width != image_buffer_x || image_height != image_buffer_y) + { + raw->scale( image_width, image_height, FALSE ); + } + setCursor(UI_CURSOR_ARROW); @@ -4541,7 +4651,7 @@ void LLViewerWindow::drawMouselookInstructions() { LLGLSNoTexture gls_no_texture; - glColor4f( 0.9f, 0.9f, 0.9f, 1.0f ); + gGL.color4f( 0.9f, 0.9f, 0.9f, 1.0f ); gl_rect_2d( instructions_rect ); } @@ -4624,12 +4734,16 @@ void LLViewerWindow::setTopCtrl(LLUICtrl* new_top) void LLViewerWindow::setupViewport(S32 x_offset, S32 y_offset) { - glViewport(x_offset, y_offset, mWindowRect.getWidth(), mWindowRect.getHeight()); + gGLViewport[0] = x_offset; + gGLViewport[1] = y_offset; + gGLViewport[2] = mWindowRect.getWidth(); + gGLViewport[3] = mWindowRect.getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); } void LLViewerWindow::setup3DRender() { - gCamera->setPerspective(NOT_FOR_SELECTION, 0, 0, mWindowRect.getWidth(), mWindowRect.getHeight(), FALSE, gCamera->getNear(), MAX_FAR_PLANE); + gCamera->setPerspective(NOT_FOR_SELECTION, 0, 0, mWindowRect.getWidth(), mWindowRect.getHeight(), FALSE, gCamera->getNear(), MAX_FAR_CLIP*2.f); } void LLViewerWindow::setup2DRender() @@ -4758,7 +4872,10 @@ void LLViewerWindow::stopGL(BOOL save_state) LLDynamicTexture::destroyGL(); stop_glerror(); - gPipeline.destroyGL(); + if (gPipeline.isInit()) + { + gPipeline.destroyGL(); + } gCone.cleanupGL(); gBox.cleanupGL(); @@ -4793,6 +4910,8 @@ void LLViewerWindow::restoreGL(const LLString& progress_message) LLDynamicTexture::restoreGL(); LLVOAvatar::restoreGL(); + gResizeScreenTexture = TRUE; + if (gFloaterCustomize && gFloaterCustomize->getVisible()) { LLVisualParamHint::requestHintUpdates(); @@ -4887,11 +5006,20 @@ BOOL LLViewerWindow::checkSettings() return FALSE; } +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); +#endif gViewerWindow->changeDisplaySettings(TRUE, LLCoordScreen(gSavedSettings.getS32("FullScreenWidth"), gSavedSettings.getS32("FullScreenHeight")), gSavedSettings.getBOOL("DisableVerticalSync"), mShowFullscreenProgress); + +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); +#endif return TRUE; } return FALSE; @@ -4918,6 +5046,8 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, mShowFullscreenProgress = show_progress_bar; gSavedSettings.setBOOL("FullScreen", mWantFullscreen); + gResizeScreenTexture = TRUE; + BOOL old_fullscreen = mWindow->getFullscreen(); if (!old_fullscreen && fullscreen && !LLStartUp::canGoFullscreen()) { @@ -5061,6 +5191,8 @@ void LLViewerWindow::drawPickBuffer() const { if (mPickBuffer) { + gGL.start(); + gGL.pushMatrix(); LLGLDisable no_blend(GL_BLEND); LLGLDisable no_alpha_test(GL_ALPHA_TEST); LLGLSNoTexture no_texture; @@ -5069,7 +5201,7 @@ void LLViewerWindow::drawPickBuffer() const ((F32)mPickPoint.mY * mDisplayScale.mV[VY] + 10.f)); glDrawPixels(PICK_DIAMETER, PICK_DIAMETER, GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer); glPixelZoom(1.f, 1.f); - glColor4fv(LLColor4::white.mV); + gGL.color4fv(LLColor4::white.mV); gl_rect_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] - (F32)(PICK_HALF_WIDTH)), llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH)), llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH)), @@ -5083,7 +5215,7 @@ void LLViewerWindow::drawPickBuffer() const llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] - (F32)(PICK_HALF_WIDTH)), llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_DIAMETER) * 10.f + 10.f), llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + 10.f)); - glTranslatef(10.f, 10.f, 0.f); + gGL.translatef(10.f, 10.f, 0.f); gl_rect_2d(llround((F32)mPickPoint.mX * mDisplayScale.mV[VX]), llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_DIAMETER) * 10.f), llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_DIAMETER) * 10.f), @@ -5094,7 +5226,8 @@ void LLViewerWindow::drawPickBuffer() const llround((F32)mPickPoint.mX * mDisplayScale.mV[VX] + (F32)(PICK_HALF_WIDTH + mPickOffset.mX + 1) * 10.f), llround((F32)mPickPoint.mY * mDisplayScale.mV[VY] + (F32)(PICK_HALF_WIDTH + mPickOffset.mY) * 10.f), FALSE); - glPopMatrix(); + gGL.popMatrix(); + gGL.stop(); } } diff --git a/linden/indra/newview/llviewerwindow.h b/linden/indra/newview/llviewerwindow.h index d27e74b..3122d8c 100644 --- a/linden/indra/newview/llviewerwindow.h +++ b/linden/indra/newview/llviewerwindow.h @@ -41,7 +41,6 @@ #ifndef LL_LLVIEWERWINDOW_H #define LL_LLVIEWERWINDOW_H -#include "linked_lists.h" #include "v3dmath.h" #include "v2math.h" #include "llwindow.h" @@ -61,6 +60,8 @@ class LLTextBox; class LLImageRaw; class LLHUDIcon; +#define MAX_IMAGE_SIZE 6144 //6 * 1024, max snapshot image size 6144 * 6144 + class LLViewerWindow : public LLWindowCallbacks { public: @@ -219,8 +220,8 @@ public: } ESnapshotType; BOOL saveSnapshot(const LLString& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR); - BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, - BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR ); + BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE, + BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_IMAGE_SIZE ); BOOL saveImageNumbered(LLImageRaw *raw, const LLString& extension = LLString()); void playSnapshotAnimAndSound(); diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 6798b4d..5d04009 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -37,6 +37,7 @@ #include "llvoavatar.h" +#include "llglimmediate.h" #include "audioengine.h" #include "imageids.h" #include "indra_constants.h" @@ -113,6 +114,7 @@ #include "llwearablelist.h" #include "llworld.h" #include "pipeline.h" +#include "llspatialpartition.h" #include "llglslshader.h" #include "llappviewer.h" #include "lscript_byteformat.h" @@ -255,6 +257,7 @@ S32 LLVOAvatar::sMaxOtherAvatarsToComposite = 1; // Only this many avatars (oth LLMap< LLGLenum, LLGLuint*> LLVOAvatar::sScratchTexNames; LLMap< LLGLenum, F32*> LLVOAvatar::sScratchTexLastBindTime; S32 LLVOAvatar::sScratchTexBytes = 0; +F32 LLVOAvatar::sRenderDistance = 256.f; S32 LLVOAvatar::sNumVisibleAvatars = 0; S32 LLVOAvatar::sNumLODChangesThisFrame = 0; @@ -279,8 +282,8 @@ BOOL LLVOAvatar::sShowAnimationDebug = FALSE; BOOL LLVOAvatar::sShowFootPlane = FALSE; BOOL LLVOAvatar::sShowCollisionVolumes = FALSE; BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE; -BOOL LLVOAvatar::sAvatarLoadTest = FALSE; F32 LLVOAvatar::sLODFactor = 1.f; +BOOL LLVOAvatar::sUseImpostors = TRUE; BOOL LLVOAvatar::sJointDebug = FALSE; S32 LLVOAvatar::sCurJoint = 0; @@ -679,7 +682,9 @@ LLVOAvatar::LLVOAvatar( mCulled( FALSE ), mTexSkinColor( NULL ), mTexHairColor( NULL ), - mTexEyeColor( NULL ) + mTexEyeColor( NULL ), + mNeedsSkin(FALSE), + mUpdatePeriod(1) { LLMemType mt(LLMemType::MTYPE_AVATAR); @@ -730,6 +735,11 @@ LLVOAvatar::LLVOAvatar( mIsSelf = FALSE; } + mNeedsImpostorUpdate = TRUE; + mNeedsAnimUpdate = TRUE; + + mImpostorDistance = 0; + setNumTEs(TEX_NUM_ENTRIES); mbCanSelect = TRUE; @@ -986,7 +996,8 @@ LLVOAvatar::~LLVOAvatar() delete mSkirtLayerSet; mSkirtLayerSet = NULL; - mAttachmentPoints.deleteAllData(); + std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer()); + mAttachmentPoints.clear(); delete mTexSkinColor; mTexSkinColor = NULL; @@ -996,6 +1007,7 @@ LLVOAvatar::~LLVOAvatar() mTexEyeColor = NULL; std::for_each(mMeshes.begin(), mMeshes.end(), DeletePairedPointer()); + mMeshes.clear(); mDead = TRUE; @@ -1269,16 +1281,6 @@ void LLVOAvatar::dumpBakedStatus() } //static -void LLVOAvatar::cleanupVertexPrograms() -{ -} - -//static -void LLVOAvatar::initVertexPrograms() -{ -} - -//static void LLVOAvatar::restoreGL() { for (std::vector::iterator iter = LLCharacter::sInstances.begin(); @@ -1299,7 +1301,19 @@ void LLVOAvatar::restoreGL() void LLVOAvatar::destroyGL() { deleteCachedImages(); - cleanupVertexPrograms(); + + resetImpostors(); +} + +//static +void LLVOAvatar::resetImpostors() +{ + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* avatar = (LLVOAvatar*) *iter; + avatar->mImpostor.release(); + } } // static @@ -1452,17 +1466,106 @@ void LLVOAvatar::cleanupClass() sXMLTree.cleanup(); } +const LLVector3 LLVOAvatar::getRenderPosition() const +{ + if (mDrawable.isNull() || mDrawable->getGeneration() < 0) + { + return getPositionAgent(); + } + else if (isRoot()) + { + return mDrawable->getPositionAgent(); + } + else + { + return getPosition() * mDrawable->getParent()->getRenderMatrix(); + } +} + +void LLVOAvatar::updateDrawable(BOOL force_damped) +{ + clearChanged(SHIFTED); +} + +void LLVOAvatar::onShift(const LLVector3& shift_vector) +{ + mLastAnimExtents[0] += shift_vector; + mLastAnimExtents[1] += shift_vector; + mNeedsImpostorUpdate = TRUE; + mNeedsAnimUpdate = TRUE; +} void LLVOAvatar::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax) { - LLVector3 center = getRenderPosition(); - LLVector3 size = getScale(); - //maximum amount an animation can move avatar from drawable position - LLVector3 animation_buffer(5, 5, 5); + if (isImpostor() && !needsImpostorUpdate()) + { + LLVector3 delta = getRenderPosition() - + ((LLVector3(mDrawable->getPositionGroup())-mImpostorOffset)); + + newMin = mLastAnimExtents[0] + delta; + newMax = mLastAnimExtents[1] + delta; + } + else + { + getSpatialExtents(newMin,newMax); + mLastAnimExtents[0] = newMin; + mLastAnimExtents[1] = newMax; + LLVector3 pos_group = (newMin+newMax)*0.5f; + mImpostorOffset = pos_group-getRenderPosition(); + mDrawable->setPositionGroup(pos_group); + } +} + +void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax) +{ + LLVector3 buffer(0.25f, 0.25f, 0.25f); + LLVector3 pos = getRenderPosition(); + newMin = pos - buffer; + newMax = pos + buffer; + + //stretch bounding box by joint positions + for (mesh_map_t::iterator i = mMeshes.begin(); i != mMeshes.end(); ++i) + { + LLPolyMesh* mesh = i->second; + for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.count(); joint_num++) + { + update_min_max(newMin, newMax, + mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation()); + } + } + + //stretch bounding box by attachments + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + + if(!attachment->getValid()) + { + continue ; + } + + LLViewerObject* object = attachment->getObject(); + if (object && !object->isHUDAttachment()) + { + LLDrawable* drawable = object->mDrawable; + if (drawable) + { + LLSpatialBridge* bridge = drawable->getSpatialBridge(); + if (bridge) + { + const LLVector3* ext = bridge->getSpatialExtents(); + update_min_max(newMin,newMax,ext[0]); + update_min_max(newMin,newMax,ext[1]); + } + } + } + } - newMin.setVec((center-size)-animation_buffer); - newMax.setVec(center+size+animation_buffer); - mDrawable->setPositionGroup((newMin + newMax) * 0.5f); + //pad bounding box + newMin -= buffer; + newMax += buffer; } @@ -1832,17 +1935,18 @@ void LLVOAvatar::buildCharacter() else { BOOL attachment_found = FALSE; - for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; if (attachment->getGroup() == i) { LLMenuItemCallGL* item; item = new LLMenuItemCallGL(attachment->getName(), - NULL, - object_selected_and_point_valid); - item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", mAttachmentPoints.reverseLookup(attachment)); + NULL, + object_selected_and_point_valid); + item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", curiter->first); gAttachPieMenu->append(item); @@ -1865,10 +1969,11 @@ void LLVOAvatar::buildCharacter() else { BOOL attachment_found = FALSE; - for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; if (attachment->getGroup() == i) { gDetachPieMenu->append(new LLMenuItemCallGL(attachment->getName(), @@ -1887,17 +1992,18 @@ void LLVOAvatar::buildCharacter() } // add screen attachments - for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; if (attachment->getGroup() == 8) { LLMenuItemCallGL* item; item = new LLMenuItemCallGL(attachment->getName(), - NULL, - object_selected_and_point_valid); - item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", mAttachmentPoints.reverseLookup(attachment)); + NULL, + object_selected_and_point_valid); + item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", curiter->first); gAttachScreenPieMenu->append(item); gDetachScreenPieMenu->append(new LLMenuItemCallGL(attachment->getName(), &handle_detach_from_avatar, object_attached, attachment)); @@ -1906,17 +2012,19 @@ void LLVOAvatar::buildCharacter() for (S32 pass = 0; pass < 2; pass++) { - for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; if (attachment->getIsHUDAttachment() != (pass == 1)) { continue; } LLMenuItemCallGL* item = new LLMenuItemCallGL(attachment->getName(), - NULL, &object_selected_and_point_valid, &attach_label, attachment); - item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", mAttachmentPoints.reverseLookup(attachment)); + NULL, &object_selected_and_point_valid, + &attach_label, attachment); + item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", curiter->first); gAttachSubMenu->append(item); gDetachSubMenu->append(new LLMenuItemCallGL(attachment->getName(), @@ -1939,26 +2047,29 @@ void LLVOAvatar::buildCharacter() continue; } - std::multimap attachment_pie_menu_map; + std::multimap attachment_pie_menu_map; // gather up all attachment points assigned to this group, and throw into map sorted by pie slice number - for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; if(attachment->getGroup() == group) { // use multimap to provide a partial order off of the pie slice key - attachment_pie_menu_map.insert(std::pair(attachment->getPieSlice(), attachment)); + S32 pie_index = attachment->getPieSlice(); + attachment_pie_menu_map.insert(std::make_pair(pie_index, curiter->first)); } } // add in requested order to pie menu, inserting separators as necessary - std::multimap::iterator attach_it; S32 cur_pie_slice = 0; - for (attach_it = attachment_pie_menu_map.begin(); attach_it != attachment_pie_menu_map.end(); ++attach_it) + for (std::multimap::iterator attach_it = attachment_pie_menu_map.begin(); + attach_it != attachment_pie_menu_map.end(); ++attach_it) { S32 requested_pie_slice = attach_it->first; + S32 attach_index = attach_it->second; while (cur_pie_slice < requested_pie_slice) { gAttachBodyPartPieMenus[group]->appendSeparator(); @@ -1966,16 +2077,18 @@ void LLVOAvatar::buildCharacter() cur_pie_slice++; } - LLViewerJointAttachment* attachment = attach_it->second; - - LLMenuItemCallGL* item = new LLMenuItemCallGL(attachment->getName(), - NULL, object_selected_and_point_valid); - gAttachBodyPartPieMenus[group]->append(item); - item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", mAttachmentPoints.reverseLookup(attachment)); - gDetachBodyPartPieMenus[group]->append(new LLMenuItemCallGL(attachment->getName(), - &handle_detach_from_avatar, object_attached, attachment)); - - cur_pie_slice++; + LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attach_index, (LLViewerJointAttachment*)NULL); + if (attachment) + { + LLMenuItemCallGL* item = new LLMenuItemCallGL(attachment->getName(), + NULL, object_selected_and_point_valid); + gAttachBodyPartPieMenus[group]->append(item); + item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", attach_index); + gDetachBodyPartPieMenus[group]->append(new LLMenuItemCallGL(attachment->getName(), + &handle_detach_from_avatar, + object_attached, attachment)); + cur_pie_slice++; + } } } } @@ -2015,13 +2128,14 @@ void LLVOAvatar::releaseMeshData() facep->setSize(0, 0); } - for (LLViewerJointAttachment *attachmentPoint = mAttachmentPoints.getFirstData(); - attachmentPoint; - attachmentPoint = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { - if (!attachmentPoint->getIsHUDAttachment()) + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if (!attachment->getIsHUDAttachment()) { - attachmentPoint->setAttachmentVisibility(FALSE); + attachment->setAttachmentVisibility(FALSE); } } mMeshValid = FALSE; @@ -2044,13 +2158,14 @@ void LLVOAvatar::restoreMeshData() } else { - for (LLViewerJointAttachment *attachmentPoint = mAttachmentPoints.getFirstData(); - attachmentPoint; - attachmentPoint = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { - if (!attachmentPoint->getIsHUDAttachment()) + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if (!attachment->getIsHUDAttachment()) { - attachmentPoint->setAttachmentVisibility(TRUE); + attachment->setAttachmentVisibility(TRUE); } } } @@ -2066,6 +2181,7 @@ void LLVOAvatar::updateMeshData() { if (mDrawable.notNull()) { + stop_glerror(); LLFace* facep = mDrawable->getFace(0); U32 num_vertices = 0; @@ -2088,6 +2204,7 @@ void LLVOAvatar::updateMeshData() facep->mVertexBuffer = new LLVertexBufferAvatar(); facep->mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE); + facep->setGeomIndex(0); facep->setIndicesIndex(0); @@ -2106,6 +2223,9 @@ void LLVOAvatar::updateMeshData() mSkirtLOD.updateFaceData(facep, mAdjustedPixelArea); mUpperBodyLOD.updateFaceData(facep, mAdjustedPixelArea); mHairLOD.updateFaceData(facep, mAdjustedPixelArea, TRUE); + + stop_glerror(); + facep->mVertexBuffer->setBuffer(0); } } @@ -2272,9 +2392,6 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) // force immediate pixel area update on avatars using last frames data (before drawable or camera updates) setPixelAreaAndAngle(gAgent); - // Update the LOD of the joints - //static const F32 UPDATE_TIME = .5f; - // force asynchronous drawable update if(mDrawable.notNull() && !gNoRender) { @@ -2332,86 +2449,87 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) // store off last frame's root position to be consistent with camera position LLVector3 root_pos_last = mRoot.getWorldPosition(); - updateCharacter(agent); - - //Ventrella - bool voiceEnabled = gVoiceClient->getVoiceEnabled( mID ) && gVoiceClient->inProximalChannel(); - // disable voice visualizer when in mouselook - mVoiceVisualizer->setVoiceEnabled( voiceEnabled && !(mIsSelf && gAgent.cameraMouselook()) ); - if ( voiceEnabled ) - { - //---------------------------------------------------------------- - // Only do gesture triggering for your own avatar, and only when you're in a proximal channel. - //---------------------------------------------------------------- - if( mIsSelf ) - { - //---------------------------------------------------------------------------------------- - // The following takes the voice signal and uses that to trigger gesticulations. - //---------------------------------------------------------------------------------------- - int lastGesticulationLevel = mCurrentGesticulationLevel; - mCurrentGesticulationLevel = mVoiceVisualizer->getCurrentGesticulationLevel(); - - //--------------------------------------------------------------------------------------------------- - // If "current gesticulation level" changes, we catch this, and trigger the new gesture - //--------------------------------------------------------------------------------------------------- - if ( lastGesticulationLevel != mCurrentGesticulationLevel ) + BOOL detailed_update = updateCharacter(agent); + + { + //Ventrella + bool voiceEnabled = gVoiceClient->getVoiceEnabled( mID ) && gVoiceClient->inProximalChannel(); + // disable voice visualizer when in mouselook + mVoiceVisualizer->setVoiceEnabled( voiceEnabled && !(mIsSelf && gAgent.cameraMouselook()) ); + if ( voiceEnabled ) + { + //---------------------------------------------------------------- + // Only do gesture triggering for your own avatar, and only when you're in a proximal channel. + //---------------------------------------------------------------- + if( mIsSelf ) { - if ( mCurrentGesticulationLevel != VOICE_GESTICULATION_LEVEL_OFF ) + //---------------------------------------------------------------------------------------- + // The following takes the voice signal and uses that to trigger gesticulations. + //---------------------------------------------------------------------------------------- + int lastGesticulationLevel = mCurrentGesticulationLevel; + mCurrentGesticulationLevel = mVoiceVisualizer->getCurrentGesticulationLevel(); + + //--------------------------------------------------------------------------------------------------- + // If "current gesticulation level" changes, we catch this, and trigger the new gesture + //--------------------------------------------------------------------------------------------------- + if ( lastGesticulationLevel != mCurrentGesticulationLevel ) { - LLString gestureString = "unInitialized"; - if ( mCurrentGesticulationLevel == 0 ) { gestureString = "/voicelevel1"; } - else if ( mCurrentGesticulationLevel == 1 ) { gestureString = "/voicelevel2"; } - else if ( mCurrentGesticulationLevel == 2 ) { gestureString = "/voicelevel3"; } - else { printf( "oops - CurrentGesticulationLevel can be only 0, 1, or 2\n" ); } - - // this is the call that Karl S. created for triggering gestures from within the code. - gGestureManager.triggerAndReviseString( gestureString ); + if ( mCurrentGesticulationLevel != VOICE_GESTICULATION_LEVEL_OFF ) + { + LLString gestureString = "unInitialized"; + if ( mCurrentGesticulationLevel == 0 ) { gestureString = "/voicelevel1"; } + else if ( mCurrentGesticulationLevel == 1 ) { gestureString = "/voicelevel2"; } + else if ( mCurrentGesticulationLevel == 2 ) { gestureString = "/voicelevel3"; } + else { llinfos << "oops - CurrentGesticulationLevel can be only 0, 1, or 2" << llendl; } + + // this is the call that Karl S. created for triggering gestures from within the code. + gGestureManager.triggerAndReviseString( gestureString ); + } } - } - - } //if( mIsSelf ) - - //----------------------------------------------------------------------------------------------------------------- - // If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer. - // Also, here we trigger voice visualizer start and stop speaking, so it can animate the voice symbol. - // - // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been - // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking. - //----------------------------------------------------------------------------------------------------------------- - if ( gVoiceClient->getIsSpeaking( mID ) ) - { - if ( ! mVoiceVisualizer->getCurrentlySpeaking() ) - { - mVoiceVisualizer->setStartSpeaking(); - //printf( "gAwayTimer.reset();\n" ); - } + } //if( mIsSelf ) + + //----------------------------------------------------------------------------------------------------------------- + // If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer. + // Also, here we trigger voice visualizer start and stop speaking, so it can animate the voice symbol. + // + // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been + // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking. + //----------------------------------------------------------------------------------------------------------------- + if ( gVoiceClient->getIsSpeaking( mID ) ) + { + if ( ! mVoiceVisualizer->getCurrentlySpeaking() ) + { + mVoiceVisualizer->setStartSpeaking(); + + //printf( "gAwayTimer.reset();\n" ); + } - mVoiceVisualizer->setSpeakingAmplitude( gVoiceClient->getCurrentPower( mID ) ); + mVoiceVisualizer->setSpeakingAmplitude( gVoiceClient->getCurrentPower( mID ) ); - if( mIsSelf ) - { - gAgent.clearAFK(); + if( mIsSelf ) + { + gAgent.clearAFK(); + } } - } - else - { - if ( mVoiceVisualizer->getCurrentlySpeaking() ) + else { - mVoiceVisualizer->setStopSpeaking(); + if ( mVoiceVisualizer->getCurrentlySpeaking() ) + { + mVoiceVisualizer->setStopSpeaking(); + } } - } - //-------------------------------------------------------------------------------------------- - // here we get the approximate head position and set as sound source for the voice symbol - // (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing) - //-------------------------------------------------------------------------------------------- - LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] ); - mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset ); + //-------------------------------------------------------------------------------------------- + // here we get the approximate head position and set as sound source for the voice symbol + // (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing) + //-------------------------------------------------------------------------------------------- + LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] ); + mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset ); - }//if ( voiceEnabled ) + }//if ( voiceEnabled ) + } //End Ventrella - if (LLVOAvatar::sJointDebug) { @@ -2432,17 +2550,22 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_SHADOW, TRUE); } + BOOL visible = isVisible() || mNeedsAnimUpdate; + // update attachments positions + if (detailed_update || !sUseImpostors) { LLFastTimer t(LLFastTimer::FTM_ATTACHMENT_UPDATE); - for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; LLViewerObject *attached_object = attachment->getObject(); - BOOL visibleAttachment = isVisible() || !(attached_object && attached_object->mDrawable->getSpatialBridge() - && (attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0)); + BOOL visibleAttachment = visible || (attached_object && + !(attached_object->mDrawable->getSpatialBridge() && + attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0)); if (visibleAttachment && attached_object && !attached_object->isDead() && attachment->getValid()) { @@ -2455,10 +2578,61 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { gPipeline.updateMoveDampedAsync(attached_object->mDrawable); } - attached_object->updateText(); + + LLSpatialBridge* bridge = attached_object->mDrawable->getSpatialBridge(); + if (bridge) + { + gPipeline.updateMoveNormalAsync(bridge); + } + attached_object->updateText(); } } } + + mNeedsAnimUpdate = FALSE; + + if (isImpostor() && !mNeedsImpostorUpdate) + { + LLVector3 ext[2]; + F32 distance; + LLVector3 angle; + + getImpostorValues(ext, angle, distance); + + for (U32 i = 0; i < 3 && !mNeedsImpostorUpdate; i++) + { + F32 cur_angle = angle.mV[i]; + F32 old_angle = mImpostorAngle.mV[i]; + F32 angle_diff = fabsf(cur_angle-old_angle); + + if (angle_diff > 3.14159f/16.f) + { + mNeedsImpostorUpdate = TRUE; + } + } + + if (detailed_update && !mNeedsImpostorUpdate) + { //update impostor if view angle, distance, or bounding box change + //significantly + + F32 dist_diff = fabsf(distance-mImpostorDistance); + if (dist_diff/mImpostorDistance > 0.1f) + { + mNeedsImpostorUpdate = TRUE; + } + else + { + getSpatialExtents(ext[0], ext[1]); + if ((ext[1]-mImpostorExtents[1]).magVec() > 0.05f || + (ext[0]-mImpostorExtents[0]).magVec() > 0.05f) + { + mNeedsImpostorUpdate = TRUE; + } + } + } + } + + mDrawable->movePartition(); //force a move if sitting on an active object if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) @@ -2598,7 +2772,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) const F32 FADE_DURATION = gSavedSettings.getF32("RenderNameFadeDuration"); // seconds BOOL visible_chat = gSavedSettings.getBOOL("UseChatBubbles") && (mChats.size() || mTyping); BOOL render_name = visible_chat || - (isVisible() && + (visible && ((sRenderName == RENDER_NAME_ALWAYS) || (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME))); // If it's your own avatar, don't draw in mouselook, and don't @@ -2981,10 +3155,9 @@ void LLVOAvatar::slamPosition() // updateCharacter() // called on both your avatar and other avatars //------------------------------------------------------------------------ -void LLVOAvatar::updateCharacter(LLAgent &agent) +BOOL LLVOAvatar::updateCharacter(LLAgent &agent) { LLMemType mt(LLMemType::MTYPE_AVATAR); - // update screen joint size if (mScreenp) { @@ -3030,7 +3203,7 @@ void LLVOAvatar::updateCharacter(LLAgent &agent) { gAgent.setPositionAgent(getPositionAgent()); } - return; + return FALSE; } @@ -3038,19 +3211,51 @@ void LLVOAvatar::updateCharacter(LLAgent &agent) if (!mIsBuilt) { - return; + return FALSE; } + BOOL visible = isVisible(); + // For fading out the names above heads, only let the timer // run if we're visible. - if (mDrawable.notNull() && !mDrawable->isVisible()) + if (mDrawable.notNull() && !visible) { mTimeVisible.reset(); } - if (!mIsSelf && !isVisible()) + + //-------------------------------------------------------------------- + // the rest should only be done occasionally for far away avatars + //-------------------------------------------------------------------- + + if (!mIsSelf && sUseImpostors && !mNeedsAnimUpdate) { - return; + F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f); + if (visible && mPixelArea <= impostor_area) + { + mUpdatePeriod = llclamp((S32) sqrtf(impostor_area*4.f/mPixelArea), 2, 8); + + visible = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0 ? TRUE : FALSE; + } + else + { + mUpdatePeriod = 1; + } + + if (!visible) + { + if (!mMotionController.isPaused()) + { + mMotionController.pause(); + mMotionController.updateMotion(); + mMotionController.unpause(); + } + else + { + mMotionController.updateMotion(); + } + return FALSE; + } } // change animation time quanta based on avatar render load @@ -3321,27 +3526,6 @@ void LLVOAvatar::updateCharacter(LLAgent &agent) mRoot.setRotation(mDrawable->getRotation()); } - //-------------------------------------------------------------------- - // the rest should only be done when close enough to see it - //-------------------------------------------------------------------- - - - if (mPixelArea > 12.0f) - throttle = FALSE; - if (mPixelArea < 400.0f) - { - throttle = (LLDrawable::getCurrentFrame()+mID.mData[0])%2 != 0; - } - - if ( !(mIsSitting && getParent()) && - (throttle || - (!isVisible() && (mPixelArea < MIN_PIXEL_AREA_FOR_COMPOSITE))) ) - { - mRoot.setWorldRotation( getRotation() ); - mRoot.updateWorldMatrixChildren(); - return; - } - //------------------------------------------------------------------------- // Update character motions //------------------------------------------------------------------------- @@ -3479,6 +3663,11 @@ void LLVOAvatar::updateCharacter(LLAgent &agent) { setDebugText(mDebugText); } + + //mesh vertices need to be reskinned + mNeedsSkin = TRUE; + + return TRUE; } //----------------------------------------------------------------------------- @@ -3509,7 +3698,7 @@ void LLVOAvatar::updateHeadOffset() //------------------------------------------------------------------------ // updateVisibility() //------------------------------------------------------------------------ -void LLVOAvatar::updateVisibility(BOOL force_invisible) +void LLVOAvatar::updateVisibility() { BOOL visible = FALSE; @@ -3521,7 +3710,7 @@ void LLVOAvatar::updateVisibility(BOOL force_invisible) { visible = FALSE; } - else if (!force_invisible) + else { // calculate avatar distance wrt head mDrawable->updateDistance(*gCamera); @@ -3593,10 +3782,11 @@ void LLVOAvatar::updateVisibility(BOOL force_invisible) llinfos << "PA: " << getPositionAgent() << llendl; /*llinfos << "SPA: " << sel_pos_agent << llendl; llinfos << "WPA: " << wrist_right_pos_agent << llendl;*/ - for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; if (attachment->getObject()) { if(attachment->getObject()->mDrawable->isVisible()) @@ -3643,48 +3833,6 @@ void LLVOAvatar::updateVisibility(BOOL force_invisible) } //------------------------------------------------------------------------ -// updateAllVisibility() -//------------------------------------------------------------------------ -//static -void LLVOAvatar::updateAllAvatarVisiblity() -{ - LLVOAvatar::sNumVisibleAvatars = 0; - - F32 render_priority = (F32)LLVOAvatar::sMaxVisible; - for (std::vector::iterator iter = LLCharacter::sInstances.begin(); - iter != LLCharacter::sInstances.end(); ++iter) - { - LLVOAvatar* avatarp = (LLVOAvatar*) *iter; - if (avatarp->isDead()) - { - continue; - } - if (avatarp->isSelf()) - { - avatarp->mRenderPriority = 1000.f; - } - else - { - avatarp->mRenderPriority = render_priority * 10.f; // 500 -> 10 - if (render_priority > 0.f) - { - render_priority -= 1.f; - } - } - avatarp->updateVisibility(LLVOAvatar::sNumVisibleAvatars > LLVOAvatar::sMaxVisible); - - if (avatarp->mDrawable.isNull()) - { - llwarns << "Avatar with no drawable" << llendl; - } - else if (avatarp->mDrawable->isVisible()) - { - LLVOAvatar::sNumVisibleAvatars++; - } - } -} - -//------------------------------------------------------------------------ // needsRenderBeam() //------------------------------------------------------------------------ BOOL LLVOAvatar::needsRenderBeam() @@ -3717,6 +3865,47 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) return num_indices; } + if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) + { //LOD changed or new mesh created, allocate new vertex buffer if needed + updateMeshData(); + mDirtyMesh = FALSE; + mNeedsSkin = TRUE; + mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); + } + + if (LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR) <= 0) + { + if (mNeedsSkin) + { + //generate animated mesh + mLowerBodyLOD.updateGeometry(); + mUpperBodyLOD.updateGeometry(); + + if( isWearingWearableType( WT_SKIRT ) ) + { + mSkirtLOD.updateGeometry(); + } + + if (!mIsSelf || gAgent.needsRenderHead()) + { + mEyeLashLOD.updateGeometry(); + mHeadLOD.updateGeometry(); + mHairLOD.updateGeometry(); + } + mNeedsSkin = FALSE; + + LLVertexBuffer* vb = mDrawable->getFace(0)->mVertexBuffer; + if (vb) + { + vb->setBuffer(0); + } + } + } + else + { + mNeedsSkin = FALSE; + } + if (sDebugInvisible) { LLNameValue* firstname = getNVPair("FirstName"); @@ -3761,27 +3950,27 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) LLVector3 collide_point = slaved_pos; collide_point.mV[VZ] -= foot_plane_normal.mV[VZ] * (dist_from_plane + COLLISION_TOLERANCE - FOOT_COLLIDE_FUDGE); - glBegin(GL_LINES); + gGL.begin(GL_LINES); { F32 SQUARE_SIZE = 0.2f; - glColor4f(1.f, 0.f, 0.f, 1.f); + gGL.color4f(1.f, 0.f, 0.f, 1.f); - glVertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - glVertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); + gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); + gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - glVertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - glVertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); + gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); + gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); - glVertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); - glVertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); + gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); + gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); - glVertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); - glVertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); + gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); + gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - glVertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]); - glVertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]); + gGL.vertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]); + gGL.vertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]); - }glEnd(); + }gGL.end(); } //-------------------------------------------------------------------- // render all geomety attached to the skeleton @@ -3807,41 +3996,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) num_indices += renderTransparent(); } } - /*else if (pass == AVATAR_RENDER_PASS_CLOTHING_INNER) - { - if (!mIsSelf || gAgent.needsRenderHead()) - { - num_indices += mHeadLOD.render(mAdjustedPixelArea); - } - LLViewerJointMesh::sClothingInnerColor = mTexSkinColor->getColor() * 0.5f; - LLViewerJointMesh::sClothingMaskImageName = mUpperMaskTexName; - num_indices += mUpperBodyLOD.render(mAdjustedPixelArea); - LLViewerJointMesh::sClothingMaskImageName = mLowerMaskTexName; - num_indices += mLowerBodyLOD.render(mAdjustedPixelArea); - LLViewerJointMesh::sClothingMaskImageName = 0; - if( isWearingWearableType( WT_SKIRT ) ) - { - glAlphaFunc(GL_GREATER,0.25f); - num_indices += mSkirtLOD.render(mAdjustedPixelArea); - glAlphaFunc(GL_GREATER,0.01f); - } - - if (!mIsSelf || gAgent.needsRenderHead()) - { - num_indices += mEyeLashLOD.render(mAdjustedPixelArea); - num_indices += mHairLOD.render(mAdjustedPixelArea); - } - } - else if (pass == AVATAR_RENDER_PASS_CLOTHING_OUTER) - { - LLViewerJointMesh::sClothingInnerColor = mTexSkinColor->getColor() * 0.5f; - LLViewerJointMesh::sClothingMaskImageName = mUpperMaskTexName; - num_indices += mUpperBodyLOD.render(mAdjustedPixelArea); - LLViewerJointMesh::sClothingMaskImageName = mLowerMaskTexName; - num_indices += mLowerBodyLOD.render(mAdjustedPixelArea); - LLViewerJointMesh::sClothingMaskImageName = 0; - }*/ - + LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE; //llinfos << "Avatar render: " << render_timer.getElapsedTimeF32() << llendl; @@ -3865,8 +4020,16 @@ U32 LLVOAvatar::renderTransparent() if (!mIsSelf || gAgent.needsRenderHead()) { + if (LLPipeline::sImpostorRender) + { + glAlphaFunc(GL_GREATER, 0.5f); + } num_indices += mEyeLashLOD.render(mAdjustedPixelArea, first_pass); num_indices += mHairLOD.render(mAdjustedPixelArea, FALSE); + if (LLPipeline::sImpostorRender) + { + glAlphaFunc(GL_GREATER, 0.01f); + } } return num_indices; @@ -3919,9 +4082,17 @@ U32 LLVOAvatar::renderFootShadows() return 0; } + // Update the shadow, tractor, and text label geometry. + if (mDrawable->isState(LLDrawable::REBUILD_SHADOW) && !isImpostor()) + { + updateShadowFaces(); + mDrawable->clearState(LLDrawable::REBUILD_SHADOW); + } + U32 foot_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD; + LLGLDepthTest test(GL_TRUE, GL_FALSE); //render foot shadows LLGLEnable blend(GL_BLEND); mShadowImagep->bind(); @@ -3933,6 +4104,38 @@ U32 LLVOAvatar::renderFootShadows() return num_indices; } +U32 LLVOAvatar::renderImpostor(LLColor4U color) +{ + if (!mImpostor.isComplete()) + { + return 0; + } + + LLVector3 pos(getRenderPosition()+mImpostorOffset); + LLVector3 left = gCamera->getLeftAxis()*mImpostorDim.mV[0]; + LLVector3 up = gCamera->getUpAxis()*mImpostorDim.mV[1]; + + LLGLEnable test(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.f); + + gGL.start(); + gGL.color4ubv(color.mV); + mImpostor.bindTexture(); + gGL.begin(GL_QUADS); + gGL.texCoord2f(0,0); + gGL.vertex3fv((pos+left-up).mV); + gGL.texCoord2f(1,0); + gGL.vertex3fv((pos-left-up).mV); + gGL.texCoord2f(1,1); + gGL.vertex3fv((pos-left+up).mV); + gGL.texCoord2f(0,1); + gGL.vertex3fv((pos+left+up).mV); + gGL.end(); + gGL.stop(); + + return 6; +} + //----------------------------------------------------------------------------- // renderCollisionVolumes() //----------------------------------------------------------------------------- @@ -3949,7 +4152,6 @@ void LLVOAvatar::renderCollisionVolumes() //------------------------------------------------------------------------ void LLVOAvatar::updateTextures(LLAgent &agent) { -// LLFastTimer ftm(LLFastTimer::FTM_TEMP5); BOOL render_avatar = TRUE; if (mIsDummy || gNoRender) @@ -5103,7 +5305,7 @@ BOOL LLVOAvatar::loadSkeletonNode () delete attachment; continue; } - if (mAttachmentPoints.checkData(attachmentID)) + if (mAttachmentPoints.find(attachmentID) != mAttachmentPoints.end()) { llwarns << "Attachment point redefined with id " << attachmentID << " on attachment point " << info->mName << llendl; delete attachment; @@ -5407,38 +5609,23 @@ BOOL LLVOAvatar::isActive() const void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) { LLMemType mt(LLMemType::MTYPE_AVATAR); - - F32 max_scale = getMaxScale(); - F32 mid_scale = getMidScale(); - F32 min_scale = llmin( getScale().mV[VX], llmin( getScale().mV[VY], getScale().mV[VZ] ) ); - // IW: esitmate - when close to large objects, computing range based on distance from center is no good - // to try to get a min distance from face, subtract min_scale/2 from the range. - // This means we'll load too much detail sometimes, but that's better than not enough - // I don't think there's a better way to do this without calculating distance per-poly - F32 range = (getRenderPosition()-gCamera->getOrigin()).magVec() - min_scale/2; + const LLVector3* ext = mDrawable->getSpatialExtents(); + LLVector3 center = (ext[1] + ext[0]) * 0.5f; + LLVector3 size = (ext[1]-ext[0])*0.5f; + + mPixelArea = LLPipeline::calcPixelArea(center, size, *gCamera); + + F32 range = mDrawable->mDistanceWRTCamera; if (range < 0.001f) // range == zero { mAppAngle = 180.f; - mPixelArea = gCamera->getViewHeightInPixels() * - gCamera->getViewHeightInPixels() * - gCamera->getAspect(); } else { - mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG; - - F32 pixels_per_meter = gCamera->getPixelMeterRatio() / range; - - mPixelArea = (pixels_per_meter * max_scale) * (pixels_per_meter * mid_scale); -// if( !mIsSelf ) -// { -// llinfos << "range " << range << llendl; -// llinfos << "pixels_per_meter " << pixels_per_meter << llendl; -// llinfos << "scale " << max_scale << "x" << mid_scale << llendl; -// llinfos << "pixel area " << mPixelArea << llendl; -// } + F32 radius = size.magVec(); + mAppAngle = (F32) atan2( radius, range) * RAD_TO_DEG; } // We always want to look good to ourselves @@ -5551,10 +5738,11 @@ void LLVOAvatar::updateShadowFaces() { LLFace *face0p = mShadow0Facep; LLFace *face1p = mShadow1Facep; + // // render avatar shadows // - if (mInAir) + if (mInAir || mUpdatePeriod >= VOAVATAR_IMPOSTOR_PERIOD) { face0p->setSize(0, 0); face1p->setSize(0, 0); @@ -5567,7 +5755,7 @@ void LLVOAvatar::updateShadowFaces() F32 cos_elev = sqrt(1 - cos_angle * cos_angle); if (cos_angle < 0) cos_elev = -cos_elev; sprite.setSize(0.4f + cos_elev * 0.8f, 0.3f); - LLVector3 sun_vec = gSky.mVOSkyp->getToSun(); + LLVector3 sun_vec = gSky.mVOSkyp ? gSky.mVOSkyp->getToSun() : LLVector3(0.f, 0.f, 0.f); if (mShadowImagep->getHasGLTexture()) { @@ -5755,7 +5943,14 @@ void LLVOAvatar::setParent(LLViewerObject* parent) void LLVOAvatar::addChild(LLViewerObject *childp) { LLViewerObject::addChild(childp); - attachObject(childp); + if (childp->mDrawable) + { + attachObject(childp); + } + else + { + mPendingAttachment.push_back(childp); + } } void LLVOAvatar::removeChild(LLViewerObject *childp) @@ -5768,7 +5963,7 @@ LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* vi { S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getState()); - LLViewerJointAttachment* attachment = mAttachmentPoints.getIfThere(attachmentID); + LLViewerJointAttachment* attachment = get_if_there(mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL); if (!attachment) { @@ -5813,27 +6008,24 @@ BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object) //----------------------------------------------------------------------------- void LLVOAvatar::lazyAttach() { - for(LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + for (U32 i = 0; i < mPendingAttachment.size(); i++) + { + if (mPendingAttachment[i]->mDrawable) { - if (attachment->getAttachmentDirty()) - { - attachment->lazyAttach(); - if (mIsSelf) - { - updateAttachmentVisibility(gAgent.getCameraMode()); - } - } + attachObject(mPendingAttachment[i]); } + } + + mPendingAttachment.clear(); } void LLVOAvatar::resetHUDAttachments() { - for(LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; if (attachment->getIsHUDAttachment()) { LLViewerObject* obj = attachment->getObject(); @@ -5850,10 +6042,11 @@ void LLVOAvatar::resetHUDAttachments() //----------------------------------------------------------------------------- BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) { - for(LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; // only one object per attachment point for now if (attachment->getObject() == viewer_object) { @@ -5862,7 +6055,7 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) if (mIsSelf) { // the simulator should automatically handle - // permissiosn revokation + // permission revocation stopMotionFromSource(viewer_object->getID()); LLFollowCamMgr::setCameraActive(viewer_object->getID(), FALSE); @@ -5871,7 +6064,7 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) { LLViewerObject* child_objectp = viewer_object->mChildList[i]; // the simulator should automatically handle - // permissions revokation + // permissions revocation stopMotionFromSource(child_objectp->getID()); LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE); @@ -6025,11 +6218,12 @@ LLVOAvatar* LLVOAvatar::findAvatarFromAttachment( LLViewerObject* obj ) //----------------------------------------------------------------------------- BOOL LLVOAvatar::isWearingAttachment( const LLUUID& inv_item_id ) { - for (LLViewerJointAttachment *attachment_point = mAttachmentPoints.getFirstData(); - attachment_point; - attachment_point = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { - if( attachment_point->getItemID() == inv_item_id ) + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if( attachment->getItemID() == inv_item_id ) { return TRUE; } @@ -6042,13 +6236,14 @@ BOOL LLVOAvatar::isWearingAttachment( const LLUUID& inv_item_id ) //----------------------------------------------------------------------------- LLViewerObject* LLVOAvatar::getWornAttachment( const LLUUID& inv_item_id ) { - for (LLViewerJointAttachment *attachment_point = mAttachmentPoints.getFirstData(); - attachment_point; - attachment_point = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { - if( attachment_point->getItemID() == inv_item_id ) + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if( attachment->getItemID() == inv_item_id ) { - return attachment_point->getObject(); + return attachment->getObject(); } } return NULL; @@ -6056,13 +6251,14 @@ LLViewerObject* LLVOAvatar::getWornAttachment( const LLUUID& inv_item_id ) const LLString LLVOAvatar::getAttachedPointName(const LLUUID& inv_item_id) { - for (LLViewerJointAttachment *attachment_point = mAttachmentPoints.getFirstData(); - attachment_point; - attachment_point = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { - if( attachment_point->getItemID() == inv_item_id ) + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if( attachment->getItemID() == inv_item_id ) { - return (LLString)attachment_point->getName(); + return (LLString)attachment->getName(); } } @@ -7617,30 +7813,31 @@ void LLVOAvatar::dumpAvatarTEs( const char* context ) //----------------------------------------------------------------------------- void LLVOAvatar::updateAttachmentVisibility(U32 camera_mode) { - for (LLViewerJointAttachment *attachmentPoint = mAttachmentPoints.getFirstData(); - attachmentPoint; - attachmentPoint = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { - if (attachmentPoint->getIsHUDAttachment()) + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if (attachment->getIsHUDAttachment()) { - attachmentPoint->setAttachmentVisibility(TRUE); + attachment->setAttachmentVisibility(TRUE); } else { switch (camera_mode) { case CAMERA_MODE_MOUSELOOK: - if (LLVOAvatar::sVisibleInFirstPerson && attachmentPoint->getVisibleInFirstPerson()) + if (LLVOAvatar::sVisibleInFirstPerson && attachment->getVisibleInFirstPerson()) { - attachmentPoint->setAttachmentVisibility(TRUE); + attachment->setAttachmentVisibility(TRUE); } else { - attachmentPoint->setAttachmentVisibility(FALSE); + attachment->setAttachmentVisibility(FALSE); } break; default: - attachmentPoint->setAttachmentVisibility(TRUE); + attachment->setAttachmentVisibility(TRUE); break; } } @@ -7789,39 +7986,45 @@ BOOL LLVOAvatar::isWearingWearableType( EWearableType type ) //----------------------------------------------------------------------------- void LLVOAvatar::clampAttachmentPositions() { - if (isDead()) return; - for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + if (isDead()) + { + return; + } + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) + { + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if (attachment) { - if (attachment) - { - attachment->clampObjectPosition(); - } + attachment->clampObjectPosition(); } + } } BOOL LLVOAvatar::hasHUDAttachment() { - for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) + { + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if (attachment->getIsHUDAttachment() && attachment->getObject()) { - if (attachment->getIsHUDAttachment() && attachment->getObject()) - { - return TRUE; - } + return TRUE; } + } return FALSE; } LLBBox LLVOAvatar::getHUDBBox() { LLBBox bbox; - for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); ) { + attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; if (attachment->getIsHUDAttachment() && attachment->getObject()) { LLViewerObject* hud_object = attachment->getObject(); @@ -9130,255 +9333,10 @@ BOOL LLVOAvatarInfo::parseXmlDriverNodes(LLXmlTreeNode* root) return TRUE; } -void LLVOAvatar::writeCAL3D(std::string& path, std::string& file_base) -{ - char filename[MAX_PATH]; /* Flawfinder: ignore */ - - // reset animated morphs - setVisualParamWeight("Blink_Left", 0.f); - setVisualParamWeight("Blink_Right", 0.f); - setVisualParamWeight("Hands_Relaxed", 1.f); - setVisualParamWeight("Hands_Point", 0.f); - setVisualParamWeight("Hands_Fist", 0.f); - setVisualParamWeight("Hands_Relaxed_L", 0.f); - setVisualParamWeight("Hands_Point_L", 0.f); - setVisualParamWeight("Hands_Fist_L", 0.f); - setVisualParamWeight("Hands_Relaxed_R", 0.f); - setVisualParamWeight("Hands_Point_R", 0.f); - setVisualParamWeight("Hands_Fist_R", 0.f); - setVisualParamWeight("Hands_Salute_R", 0.f); - setVisualParamWeight("Hands_Typing", 0.f); - setVisualParamWeight("Hands_Peace_R", 0.f); - setVisualParamWeight("Hands_Spread_R", 0.f); - updateVisualParams(); - - snprintf(filename, MAX_PATH, "%s\\%s_skeleton.xsf", path.c_str(), file_base.c_str()); /* Flawfinder: ignore */ - apr_file_t* fp = ll_apr_file_open(filename, LL_APR_W); - if (!fp) - { - llwarns << "Unable to write avatar file " << filename << llendl; - return; - } - apr_file_printf(fp, "\n", sSkeletonInfo->getNumBones() - sSkeletonInfo->getNumCollisionVolumes()); - mRoot.writeCAL3D(fp); - apr_file_printf(fp, "\n"); - apr_file_close(fp); - - snprintf(filename, MAX_PATH, "%s\\%s_mesh_body.xmf", path.c_str(), file_base.c_str()); /* Flawfinder: ignore */ - //gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"avatar.cal").c_str() - fp = ll_apr_file_open(filename, LL_APR_W); - if (!fp) - { - llwarns << "Unable to write avatar file " << filename << llendl; - return; - } - - BOOL has_skirt = isWearingWearableType(WT_SKIRT); - - apr_file_printf(fp, "\n", has_skirt ? 8 : 7); - mHairMesh0.writeCAL3D(fp, 5, this); - mHeadMesh0.writeCAL3D(fp, 0, this); - mEyeLashMesh0.writeCAL3D(fp, 0, this); - mUpperBodyMesh0.writeCAL3D(fp, 1, this); - mLowerBodyMesh0.writeCAL3D(fp, 2, this); - mEyeBallLeftMesh0.writeCAL3D(fp, 3, this); - mEyeBallRightMesh0.writeCAL3D(fp, 3, this); - if (has_skirt) - { - mSkirtMesh0.writeCAL3D(fp, 4, this); - } - apr_file_printf(fp, "\n"); - apr_file_close(fp); - - // write out material files - LLPointer tga_image = new LLImageTGA; - - for (S32 i = 0; i < (has_skirt ? BAKED_TEXTURE_COUNT : BAKED_TEXTURE_COUNT - 1); i++) - { - snprintf(filename, MAX_PATH, "%s\\%s_material_tex_%d.tga", path.c_str(), file_base.c_str(), i); /* Flawfinder: ignore */ - - LLViewerImage* viewer_imagep = mTEImages[sBakedTextureIndices[i]]; - if (!viewer_imagep->getHasGLTexture()) - { - llinfos << "No image data available for " << filename << llendl; - continue; - } - LLPointer raw_image = new LLImageRaw; - viewer_imagep->readBackRaw(-1, raw_image, false); - BOOL success = tga_image->encode(raw_image); - success = tga_image->save(filename); - } - - // output image for hair - snprintf(filename, MAX_PATH, "%s\\%s_material_tex_5.tga", path.c_str(), file_base.c_str()); /* Flawfinder: ignore */ - LLViewerImage* viewer_imagep = mTEImages[TEX_HAIR]; - if (!viewer_imagep->getHasGLTexture()) - { - llinfos << "No image data available for " << filename << llendl; - } - else - { - LLPointer raw_image = new LLImageRaw; - viewer_imagep->readBackRaw(-1, raw_image, false); - BOOL success = tga_image->encode(raw_image); - success = tga_image->save(filename); - } - - // save out attachments - snprintf(filename, MAX_PATH, "%s\\%s_mesh_attachments.xmf", path.c_str(), file_base.c_str()); /* Flawfinder: ignore */ - fp = ll_apr_file_open(filename, LL_APR_W); - if (!fp) - { - llwarns << "Unable to write attachments file " << filename << llendl; - return; - } - - typedef std::multimap::iterator material_it_t; - std::multimap material_map; - - S32 num_attachment_objects = 0; - for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) - { - LLViewerObject *attached_object = attachment->getObject(); - if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull() && - attached_object->getPCode() == LL_PCODE_VOLUME) - { - num_attachment_objects += attached_object->mDrawable->getNumFaces(); - for (U32 i = 0; i < attached_object->mChildList.size(); i++) - { - LLViewerObject* child_object = attached_object->mChildList[i]; - num_attachment_objects += child_object->mDrawable->getNumFaces(); - } - } - } - - apr_file_printf(fp, "\n", num_attachment_objects); - - S32 material_index = 6; - S32 texture_index = 6; - for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); - attachment; - attachment = mAttachmentPoints.getNextData()) - { - LLViewerObject *attached_object = attachment->getObject(); - if (attached_object && !attached_object->isDead() && attached_object->getPCode() == LL_PCODE_VOLUME) - { - LLVOVolume* attached_volume = (LLVOVolume*)attached_object; - LLVector3 pos = attachment->getPosition(); - LLJoint* cur_joint = attachment->getParent(); - while (cur_joint) - { - pos += cur_joint->getSkinOffset(); - cur_joint = (LLViewerJoint*)cur_joint->getParent(); - } - pos *= 100.f; - S32 attached_joint_num = attachment->getParent()->mJointNum; - LLQuaternion rot = attachment->getRotation(); - attached_volume->writeCAL3D(fp, path, file_base, attached_joint_num, pos, rot, material_index, texture_index, material_map); - } - } - apr_file_printf(fp, "\n"); - apr_file_close(fp); - - // now dump sample animation - LLKeyframeMotion* walk_motion = - getSex() == SEX_MALE ? (LLKeyframeMotion*)findMotion(ANIM_AGENT_WALK) : (LLKeyframeMotion*)findMotion(ANIM_AGENT_FEMALE_WALK); - if (FALSE)//(walk_motion) - { - snprintf(filename, MAX_PATH, "%s\\%s_anim.xaf", path.c_str(), file_base.c_str()); /* Flawfinder: ignore */ - apr_file_t* fp = ll_apr_file_open(filename, LL_APR_W); - if (!fp) - { - llwarns << "Unable to write avatar animation file " << filename << llendl; - return; - } - - walk_motion->writeCAL3D(fp); - - apr_file_close(fp); - } - - // finally, write out .cfg file - snprintf(filename, MAX_PATH, "%s\\%s_avatar.cfg", path.c_str(), file_base.c_str()); /* Flawfinder: ignore */ - fp = ll_apr_file_open(filename, LL_APR_W); - if (!fp) - { - llwarns << "Unable to write avatar config file " << filename << llendl; - return; - } - - // this version exports animation - //apr_file_printf(fp, "#\n# cal3d model configuration file\n#\n# model: %s_avatar\n#\n\nscale=1.0\n\nskeleton=%s_skeleton.xsf\n\nanimation=%s_anim.xaf\n\n", file_base.c_str(), file_base.c_str(), file_base.c_str()); - apr_file_printf(fp, "#\n# cal3d model configuration file\n#\n# model: %s_avatar\n#\n\nscale=1.0\n\nskeleton=%s_skeleton.xsf\n\n", file_base.c_str(), file_base.c_str()); - apr_file_printf(fp, "mesh=%s_mesh_body.xmf\nmesh=%s_mesh_attachments.xmf\n", file_base.c_str(), file_base.c_str()); - - for (S32 i = 0; i < material_index; i++) - { - apr_file_printf(fp, "material=%s_material_%d.xrf\n", file_base.c_str(), i); - } - apr_file_close(fp); - - for(S32 i = 0; i < 6; i++) - { - snprintf(filename, MAX_PATH, "%s\\%s_material_%d.xrf", path.c_str(), file_base.c_str(), i); /* Flawfinder: ignore */ - apr_file_t* fp = ll_apr_file_open(filename, LL_APR_W); - if (!fp) - { - llwarns << "Unable to write material definition file " << filename << llendl; - return; - } - - // for hair material, use hair color...otherwise use white for entire body - LLColor4U material_color = (i == 5) ? mTexHairColor->getColor() : LLColor4U::white; - - apr_file_printf(fp, "
\n\n"); - apr_file_printf(fp, " %d %d %d %d\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]); - apr_file_printf(fp, " %d %d %d %d\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]); - apr_file_printf(fp, " 0 0 0 0\n"); - apr_file_printf(fp, " 1.0\n"); - apr_file_printf(fp, " %s_material_tex_%d.tga\n", file_base.c_str(), i); - apr_file_printf(fp, "\n"); - - apr_file_close(fp); - } - - // write out material files - for(material_it_t material_it = material_map.begin(); material_it != material_map.end(); ++material_it) - { - LLMaterialExportInfo* export_info = material_it->second; - - snprintf(filename, MAX_PATH, "%s\\%s_material_%d.xrf", path.c_str(), file_base.c_str(), export_info->mMaterialIndex); /* Flawfinder: ignore */ - apr_file_t* fp = ll_apr_file_open(filename, LL_APR_W); - if (!fp) - { - llwarns << "Unable to write material definition file " << filename << llendl; - return; - } - - LLColor4U material_color = export_info->mColor; - - apr_file_printf(fp, "
\n\n"); - apr_file_printf(fp, " %d %d %d %d\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]); - apr_file_printf(fp, " %d %d %d %d\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]); - apr_file_printf(fp, " 0 0 0 0\n"); - apr_file_printf(fp, " 1.0\n"); - apr_file_printf(fp, " %s_material_tex_%d.tga\n", file_base.c_str(), export_info->mTextureIndex); - apr_file_printf(fp, "\n"); - - apr_file_close(fp); - } - - - std::for_each(material_map.begin(), material_map.end(), DeletePairedPointer()); - material_map.clear(); -} - // warning: order(N) not order(1) S32 LLVOAvatar::getAttachmentCount() { - S32 count = mAttachmentPoints.getLength(); + S32 count = mAttachmentPoints.size(); return count; } @@ -9492,40 +9450,75 @@ BOOL LLVOAvatar::updateLOD() { //LOD changed or new mesh created, allocate new vertex buffer if needed updateMeshData(); mDirtyMesh = FALSE; + mNeedsSkin = TRUE; mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); } - if (facep->getPool()->getVertexShaderLevel() <= 0) - { - //generate animated mesh - mLowerBodyLOD.updateGeometry(); - mUpperBodyLOD.updateGeometry(); - if( isWearingWearableType( WT_SKIRT ) ) - { - mSkirtLOD.updateGeometry(); - } + return res; +} - if (!mIsSelf || gAgent.needsRenderHead()) +U32 LLVOAvatar::getPartitionType() const +{ //avatars merely exist as drawables in the bridge partition + return LLViewerRegion::PARTITION_BRIDGE; +} + +//static +void LLVOAvatar::updateImpostors() +{ + for (std::vector::iterator iter = LLCharacter::sInstances.begin(); + iter != LLCharacter::sInstances.end(); ++iter) + { + LLVOAvatar* avatar = (LLVOAvatar*) *iter; + + if (!avatar->isDead() && avatar->needsImpostorUpdate() && avatar->isVisible() && avatar->isImpostor()) { - mEyeLashLOD.updateGeometry(); - mHeadLOD.updateGeometry(); - mHairLOD.updateGeometry(); + gPipeline.generateImpostor(avatar); } } +} - // Update the shadow, tractor, and text label geometry. - if (mDrawable->isState(LLDrawable::REBUILD_SHADOW)) - { - updateShadowFaces(); - mDrawable->clearState(LLDrawable::REBUILD_SHADOW); - } +BOOL LLVOAvatar::isImpostor() const +{ + return (sUseImpostors && mUpdatePeriod >= VOAVATAR_IMPOSTOR_PERIOD) ? TRUE : FALSE; +} - return res; + +BOOL LLVOAvatar::needsImpostorUpdate() const +{ + return mNeedsImpostorUpdate; } -U32 LLVOAvatar::getPartitionType() const -{ //avatars merely exist as drawables in the bridge partition - return LLPipeline::PARTITION_BRIDGE; +const LLVector3& LLVOAvatar::getImpostorOffset() const +{ + return mImpostorOffset; +} + +const LLVector2& LLVOAvatar::getImpostorDim() const +{ + return mImpostorDim; +} + +void LLVOAvatar::setImpostorDim(const LLVector2& dim) +{ + mImpostorDim = dim; +} + +void LLVOAvatar::cacheImpostorValues() +{ + getImpostorValues(mImpostorExtents, mImpostorAngle, mImpostorDistance); +} + +void LLVOAvatar::getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) +{ + const LLVector3* ext = mDrawable->getSpatialExtents(); + extents[0] = ext[0]; + extents[1] = ext[1]; + + LLVector3 at = gCamera->getOrigin()-(getRenderPosition()+mImpostorOffset); + distance = at.normVec(); + angle.mV[0] = acosf(at.mV[0]); + angle.mV[1] = acosf(at.mV[1]); + angle.mV[2] = acosf(at.mV[2]); } diff --git a/linden/indra/newview/llvoavatar.h b/linden/indra/newview/llvoavatar.h index a8b8486..2033fda 100644 --- a/linden/indra/newview/llvoavatar.h +++ b/linden/indra/newview/llvoavatar.h @@ -43,7 +43,6 @@ #include "llchat.h" #include "llviewerobject.h" #include "lljointsolverrp3.h" -#include "llviewerjointshape.h" #include "llviewerjointmesh.h" #include "llviewerjointattachment.h" #include "llcharacter.h" @@ -54,6 +53,7 @@ #include "llframetimer.h" #include "llxmltree.h" #include "llwearable.h" +#include "llrendertarget.h" //Ventrella //#include "llvoiceclient.h" @@ -62,6 +62,7 @@ const S32 VOAVATAR_SCRATCH_TEX_WIDTH = 512; const S32 VOAVATAR_SCRATCH_TEX_HEIGHT = 512; +const S32 VOAVATAR_IMPOSTOR_PERIOD = 2; const LLUUID ANIM_AGENT_BODY_NOISE = LLUUID("9aa8b0a6-0c6f-9518-c7c3-4f41f2c001ad"); //"body_noise" const LLUUID ANIM_AGENT_BREATHE_ROT = LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8"); //"breathe_rot" @@ -269,6 +270,8 @@ public: LLVOAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); /*virtual*/ void markDead(); + static void updateImpostors(); + //-------------------------------------------------------------------- // LLViewerObject interface //-------------------------------------------------------------------- @@ -288,6 +291,7 @@ public: // Graphical stuff for objects - maybe broken out into render class later? U32 renderFootShadows(); + U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255)); U32 renderRigid(); U32 renderSkinned(EAvatarRenderPass pass); U32 renderTransparent(); @@ -296,10 +300,10 @@ public: /*virtual*/ void updateTextures(LLAgent &agent); // If setting a baked texture, need to request it from a non-local sim. /*virtual*/ S32 setTETexture(const U8 te, const LLUUID& uuid); - + /*virtual*/ void onShift(const LLVector3& shift_vector); virtual U32 getPartitionType() const; - void updateVisibility(BOOL force_invisible); + void updateVisibility(); void updateAttachmentVisibility(U32 camera_mode); void clampAttachmentPositions(); S32 getAttachmentCount(); // Warning: order(N) not order(1) @@ -309,8 +313,6 @@ public: // void renderHUD(BOOL for_select); // old void rebuildHUD(); - static void updateAllAvatarVisiblity(); - /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); void updateShadowFaces(); @@ -318,13 +320,20 @@ public: /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); BOOL updateJointLODs(); - void writeCAL3D(std::string& path, std::string& file_base); - virtual void updateRegion(LLViewerRegion *regionp); - + virtual const LLVector3 getRenderPosition() const; + virtual void updateDrawable(BOOL force_damped); void updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax); - + void getSpatialExtents(LLVector3& newMin, LLVector3& newMax); + BOOL isImpostor() const; + BOOL needsImpostorUpdate() const; + const LLVector3& getImpostorOffset() const; + const LLVector2& getImpostorDim() const; + void getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance); + void cacheImpostorValues(); + void setImpostorDim(const LLVector2& dim); + //-------------------------------------------------------------------- // texture entry assignment //-------------------------------------------------------------------- @@ -448,7 +457,7 @@ public: void computeBodySize(); - void updateCharacter(LLAgent &agent); + BOOL updateCharacter(LLAgent &agent); void updateHeadOffset(); LLUUID& getStepSound(); @@ -546,8 +555,7 @@ public: static void deleteCachedImages(); static void destroyGL(); static void restoreGL(); - static void initVertexPrograms(); - static void cleanupVertexPrograms(); + static void resetImpostors(); static enum EWearableType getTEWearableType( S32 te ); static LLUUID getDefaultTEImageID( S32 te ); @@ -696,6 +704,19 @@ public: LLUUID mLastSkirtBakedID; //-------------------------------------------------------------------- + // impostor state + //-------------------------------------------------------------------- + LLRenderTarget mImpostor; + LLVector3 mImpostorOffset; + LLVector2 mImpostorDim; + BOOL mNeedsImpostorUpdate; + BOOL mNeedsAnimUpdate; + LLVector3 mImpostorExtents[2]; + LLVector3 mImpostorAngle; + F32 mImpostorDistance; + LLVector3 mLastAnimExtents[2]; + + //-------------------------------------------------------------------- // Misc Render State //-------------------------------------------------------------------- BOOL mIsDummy; // For special views @@ -815,13 +836,14 @@ public: // static members //-------------------------------------------------------------------- static S32 sMaxVisible; + static F32 sRenderDistance; //distance at which avatars will render (affected by control "RenderAvatarMaxVisible") static S32 sCurJoint; static S32 sCurVolume; static BOOL sShowAnimationDebug; // show animation debug info + static BOOL sUseImpostors; //use impostors for far away avatars static BOOL sShowFootPlane; // show foot collision plane reported by server static BOOL sShowCollisionVolumes; // show skeletal collision volumes static BOOL sVisibleInFirstPerson; - static S32 sMaxOtherAvatarsToComposite; static S32 sNumLODChangesThisFrame; @@ -845,16 +867,16 @@ public: static S32 sScratchTexBytes; // map of attachment points, by ID - LLPtrSkipMap mAttachmentPoints; + typedef std::map attachment_map_t; + attachment_map_t mAttachmentPoints; + + std::vector > mPendingAttachment; // xml parse tree of avatar config file static LLXmlTree sXMLTree; // xml parse tree of avatar skeleton file static LLXmlTree sSkeletonXMLTree; - // number of avatar duplicates, for debugging purposes - static BOOL sAvatarLoadTest; - // user-settable LOD factor static F32 sLODFactor; @@ -929,6 +951,9 @@ protected: LLTexGlobalColor* mTexHairColor; LLTexGlobalColor* mTexEyeColor; + BOOL mNeedsSkin; //if TRUE, avatar has been animated and verts have not been updated + S32 mUpdatePeriod; + static LLVOAvatarSkeletonInfo* sSkeletonInfo; static LLVOAvatarInfo* sAvatarInfo; diff --git a/linden/indra/newview/llvoclouds.cpp b/linden/indra/newview/llvoclouds.cpp index 56f7be9..6ca8ac0 100644 --- a/linden/indra/newview/llvoclouds.cpp +++ b/linden/indra/newview/llvoclouds.cpp @@ -49,6 +49,7 @@ #include "llvosky.h" #include "llworld.h" #include "pipeline.h" +#include "llspatialpartition.h" LLUUID gCloudTextureID = IMG_CLOUD_POOF; @@ -78,14 +79,17 @@ BOOL LLVOClouds::isActive() const BOOL LLVOClouds::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS))) + if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS))) + { return TRUE; + } // Set dirty flag (so renderer will rebuild primitive) if (mDrawable) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } + return TRUE; } @@ -113,9 +117,13 @@ LLDrawable* LLVOClouds::createDrawable(LLPipeline *pipeline) BOOL LLVOClouds::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_CLOUDS); - if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS))) + if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS))) + { return TRUE; + } + dirtySpatialGroup(); + LLFace *facep; S32 num_faces = mCloudGroupp->getNumPuffs(); @@ -137,19 +145,16 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable) continue; } - if (isParticle()) - { - facep->setSize(1,1); - } - else - { - facep->setSize(4, 6); - } + facep->setSize(4, 6); + facep->setTEOffset(face_indx); facep->setTexture(getTEImage(0)); const LLCloudPuff &puff = mCloudGroupp->getPuff(face_indx); const LLVector3 puff_pos_agent = gAgent.getPosAgentFromGlobal(puff.getPositionGlobal()); facep->mCenterLocal = puff_pos_agent; + /// Update cloud color based on sun color. + LLColor4 float_color(LLColor3(gSky.getSunDiffuseColor() + gSky.getSunAmbientColor()),puff.getAlpha()); + facep->setFaceColor(float_color); } for ( ; face_indx < drawable->getNumFaces(); face_indx++) { @@ -169,11 +174,6 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable) return TRUE; } -BOOL LLVOClouds::isParticle() -{ - return FALSE; // gGLManager.mHasPointParameters; -} - F32 LLVOClouds::getPartSize(S32 idx) { return (CLOUD_PUFF_HEIGHT+CLOUD_PUFF_WIDTH)*0.5f; @@ -184,7 +184,7 @@ void LLVOClouds::getGeometry(S32 te, LLStrider& normalsp, LLStrider& texcoordsp, LLStrider& colorsp, - LLStrider& indicesp) + LLStrider& indicesp) { if (te >= mCloudGroupp->getNumPuffs()) @@ -204,80 +204,71 @@ void LLVOClouds::getGeometry(S32 te, const LLCloudPuff &puff = mCloudGroupp->getPuff(te); S32 index_offset = facep->getGeomIndex(); - LLColor4U color(255, 255, 255, (U8) (puff.getAlpha()*255)); - facep->setFaceColor(LLColor4(color)); + LLColor4 float_color(LLColor3(gSky.getSunDiffuseColor() + gSky.getSunAmbientColor()),puff.getAlpha()); + LLColor4U color; + color.setVec(float_color); + facep->setFaceColor(float_color); - if (isParticle()) - { - *verticesp++ = facep->mCenterLocal; - *texcoordsp++ = LLVector2(0.5f, 0.5f); - *colorsp++ = color; - *normalsp++ = normal; - *indicesp++ = facep->getGeomIndex(); - } - else - { - LLVector3 up; - LLVector3 right; - LLVector3 at; - - const LLVector3& puff_pos_agent = facep->mCenterLocal; - LLVector2 uvs[4]; - - uvs[0].setVec(0.f, 1.f); - uvs[1].setVec(0.f, 0.f); - uvs[2].setVec(1.f, 1.f); - uvs[3].setVec(1.f, 0.f); - - LLVector3 vtx[4]; - - at = gCamera->getAtAxis(); - right = at % LLVector3(0.f, 0.f, 1.f); - right.normVec(); - up = right % at; - up.normVec(); - right *= 0.5f*CLOUD_PUFF_WIDTH; - up *= 0.5f*CLOUD_PUFF_HEIGHT;; + LLVector3 up; + LLVector3 right; + LLVector3 at; + + const LLVector3& puff_pos_agent = facep->mCenterLocal; + LLVector2 uvs[4]; + + uvs[0].setVec(0.f, 1.f); + uvs[1].setVec(0.f, 0.f); + uvs[2].setVec(1.f, 1.f); + uvs[3].setVec(1.f, 0.f); + + LLVector3 vtx[4]; + + at = gCamera->getAtAxis(); + right = at % LLVector3(0.f, 0.f, 1.f); + right.normVec(); + up = right % at; + up.normVec(); + right *= 0.5f*CLOUD_PUFF_WIDTH; + up *= 0.5f*CLOUD_PUFF_HEIGHT;; - *colorsp++ = color; - *colorsp++ = color; - *colorsp++ = color; - *colorsp++ = color; - - vtx[0] = puff_pos_agent - right + up; - vtx[1] = puff_pos_agent - right - up; - vtx[2] = puff_pos_agent + right + up; - vtx[3] = puff_pos_agent + right - up; - - *verticesp++ = vtx[0]; - *verticesp++ = vtx[1]; - *verticesp++ = vtx[2]; - *verticesp++ = vtx[3]; - - *texcoordsp++ = uvs[0]; - *texcoordsp++ = uvs[1]; - *texcoordsp++ = uvs[2]; - *texcoordsp++ = uvs[3]; - - *normalsp++ = normal; - *normalsp++ = normal; - *normalsp++ = normal; - *normalsp++ = normal; - - *indicesp++ = index_offset + 0; - *indicesp++ = index_offset + 1; - *indicesp++ = index_offset + 2; - - *indicesp++ = index_offset + 1; - *indicesp++ = index_offset + 3; - *indicesp++ = index_offset + 2; - } + *colorsp++ = color; + *colorsp++ = color; + *colorsp++ = color; + *colorsp++ = color; + + vtx[0] = puff_pos_agent - right + up; + vtx[1] = puff_pos_agent - right - up; + vtx[2] = puff_pos_agent + right + up; + vtx[3] = puff_pos_agent + right - up; + + *verticesp++ = vtx[0]; + *verticesp++ = vtx[1]; + *verticesp++ = vtx[2]; + *verticesp++ = vtx[3]; + + *texcoordsp++ = uvs[0]; + *texcoordsp++ = uvs[1]; + *texcoordsp++ = uvs[2]; + *texcoordsp++ = uvs[3]; + + *normalsp++ = normal; + *normalsp++ = normal; + *normalsp++ = normal; + *normalsp++ = normal; + + *indicesp++ = index_offset + 0; + *indicesp++ = index_offset + 1; + *indicesp++ = index_offset + 2; + + *indicesp++ = index_offset + 1; + *indicesp++ = index_offset + 3; + *indicesp++ = index_offset + 2; } U32 LLVOClouds::getPartitionType() const { - return LLPipeline::PARTITION_CLOUD; + return LLViewerRegion::PARTITION_CLOUD; } // virtual @@ -295,6 +286,6 @@ void LLVOClouds::updateDrawable(BOOL force_damped) LLCloudPartition::LLCloudPartition() { mDrawableType = LLPipeline::RENDER_TYPE_CLOUDS; - mPartitionType = LLPipeline::PARTITION_CLOUD; + mPartitionType = LLViewerRegion::PARTITION_CLOUD; } diff --git a/linden/indra/newview/llvoclouds.h b/linden/indra/newview/llvoclouds.h index 71e8c40..670922d 100644 --- a/linden/indra/newview/llvoclouds.h +++ b/linden/indra/newview/llvoclouds.h @@ -59,10 +59,9 @@ public: LLStrider& normalsp, LLStrider& texcoordsp, LLStrider& colorsp, - LLStrider& indicesp); + LLStrider& indicesp); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. - BOOL isParticle(); F32 getPartSize(S32 idx); /*virtual*/ void updateTextures(LLAgent &agent); diff --git a/linden/indra/newview/llvograss.cpp b/linden/indra/newview/llvograss.cpp index 3b6b837..f9b4bc0 100644 --- a/linden/indra/newview/llvograss.cpp +++ b/linden/indra/newview/llvograss.cpp @@ -48,6 +48,7 @@ #include "llviewerimagelist.h" #include "llviewerregion.h" #include "pipeline.h" +#include "llspatialpartition.h" #include "llworld.h" #include "lldir.h" #include "llxmltree.h" @@ -400,6 +401,7 @@ LLDrawable* LLVOGrass::createDrawable(LLPipeline *pipeline) BOOL LLVOGrass::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_GRASS); + dirtySpatialGroup(); plantBlades(); return TRUE; } @@ -439,7 +441,7 @@ void LLVOGrass::getGeometry(S32 idx, LLStrider& normalsp, LLStrider& texcoordsp, LLStrider& colorsp, - LLStrider& indicesp) + LLStrider& indicesp) { mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); if (mPatch) @@ -552,13 +554,13 @@ void LLVOGrass::getGeometry(S32 idx, U32 LLVOGrass::getPartitionType() const { - return LLPipeline::PARTITION_GRASS; + return LLViewerRegion::PARTITION_GRASS; } LLGrassPartition::LLGrassPartition() { mDrawableType = LLPipeline::RENDER_TYPE_GRASS; - mPartitionType = LLPipeline::PARTITION_GRASS; + mPartitionType = LLViewerRegion::PARTITION_GRASS; mLODPeriod = 16; mDepthMask = TRUE; mSlopRatio = 0.1f; diff --git a/linden/indra/newview/llvograss.h b/linden/indra/newview/llvograss.h index 36a0e9f..f5b0c5d 100644 --- a/linden/indra/newview/llvograss.h +++ b/linden/indra/newview/llvograss.h @@ -68,7 +68,7 @@ public: LLStrider& normalsp, LLStrider& texcoordsp, LLStrider& colorsp, - LLStrider& indicesp); + LLStrider& indicesp); void updateFaceSize(S32 idx) { } /*virtual*/ void updateTextures(LLAgent &agent); diff --git a/linden/indra/newview/llvoground.cpp b/linden/indra/newview/llvoground.cpp index ad627e6..a985c44 100644 --- a/linden/indra/newview/llvoground.cpp +++ b/linden/indra/newview/llvoground.cpp @@ -93,7 +93,7 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) LLStrider verticesp; LLStrider normalsp; LLStrider texCoordsp; - LLStrider indicesp; + LLStrider indicesp; S32 index_offset; LLFace *face; @@ -167,6 +167,7 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) *(texCoordsp++) = LLVector2(0.f, 1.f); *(texCoordsp++) = LLVector2(0.5f, 0.5f); + face->mVertexBuffer->setBuffer(0); LLPipeline::sCompiles++; return TRUE; } diff --git a/linden/indra/newview/llvoiceclient.cpp b/linden/indra/newview/llvoiceclient.cpp index 6079447..45935db 100644 --- a/linden/indra/newview/llvoiceclient.cpp +++ b/linden/indra/newview/llvoiceclient.cpp @@ -2286,10 +2286,19 @@ void LLVoiceClient::tuningSetMicVolume(float volume) void LLVoiceClient::tuningSetSpeakerVolume(float volume) { - int scaledVolume = ((int)(volume * 100.0f)) - 100; + // incoming volume has the range [0.0 ... 1.0], with 0.5 as the default. + // Map it as follows: 0.0 -> -100, 0.5 -> 24, 1.0 -> 50 + + volume -= 0.5f; // offset volume to the range [-0.5 ... 0.5], with 0 at the default. + int scaledVolume = 24; // offset scaledVolume by its default level + if(volume < 0.0f) + scaledVolume += ((int)(volume * 248.0f)); // (24 - (-100)) * 2 + else + scaledVolume += ((int)(volume * 52.0f)); // (50 - 24) * 2 + if(scaledVolume != mTuningSpeakerVolume) { - mTuningSpeakerVolume = ((int)(volume * 100.0f)) - 100; + mTuningSpeakerVolume = scaledVolume; mTuningSpeakerVolumeDirty = true; } } @@ -3690,7 +3699,18 @@ void LLVoiceClient::setEarLocation(S32 loc) void LLVoiceClient::setVoiceVolume(F32 volume) { - int scaledVolume = ((int)(volume * 100.0f)) - 100; +// llinfos << "volume is " << volume << llendl; + + // incoming volume has the range [0.0 ... 1.0], with 0.5 as the default. + // Map it as follows: 0.0 -> -100, 0.5 -> 24, 1.0 -> 50 + + volume -= 0.5f; // offset volume to the range [-0.5 ... 0.5], with 0 at the default. + int scaledVolume = 24; // offset scaledVolume by its default level + if(volume < 0.0f) + scaledVolume += ((int)(volume * 248.0f)); // (24 - (-100)) * 2 + else + scaledVolume += ((int)(volume * 52.0f)); // (50 - 24) * 2 + if(scaledVolume != mSpeakerVolume) { if((scaledVolume == -100) || (mSpeakerVolume == -100)) diff --git a/linden/indra/newview/llvoiceremotectrl.cpp b/linden/indra/newview/llvoiceremotectrl.cpp index 099e528..f4adc8f 100644 --- a/linden/indra/newview/llvoiceremotectrl.cpp +++ b/linden/indra/newview/llvoiceremotectrl.cpp @@ -1,5 +1,4 @@ -/** - * @file llvoiceremotectrl.cpp +/* @file llvoiceremotectrl.cpp * @brief A remote control for voice chat * * $LicenseInfo:firstyear=2005&license=viewergpl$ @@ -59,7 +58,7 @@ LLVoiceRemoteCtrl::LLVoiceRemoteCtrl (const LLString& name) : LLPanel(name) gUICtrlFactory->buildPanel(this, "panel_voice_remote.xml"); } - mIsFocusRoot = TRUE; + setFocusRoot(TRUE); } LLVoiceRemoteCtrl::~LLVoiceRemoteCtrl() diff --git a/linden/indra/newview/llvoicevisualizer.cpp b/linden/indra/newview/llvoicevisualizer.cpp index c931734..0046ae0 100644 --- a/linden/indra/newview/llvoicevisualizer.cpp +++ b/linden/indra/newview/llvoicevisualizer.cpp @@ -45,6 +45,7 @@ #include "llviewerimage.h" #include "llviewerimagelist.h" #include "llvoiceclient.h" +#include "llglimmediate.h" //brent's wave image //29de489d-0491-fb00-7dab-f9e686d31e83 @@ -197,7 +198,6 @@ void LLVoiceVisualizer::render() //--------------------------------------------------------------- // some gl state //--------------------------------------------------------------- - LLGLEnable tex( GL_TEXTURE_2D ); LLGLEnable blend( GL_BLEND ); //------------------------------------------------------------- @@ -219,19 +219,19 @@ void LLVoiceVisualizer::render() //------------------------------------------------------------- // now render the dot //------------------------------------------------------------- - glColor4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV ); + gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV ); - glBegin( GL_TRIANGLE_STRIP ); - glTexCoord2i( 0, 0 ); glVertex3fv( bottomLeft.mV ); - glTexCoord2i( 1, 0 ); glVertex3fv( bottomRight.mV ); - glTexCoord2i( 0, 1 ); glVertex3fv( topLeft.mV ); - glEnd(); - - glBegin( GL_TRIANGLE_STRIP ); - glTexCoord2i( 1, 0 ); glVertex3fv( bottomRight.mV ); - glTexCoord2i( 1, 1 ); glVertex3fv( topRight.mV ); - glTexCoord2i( 0, 1 ); glVertex3fv( topLeft.mV ); - glEnd(); + gGL.begin( GL_TRIANGLE_STRIP ); + gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV ); + gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); + gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); + gGL.end(); + + gGL.begin( GL_TRIANGLE_STRIP ); + gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); + gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV ); + gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); + gGL.end(); @@ -338,23 +338,23 @@ void LLVoiceVisualizer::render() LLVector3 topLeft = mSoundSymbol.mPosition + l + u; LLVector3 topRight = mSoundSymbol.mPosition - l + u; - glColor4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV ); + gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV ); mSoundSymbol.mTexture[i]->bind(); //--------------------------------------------------- // now, render the mofo //--------------------------------------------------- - glBegin( GL_TRIANGLE_STRIP ); - glTexCoord2i( 0, 0 ); glVertex3fv( bottomLeft.mV ); - glTexCoord2i( 1, 0 ); glVertex3fv( bottomRight.mV ); - glTexCoord2i( 0, 1 ); glVertex3fv( topLeft.mV ); - glEnd(); - - glBegin( GL_TRIANGLE_STRIP ); - glTexCoord2i( 1, 0 ); glVertex3fv( bottomRight.mV ); - glTexCoord2i( 1, 1 ); glVertex3fv( topRight.mV ); - glTexCoord2i( 0, 1 ); glVertex3fv( topLeft.mV ); - glEnd(); + gGL.begin( GL_TRIANGLE_STRIP ); + gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV ); + gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); + gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); + gGL.end(); + + gGL.begin( GL_TRIANGLE_STRIP ); + gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); + gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV ); + gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); + gGL.end(); } //if ( mSoundSymbol.mWaveActive[i] ) @@ -451,6 +451,7 @@ void LLVoiceVisualizer::markDead() mVoiceEnabled = false; mSoundSymbol.mActive = false; + LLHUDEffect::markDead(); }//------------------------------------------------------------------ diff --git a/linden/indra/newview/llvopartgroup.cpp b/linden/indra/newview/llvopartgroup.cpp index 31ec38e..79255ca 100644 --- a/linden/indra/newview/llvopartgroup.cpp +++ b/linden/indra/newview/llvopartgroup.cpp @@ -47,6 +47,7 @@ #include "llviewerpartsim.h" #include "llviewerregion.h" #include "pipeline.h" +#include "llspatialpartition.h" const F32 MAX_PART_LIFETIME = 120.f; @@ -59,7 +60,6 @@ LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegi setNumTEs(1); setTETexture(0, LLUUID::null); mbCanSelect = FALSE; // users can't select particle systems - mDebugColor = LLColor4(ll_frand(), ll_frand(), ll_frand(), 1.f); } @@ -70,7 +70,7 @@ LLVOPartGroup::~LLVOPartGroup() BOOL LLVOPartGroup::isActive() const { - return TRUE; + return FALSE; } F32 LLVOPartGroup::getBinRadius() @@ -80,11 +80,9 @@ F32 LLVOPartGroup::getBinRadius() void LLVOPartGroup::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax) { - LLVector3 pos_agent = getPositionAgent(); - mExtents[0] = pos_agent - mScale; - mExtents[1] = pos_agent + mScale; - newMin = mExtents[0]; - newMax = mExtents[1]; + const LLVector3& pos_agent = getPositionAgent(); + newMin = pos_agent - mScale; + newMax = pos_agent + mScale; mDrawable->setPositionGroup(pos_agent); } @@ -139,6 +137,8 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_PARTICLES); + dirtySpatialGroup(); + LLVector3 at; LLVector3 position_agent; LLVector3 camera_agent = gCamera->getOrigin(); @@ -156,7 +156,7 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) { if (group && drawable->getNumFaces()) { - group->dirtyGeom(); + group->setState(LLSpatialGroup::GEOM_DIRTY); } drawable->setNumFaces(0, NULL, getTEImage(0)); LLPipeline::sCompiles++; @@ -174,7 +174,6 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) } F32 tot_area = 0; - BOOL is_particle = isParticle(); F32 max_area = LLViewerPartSim::getMaxPartCount() * MAX_PARTICLE_AREA_SCALE; F32 pixel_meter_ratio = gCamera->getPixelMeterRatio(); @@ -182,7 +181,6 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) S32 count=0; S32 i; - F32 max_width = 0.f; mDepth = 0.f; for (i = 0; i < num_parts; i++) @@ -199,9 +197,9 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) else inv_camera_dist_squared = 1.f; F32 area = part.mScale.mV[0] * part.mScale.mV[1] * inv_camera_dist_squared; - tot_area += area; + tot_area = llmax(tot_area, area); - if (!is_particle && tot_area > max_area) + if (tot_area > max_area) { break; } @@ -219,21 +217,14 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) const F32 NEAR_PART_DIST_SQ = 5.f*5.f; // Only discard particles > 5 m from the camera const F32 MIN_PART_AREA = .005f*.005f; // only less than 5 mm x 5 mm at 1 m from camera - if (!is_particle) + if (camera_dist_squared > NEAR_PART_DIST_SQ && area < MIN_PART_AREA) { - if (camera_dist_squared > NEAR_PART_DIST_SQ && area < MIN_PART_AREA) - { - facep->setSize(0, 0); - continue; - } - - facep->setSize(4, 6); - } - else - { - facep->setSize(1,1); + facep->setSize(0, 0); + continue; } + facep->setSize(4, 6); + facep->setViewerObject(this); if (part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK) @@ -248,18 +239,6 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) facep->mCenterLocal = part.mPosAgent; facep->setFaceColor(part.mColor); facep->setTexture(part.mImagep); - - if (i == 0) - { - mExtents[0] = mExtents[1] = part.mPosAgent; - } - else - { - update_min_max(mExtents[0], mExtents[1], part.mPosAgent); - } - - max_width = llmax(max_width, part.mScale.mV[0]); - max_width = llmax(max_width, part.mScale.mV[1]); mPixelArea = tot_area * pixel_meter_ratio; const F32 area_scale = 10.f; // scale area to increase priority a bit @@ -274,21 +253,9 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) continue; } facep->setTEOffset(i); - facep->setSize(0,0); + facep->setSize(0, 0); } - - LLVector3 y = gCamera->mYAxis; - LLVector3 z = gCamera->mZAxis; - LLVector3 pad; - for (i = 0; i < 3; i++) - { - pad.mV[i] = llmax(max_width, max_width * (fabsf(y.mV[i]) + fabsf(z.mV[i]))); - } - - mExtents[0] -= pad; - mExtents[1] += pad; - mDrawable->movePartition(); LLPipeline::sCompiles++; return TRUE; @@ -299,7 +266,7 @@ void LLVOPartGroup::getGeometry(S32 idx, LLStrider& normalsp, LLStrider& texcoordsp, LLStrider& colorsp, - LLStrider& indicesp) + LLStrider& indicesp) { if (idx >= (S32) mViewerPartGroupp->mParticles.size()) { @@ -310,92 +277,72 @@ void LLVOPartGroup::getGeometry(S32 idx, U32 vert_offset = mDrawable->getFace(idx)->getGeomIndex(); - if (isParticle()) - { - LLVector3 part_pos_agent(part.mPosAgent); + + LLVector3 part_pos_agent(part.mPosAgent); + LLVector3 camera_agent = gAgent.getCameraPositionAgent(); + LLVector3 at = part_pos_agent - camera_agent; + LLVector3 up, right; - const LLVector3& normal = -gCamera->getXAxis(); + right = at % LLVector3(0.f, 0.f, 1.f); + right.normVec(); + up = right % at; + up.normVec(); - *verticesp++ = part_pos_agent; - *normalsp++ = normal; - *colorsp++ = part.mColor; - *texcoordsp++ = LLVector2(0.5f, 0.5f); - *indicesp++ = vert_offset; - } - else + if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK) { - LLVector3 part_pos_agent(part.mPosAgent); - LLVector3 camera_agent = gAgent.getCameraPositionAgent(); - LLVector3 at = part_pos_agent - camera_agent; - LLVector3 up, right; - - right = at % LLVector3(0.f, 0.f, 1.f); - right.normVec(); - up = right % at; + LLVector3 normvel = part.mVelocity; + normvel.normVec(); + LLVector2 up_fracs; + up_fracs.mV[0] = normvel*right; + up_fracs.mV[1] = normvel*up; + up_fracs.normVec(); + LLVector3 new_up; + LLVector3 new_right; + new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up; + new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up; + up = new_up; + right = new_right; up.normVec(); + right.normVec(); + } - if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK) - { - LLVector3 normvel = part.mVelocity; - normvel.normVec(); - LLVector2 up_fracs; - up_fracs.mV[0] = normvel*right; - up_fracs.mV[1] = normvel*up; - up_fracs.normVec(); - - LLVector3 new_up; - LLVector3 new_right; - new_up = up_fracs.mV[0] * right + up_fracs.mV[1]*up; - new_right = up_fracs.mV[1] * right - up_fracs.mV[0]*up; - up = new_up; - right = new_right; - up.normVec(); - right.normVec(); - } - - right *= 0.5f*part.mScale.mV[0]; - up *= 0.5f*part.mScale.mV[1]; + right *= 0.5f*part.mScale.mV[0]; + up *= 0.5f*part.mScale.mV[1]; - const LLVector3& normal = -gCamera->getXAxis(); + const LLVector3& normal = -gCamera->getXAxis(); - *verticesp++ = part_pos_agent + up - right; - *verticesp++ = part_pos_agent - up - right; - *verticesp++ = part_pos_agent + up + right; - *verticesp++ = part_pos_agent - up + right; - - *colorsp++ = part.mColor; - *colorsp++ = part.mColor; - *colorsp++ = part.mColor; - *colorsp++ = part.mColor; - - *texcoordsp++ = LLVector2(0.f, 1.f); - *texcoordsp++ = LLVector2(0.f, 0.f); - *texcoordsp++ = LLVector2(1.f, 1.f); - *texcoordsp++ = LLVector2(1.f, 0.f); - - *normalsp++ = normal; - *normalsp++ = normal; - *normalsp++ = normal; - *normalsp++ = normal; - - *indicesp++ = vert_offset + 0; - *indicesp++ = vert_offset + 1; - *indicesp++ = vert_offset + 2; - - *indicesp++ = vert_offset + 1; - *indicesp++ = vert_offset + 3; - *indicesp++ = vert_offset + 2; - } -} - -BOOL LLVOPartGroup::isParticle() -{ - return FALSE; //gGLManager.mHasPointParameters && mViewerPartGroupp->mUniformParticles; + *verticesp++ = part_pos_agent + up - right; + *verticesp++ = part_pos_agent - up - right; + *verticesp++ = part_pos_agent + up + right; + *verticesp++ = part_pos_agent - up + right; + + *colorsp++ = part.mColor; + *colorsp++ = part.mColor; + *colorsp++ = part.mColor; + *colorsp++ = part.mColor; + + *texcoordsp++ = LLVector2(0.f, 1.f); + *texcoordsp++ = LLVector2(0.f, 0.f); + *texcoordsp++ = LLVector2(1.f, 1.f); + *texcoordsp++ = LLVector2(1.f, 0.f); + + *normalsp++ = normal; + *normalsp++ = normal; + *normalsp++ = normal; + *normalsp++ = normal; + + *indicesp++ = vert_offset + 0; + *indicesp++ = vert_offset + 1; + *indicesp++ = vert_offset + 2; + + *indicesp++ = vert_offset + 1; + *indicesp++ = vert_offset + 3; + *indicesp++ = vert_offset + 2; } U32 LLVOPartGroup::getPartitionType() const { - return LLPipeline::PARTITION_PARTICLE; + return LLViewerRegion::PARTITION_PARTICLE; } LLParticlePartition::LLParticlePartition() @@ -403,7 +350,7 @@ LLParticlePartition::LLParticlePartition() { mRenderPass = LLRenderPass::PASS_ALPHA; mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; - mPartitionType = LLPipeline::PARTITION_PARTICLE; + mPartitionType = LLViewerRegion::PARTITION_PARTICLE; mBufferUsage = GL_DYNAMIC_DRAW_ARB; mSlopRatio = 0.f; mLODPeriod = 1; @@ -459,6 +406,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co void LLParticlePartition::getGeometry(LLSpatialGroup* group) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); + LLFastTimer ftm(LLFastTimer::FTM_REBUILD_PARTICLE_VB); std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); @@ -469,7 +417,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) LLVertexBuffer* buffer = group->mVertexBuffer; - LLStrider indicesp; + LLStrider indicesp; LLStrider verticesp; LLStrider normalsp; LLStrider texcoordsp; @@ -503,8 +451,8 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && draw_vec[idx]->mTexture == facep->getTexture() && - draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && - draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && + (U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange && + //draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 && draw_vec[idx]->mFullbright == fullbright) { @@ -524,6 +472,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) } } + buffer->setBuffer(0); mFaceList.clear(); } diff --git a/linden/indra/newview/llvopartgroup.h b/linden/indra/newview/llvopartgroup.h index 183d9a1..5fe6750 100644 --- a/linden/indra/newview/llvopartgroup.h +++ b/linden/indra/newview/llvopartgroup.h @@ -54,7 +54,6 @@ public: /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); - BOOL isParticle(); virtual F32 getBinRadius(); virtual void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); @@ -70,7 +69,7 @@ public: LLStrider& normalsp, LLStrider& texcoordsp, LLStrider& colorsp, - LLStrider& indicesp); + LLStrider& indicesp); void updateFaceSize(S32 idx) { } F32 getPartSize(S32 idx); @@ -81,8 +80,6 @@ protected: ~LLVOPartGroup(); LLViewerPartGroup *mViewerPartGroupp; - LLVector3 mExtents[2]; - LLColor4 mDebugColor; }; #endif // LL_LLVOPARTGROUP_H diff --git a/linden/indra/newview/llvosky.cpp b/linden/indra/newview/llvosky.cpp index ba4b20b..37f6f30 100644 --- a/linden/indra/newview/llvosky.cpp +++ b/linden/indra/newview/llvosky.cpp @@ -53,23 +53,29 @@ #include "llviewerregion.h" #include "llworld.h" #include "pipeline.h" +#include "lldrawpoolwlsky.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" -const S32 NUM_TILES_X = 8; -const S32 NUM_TILES_Y = 4; -const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y; +#undef min +#undef max + +static const S32 NUM_TILES_X = 8; +static const S32 NUM_TILES_Y = 4; +static const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y; // Heavenly body constants -const F32 SUN_DISK_RADIUS = 0.5f; -const F32 MOON_DISK_RADIUS = SUN_DISK_RADIUS * 0.9f; -const F32 SUN_INTENSITY = 1e5; -const F32 SUN_DISK_INTENSITY = 24.f; +static const F32 SUN_DISK_RADIUS = 0.5f; +static const F32 MOON_DISK_RADIUS = SUN_DISK_RADIUS * 0.9f; +static const F32 SUN_INTENSITY = 1e5; +static const F32 SUN_DISK_INTENSITY = 24.f; // Texture coordinates: -const LLVector2 TEX00 = LLVector2(0.f, 0.f); -const LLVector2 TEX01 = LLVector2(0.f, 1.f); -const LLVector2 TEX10 = LLVector2(1.f, 0.f); -const LLVector2 TEX11 = LLVector2(1.f, 1.f); +static const LLVector2 TEX00 = LLVector2(0.f, 0.f); +static const LLVector2 TEX01 = LLVector2(0.f, 1.f); +static const LLVector2 TEX10 = LLVector2(1.f, 0.f); +static const LLVector2 TEX11 = LLVector2(1.f, 1.f); // Exported globals LLUUID gSunTextureID = IMG_SUN; @@ -134,7 +140,7 @@ private: F32 mTable[257]; // index 0 is unused }; -LLFastLn gFastLn; +static LLFastLn gFastLn; // Functions used a lot. @@ -163,42 +169,6 @@ inline LLColor3 color_norm(const LLColor3 &col) else return col; } -inline LLColor3 color_norm_fog(const LLColor3 &col) -{ - const F32 m = color_max(col); - if (m > 0.75f) - { - return 0.75f/m * col; - } - else return col; -} - - -inline LLColor4 color_norm_abs(const LLColor4 &col) -{ - const F32 m = color_max(col); - if (m > 1e-6) - { - return 1.f/m * col; - } - else - { - return col; - } -} - - -inline F32 color_intens ( const LLColor4 &col ) -{ - return col.mV[0] + col.mV[1] + col.mV[2]; -} - - -inline F32 color_avg ( const LLColor3 &col ) -{ - return color_intens(col) / 3.f; -} - inline void color_gamma_correct(LLColor3 &col) { const F32 gamma_inv = 1.f/1.2f; @@ -216,164 +186,6 @@ inline void color_gamma_correct(LLColor3 &col) } } -inline F32 min_intens_factor( LLColor3& col, F32 min_intens, BOOL postmultiply = FALSE); -inline F32 min_intens_factor( LLColor3& col, F32 min_intens, BOOL postmultiply) -{ - const F32 intens = color_intens(col); - F32 factor = 1; - if (0 == intens) - { - return 0; - } - - if (intens < min_intens) - { - factor = min_intens / intens; - if (postmultiply) - col *= factor; - } - return factor; -} - -inline LLVector3 move_vec(const LLVector3& v, const F32 cos_max_angle) -{ - LLVector3 v_norm = v; - v_norm.normVec(); - - LLVector2 v_norm_proj(v_norm.mV[0], v_norm.mV[1]); - const F32 projection2 = v_norm_proj.magVecSquared(); - const F32 scale = sqrt((1 - cos_max_angle * cos_max_angle) / projection2); - return LLVector3(scale * v_norm_proj.mV[0], scale * v_norm_proj.mV[1], cos_max_angle); -} - - -/*************************************** - Transparency Map -***************************************/ - -void LLTranspMap::init(const F32 elev, const F32 step, const F32 h, const LLHaze* const haze) -{ - mHaze = haze; - mAtmHeight = h; - mElevation = elev; - mStep = step; - mStepInv = 1.f / step; - F32 sin_angle = EARTH_RADIUS/(EARTH_RADIUS + mElevation); - mCosMaxAngle = -sqrt(1 - sin_angle * sin_angle); - mMapSize = S32(ceil((1 - mCosMaxAngle) * mStepInv + 1) + 0.5); - delete mT; - mT = new LLColor3[mMapSize]; - - for (S32 i = 0; i < mMapSize; ++i) - { - const F32 cos_a = 1 - i*mStep; - const LLVector3 dir(0, sqrt(1-cos_a*cos_a), cos_a); - mT[i] = calcAirTranspDir(mElevation, dir); - } -} - - - -LLColor3 LLTranspMap::calcAirTranspDir(const F32 elevation, const LLVector3 &dir) const -{ - LLColor3 opt_depth(0, 0, 0); - const LLVector3 point(0, 0, EARTH_RADIUS + elevation); - F32 dist = -dir * point; - LLVector3 cur_point; - S32 s; - - if (dist > 0) - { - cur_point = point + dist * dir; -// const F32 K = log(dist * INV_FIRST_STEP + 1) * INV_NO_STEPS; -// const F32 e_pow_k = LL_FAST_EXP(K); - const F32 e_pow_k = gFastLn.pow( dist * INV_FIRST_STEP + 1, INV_NO_STEPS ); - F32 step = FIRST_STEP * (1 - 1 / e_pow_k); - - for (s = 0; s < NO_STEPS; ++s) - { - const F32 h = cur_point.magVec() - EARTH_RADIUS; - step *= e_pow_k; - opt_depth += calcSigExt(h) * step; - cur_point -= dir * step; - } - opt_depth *= 2; - cur_point = point + 2 * dist * dir; - } - else - { - cur_point = point; - } - - dist = hitsAtmEdge(cur_point, dir); -// const F32 K = log(dist * INV_FIRST_STEP + 1) * INV_NO_STEPS; -// const F32 e_pow_k = LL_FAST_EXP(K); - const F32 e_pow_k = gFastLn.pow( dist * INV_FIRST_STEP + 1, INV_NO_STEPS ); - F32 step = FIRST_STEP * (1 - 1 / e_pow_k); - - for (s = 0; s < NO_STEPS; ++s) - { - const F32 h = cur_point.magVec() - EARTH_RADIUS; - step *= e_pow_k; - opt_depth += calcSigExt(h) * step; - cur_point += dir * step; - } - - opt_depth *= -4.0f*F_PI; - opt_depth.exp(); - return opt_depth; -} - - - -F32 LLTranspMap::hitsAtmEdge(const LLVector3& X, const LLVector3& dir) const -{ - const F32 tca = -dir * X; - const F32 R = EARTH_RADIUS + mAtmHeight; - const F32 thc2 = R * R - X.magVecSquared() + tca * tca; - return tca + sqrt ( thc2 ); -} - - - - - -void LLTranspMapSet::init(const S32 size, const F32 first_step, const F32 media_height, const LLHaze* const haze) -{ - const F32 angle_step = 0.005f; - mSize = size; - mMediaHeight = media_height; - - delete[] mTransp; - mTransp = new LLTranspMap[mSize]; - - delete[] mHeights; - mHeights = new F32[mSize]; - - F32 h = 0; - mHeights[0] = h; - mTransp[0].init(h, angle_step, mMediaHeight, haze); - const F32 K = log(mMediaHeight / first_step + 1) / (mSize - 1); - const F32 e_pow_k = exp(K); - F32 step = first_step * (e_pow_k - 1); - - for (S32 s = 1; s < mSize; ++s) - { - h += step; - mHeights[s] = h; - mTransp[s].init(h, angle_step, mMediaHeight, haze); - step *= e_pow_k; - } -} - -LLTranspMapSet::~LLTranspMapSet() -{ - delete[] mTransp; - mTransp = NULL; - delete[] mHeights; - mHeights = NULL; -} - /*************************************** @@ -392,7 +204,7 @@ LLSkyTex::LLSkyTex() void LLSkyTex::init() { - mSkyData = new LLColor3[sResolution * sResolution]; + mSkyData = new LLColor4[sResolution * sResolution]; mSkyDirs = new LLVector3[sResolution * sResolution]; for (S32 i = 0; i < 2; ++i) @@ -451,9 +263,9 @@ void LLSkyTex::initEmpty(const S32 tex) createGLImage(tex); } - -void LLSkyTex::create(const F32 brightness_scale, const LLColor3& multiscatt) +void LLSkyTex::create(const F32 brightness) { + /// Brightness ignored for now. U8* data = mImageRaw[sCurrent]->getData(); for (S32 i = 0; i < sResolution; ++i) { @@ -461,23 +273,17 @@ void LLSkyTex::create(const F32 brightness_scale, const LLColor3& multiscatt) { const S32 basic_offset = (i * sResolution + j); S32 offset = basic_offset * sComponents; - LLColor3 col(mSkyData[basic_offset]); - if (getDir(i, j).mV[VZ] >= -0.02f) { - col += 0.1f * multiscatt; - col *= brightness_scale; - col.clamp(); - color_gamma_correct(col); - } - U32* pix = (U32*)(data + offset); - LLColor4 temp = LLColor4(col, 0); - LLColor4U temp1 = LLColor4U(temp); - *pix = temp1.mAll; + LLColor4U temp = LLColor4U(mSkyData[basic_offset]); + *pix = temp.mAll; } } createGLImage(sCurrent); } + + + void LLSkyTex::createGLImage(S32 which) { mImageGL[which]->createGLTexture(0, mImageRaw[which]); @@ -495,8 +301,6 @@ void LLSkyTex::bindTexture(BOOL curr) F32 LLHeavenBody::sInterpVal = 0; -F32 LLVOSky::sNighttimeBrightness = 1.5f; - S32 LLVOSky::sResolution = LLSkyTex::getResolution(); S32 LLVOSky::sTileResX = sResolution/NUM_TILES_X; S32 LLVOSky::sTileResY = sResolution/NUM_TILES_Y; @@ -511,8 +315,32 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) mCloudDensity(0.2f), mWind(0.f), mForceUpdate(FALSE), - mWorldScale(1.f) + mWorldScale(1.f), + mBumpSunDir(0.f, 0.f, 1.f) { + bool error = false; + + /// WL PARAMS + dome_radius = 1.f; + dome_offset_ratio = 0.f; + sunlight_color = LLColor3(); + ambient = LLColor3(); + gamma = 1.f; + lightnorm = LLVector4(); + blue_density = LLColor3(); + blue_horizon = LLColor3(); + haze_density = 0.f; + haze_horizon = LLColor3(); + density_multiplier = 0.f; + max_y = 0.f; + glow = LLColor3(); + cloud_shadow = 0.f; + cloud_color = LLColor3(); + cloud_scale = 0.f; + cloud_pos_density1 = LLColor3(); + cloud_pos_density2 = LLColor3(); + + mInitialized = FALSE; mbCanSelect = FALSE; mUpdateTimer.reset(); @@ -520,6 +348,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) for (S32 i = 0; i < 6; i++) { mSkyTex[i].init(); + mShinyTex[i].init(); } for (S32 i=0; imCurParams.getVector("lightnorm", error)); if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition")) { initSunDirection(mSunDefaultPosition, LLVector3(0, 0, 0)); @@ -551,6 +379,8 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) mMoonTexturep->setClamp(TRUE, TRUE); mBloomTexturep = gImageList.getImage(IMG_BLOOM1); mBloomTexturep->setClamp(TRUE, TRUE); + + mHeavenlyBodyUpdated = FALSE ; } @@ -570,14 +400,11 @@ void LLVOSky::initClass() void LLVOSky::init() { - // index of refraction calculation. - mTransp.init(NO_STEPS+1+4, FIRST_STEP, mAtmHeight, &mHaze); - - const F32 haze_int = color_intens(mHaze.calcSigSca(0)); + const F32 haze_int = color_intens(mHaze.calcSigSca(0)); mHazeConcentration = haze_int / (color_intens(LLHaze::calcAirSca(0)) + haze_int); - mBrightnessScaleNew = 0; + calcAtmospherics(); // Initialize the cached normalized direction vectors for (S32 side = 0; side < 6; ++side) @@ -589,8 +416,16 @@ void LLVOSky::init() } } - calcBrightnessScaleAndColors(); + for (S32 i = 0; i < 6; ++i) + { + mSkyTex[i].create(1.0f); + mShinyTex[i].create(1.0f); + } + initCubeMap(); + mInitialized = true; + + mHeavenlyBodyUpdated = FALSE ; } void LLVOSky::initCubeMap() @@ -598,7 +433,7 @@ void LLVOSky::initCubeMap() std::vector > images; for (S32 side = 0; side < 6; side++) { - images.push_back(mSkyTex[side].getImageRaw()); + images.push_back(mShinyTex[side].getImageRaw()); } if (mCubeMap) { @@ -639,7 +474,7 @@ void LLVOSky::restoreGL() mBloomTexturep = gImageList.getImage(IMG_BLOOM1); mBloomTexturep->setClamp(TRUE, TRUE); - calcBrightnessScaleAndColors(); + calcAtmospherics(); if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && gFeatureManagerp->isFeatureAvailable("RenderCubeMap")) @@ -649,7 +484,7 @@ void LLVOSky::restoreGL() std::vector > images; for (S32 side = 0; side < 6; side++) { - images.push_back(mSkyTex[side].getImageRaw()); + images.push_back(mShinyTex[side].getImageRaw()); } if(cube_map) @@ -666,67 +501,6 @@ void LLVOSky::restoreGL() } - -void LLVOSky::updateHaze() -{ - static LLRandLagFib607 weather_generator(LLUUID::getRandomSeed()); - if (gSavedSettings.getBOOL("FixedWeather")) - { - weather_generator.seed(8008135); - } - - const F32 fo_upper_bound = 5; - const F32 sca_upper_bound = 6; - const F32 fo = 1 + (F32)weather_generator() *(fo_upper_bound - 1); - const static F32 upper = 0.5f / gFastLn.ln(fo_upper_bound); - mHaze.setFalloff(fo); - mHaze.setG((F32)weather_generator() * (0.0f + upper * gFastLn.ln(fo))); - LLColor3 sca; - const F32 cd = mCloudDensity * 3; - F32 min_r = cd - 1; - if (min_r < 0) - { - min_r = 0; - } - F32 max_r = cd + 1; - if (max_r > sca_upper_bound) - { - max_r = sca_upper_bound; - } - - sca.mV[0] = min_r + (F32)weather_generator() * (max_r - min_r); - - min_r = sca.mV[0] - 0.1f; - if (min_r < 0) - { - min_r = 0; - } - max_r = sca.mV[0] + 0.5f; - if (max_r > sca_upper_bound) - { - max_r = sca_upper_bound; - } - - sca.mV[1] = min_r + (F32)weather_generator() * (max_r - min_r); - - min_r = sca.mV[1]; - if (min_r < 0) - { - min_r = 0; - } - max_r = sca.mV[1] + 1; - if (max_r > sca_upper_bound) - { - max_r = sca_upper_bound; - } - - sca.mV[2] = min_r + (F32)weather_generator() * (max_r - min_r); - - sca = AIR_SCA_AVG * sca; - - mHaze.setSigSca(sca); -} - void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile) { S32 tile_x = tile % NUM_TILES_X; @@ -754,6 +528,7 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile) LLVector3 dir(coeff[0], coeff[1], coeff[2]); dir.normVec(); mSkyTex[side].setDir(dir, x, y); + mShinyTex[side].setDir(dir, x, y); } } } @@ -772,404 +547,491 @@ void LLVOSky::createSkyTexture(const S32 side, const S32 tile) for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x) { mSkyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y)), x, y); + mShinyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y), true), x, y); } } } - -LLColor3 LLVOSky::calcSkyColorInDir(const LLVector3 &dir) +static inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right) { - LLColor3 col, transp; - - if (dir.mV[VZ] < -0.02f) - { - col = LLColor3(llmax(mFogColor[0],0.2f), llmax(mFogColor[1],0.2f), llmax(mFogColor[2],0.27f)); - float x = 1.0f-fabsf(-0.1f-dir.mV[VZ]); - x *= x; - col.mV[0] *= x*x; - col.mV[1] *= powf(x, 2.5f); - col.mV[2] *= x*x*x; - return col; - } + return LLColor3(left.mV[0]/right.mV[0], + left.mV[1]/right.mV[1], + left.mV[2]/right.mV[2]); +} - calcSkyColorInDir(col, transp, dir); - F32 br = color_max(col); - if (br > mBrightnessScaleNew) - { - mBrightnessScaleNew = br; - mBrightestPointNew = col; - } - return col; +static inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right) +{ + return LLColor3(left.mV[0]*right.mV[0], + left.mV[1]*right.mV[1], + left.mV[2]*right.mV[2]); } -LLColor4 LLVOSky::calcInScatter(LLColor4& transp, const LLVector3 &point, F32 exager = 1) const +static inline LLColor3 componentExp(LLColor3 const &v) { - LLColor3 col, tr; - calcInScatter(col, tr, point, exager); - col *= mBrightnessScaleGuess; - transp = LLColor4(tr); - return LLColor4(col); + return LLColor3(exp(v.mV[0]), + exp(v.mV[1]), + exp(v.mV[2])); } +static inline LLColor3 componentPow(LLColor3 const &v, F32 exponent) +{ + return LLColor3(pow(v.mV[0], exponent), + pow(v.mV[1], exponent), + pow(v.mV[2], exponent)); +} - -void LLVOSky::calcSkyColorInDir(LLColor3& res, LLColor3& transp, const LLVector3& dir) const +static inline LLColor3 componentSaturate(LLColor3 const &v) { - const LLVector3& tosun = getToSunLast(); - res.setToBlack(); - LLColor3 haze_res(0.f, 0.f, 0.f); - transp.setToWhite(); - LLVector3 step_v ; - LLVector3 cur_pos = mCameraPosAgent; - F32 h; - - F32 dist = calcHitsAtmEdge(mCameraPosAgent, dir); -// const F32 K = log(dist / FIRST_STEP + 1) / NO_STEPS; - const F32 K = gFastLn.ln(dist / FIRST_STEP + 1) / NO_STEPS; - const F32 e_pow_k = (F32)LL_FAST_EXP(K); - F32 step = FIRST_STEP * (1 - 1 / e_pow_k); - - // Initialize outside the loop because we write into them every iteration. JC - LLColor3 air_sca_opt_depth; - LLColor3 haze_sca_opt_depth; - LLColor3 air_transp; - - for (S32 s = 0; s < NO_STEPS; ++s) - { - h = calcHeight(cur_pos); - step *= e_pow_k; - LLHaze::calcAirSca(h, air_sca_opt_depth); - air_sca_opt_depth *= step; - - mHaze.calcSigSca(h, haze_sca_opt_depth); - haze_sca_opt_depth *= step; - - LLColor3 haze_ext_opt_depth = haze_sca_opt_depth; - haze_ext_opt_depth *= (1.f + mHaze.getAbsCoef()); - - if (calcHitsEarth(cur_pos, tosun) < 0) // calculates amount of in-scattered light from the sun - { - //visibility check is too expensive - mTransp.calcTransp(calcUpVec(cur_pos) * tosun, h, air_transp); - air_transp *= transp; - res += air_sca_opt_depth * air_transp; - haze_res += haze_sca_opt_depth * air_transp; - } - LLColor3 temp(-4.f * F_PI * (air_sca_opt_depth + haze_ext_opt_depth)); - temp.exp(); - transp *= temp; - step_v = dir * step; - cur_pos += step_v; - } - const F32 cos_dir = dir * tosun; - res *= calcAirPhaseFunc(cos_dir); - res += haze_res * mHaze.calcPhase(cos_dir); - res *= mSun.getIntensity(); + return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f), + std::max(std::min(v.mV[1], 1.f), 0.f), + std::max(std::min(v.mV[2], 1.f), 0.f)); } +static inline LLColor3 componentSqrt(LLColor3 const &v) +{ + return LLColor3(sqrt(v.mV[0]), + sqrt(v.mV[1]), + sqrt(v.mV[2])); +} +static inline void componentMultBy(LLColor3 & left, LLColor3 const & right) +{ + left.mV[0] *= right.mV[0]; + left.mV[1] *= right.mV[1]; + left.mV[2] *= right.mV[2]; +} -void LLVOSky::calcInScatter(LLColor3& res, LLColor3& transp, - const LLVector3& P, const F32 exaggeration) const +static inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount) { - const LLVector3& tosun = getToSunLast(); - res.setToBlack(); - transp.setToWhite(); + return (left + ((right - left) * amount)); +} - LLVector3 lower, upper; - LLVector3 dir = P - mCameraPosAgent; +static inline F32 texture2D(LLPointer const & tex, LLVector2 const & uv) +{ + U16 w = tex->getWidth(); + U16 h = tex->getHeight(); - F32 dist = exaggeration * dir.normVec(); + U16 r = U16(uv[0] * w) % w; + U16 c = U16(uv[1] * h) % h; - const F32 cos_dir = dir * tosun; + U8 const * imageBuffer = tex->getData(); - if (dir.mV[VZ] > 0) - { - lower = mCameraPosAgent; - upper = P; - } - else - { - lower = P; - upper = mCameraPosAgent; - dir = -dir; - } + U8 sample = imageBuffer[r * w + c]; - const F32 lower_h = calcHeight(lower); - const F32 upper_h = calcHeight(upper); - const LLVector3 up_upper = calcUpVec(upper); - const LLVector3 up_lower = calcUpVec(lower); + return sample / 255.f; +} + +static inline LLColor3 smear(F32 val) +{ + return LLColor3(val, val, val); +} - transp = color_div(mTransp.calcTransp(up_lower * dir, lower_h), - mTransp.calcTransp(up_upper * dir, upper_h)); - color_pow(transp, exaggeration); +void LLVOSky::initAtmospherics(void) +{ + bool error; + + // uniform parameters for convenience + dome_radius = LLWLParamManager::instance()->getDomeRadius(); + dome_offset_ratio = LLWLParamManager::instance()->getDomeOffset(); + sunlight_color = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("sunlight_color", error)); + ambient = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("ambient", error)); + //lightnorm = LLWLParamManager::instance()->mCurParams.getVector("lightnorm", error); + gamma = LLWLParamManager::instance()->mCurParams.getVector("gamma", error)[0]; + blue_density = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("blue_density", error)); + blue_horizon = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("blue_horizon", error)); + haze_density = LLWLParamManager::instance()->mCurParams.getVector("haze_density", error)[0]; + haze_horizon = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("haze_horizon", error)); + density_multiplier = LLWLParamManager::instance()->mCurParams.getVector("density_multiplier", error)[0]; + max_y = LLWLParamManager::instance()->mCurParams.getVector("max_y", error)[0]; + glow = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("glow", error)); + cloud_shadow = LLWLParamManager::instance()->mCurParams.getVector("cloud_shadow", error)[0]; + cloud_color = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("cloud_color", error)); + cloud_scale = LLWLParamManager::instance()->mCurParams.getVector("cloud_scale", error)[0]; + cloud_pos_density1 = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("cloud_pos_density1", error)); + cloud_pos_density2 = LLColor3(LLWLParamManager::instance()->mCurParams.getVector("cloud_pos_density2", error)); + + // light norm is different. We need the sun's direction, not the light direction + // which could be from the moon. And we need to clamp it + // just like for the gpu + LLVector3 sunDir = gSky.getSunDirection(); + + // CFR_TO_OGL + lightnorm = LLVector4(sunDir.mV[1], sunDir.mV[2], sunDir.mV[0], 0); + unclamped_lightnorm = lightnorm; + if(lightnorm.mV[1] < -0.1f) + { + lightnorm.mV[1] = -0.1f; + } + +} - if (calcHitsEarth(upper, tosun) > 0) +LLColor4 LLVOSky::calcSkyColorInDir(const LLVector3 &dir, bool isShiny) +{ + F32 saturation = 0.3f; + if (dir.mV[VZ] < -0.02f) { - const F32 avg = color_avg(transp); - //const F32 avg = llmin(1.f, 1.2f * color_avg(transp)); - transp.setVec(avg, avg, avg); - return; + LLColor4 col = LLColor4(llmax(mFogColor[0],0.2f), llmax(mFogColor[1],0.2f), llmax(mFogColor[2],0.22f),0.f); + if (isShiny) + { + LLColor3 desat_fog = LLColor3(mFogColor); + F32 brightness = desat_fog.brightness(); + // So that shiny somewhat shows up at night. + if (brightness < 0.15f) + { + brightness = 0.15f; + desat_fog = smear(0.15f); + } + LLColor3 greyscale = smear(brightness); + desat_fog = desat_fog * saturation + greyscale * (1.0f - saturation); + if (!gPipeline.canUseWindLightShaders()) + { + col = LLColor4(desat_fog, 0.f); + } + else + { + col = LLColor4(desat_fog * 0.5f, 0.f); + } + } + float x = 1.0f-fabsf(-0.1f-dir.mV[VZ]); + x *= x; + col.mV[0] *= x*x; + col.mV[1] *= powf(x, 2.5f); + col.mV[2] *= x*x*x; + return col; } - LLColor3 air_sca_opt_depth = LLHaze::calcAirSca(upper_h); - LLColor3 haze_sca_opt_depth = mHaze.calcSigSca(upper_h); - LLColor3 sun_transp; - mTransp.calcTransp(up_upper * tosun, upper_h, sun_transp); + // undo OGL_TO_CFR_ROTATION and negate vertical direction. + LLVector3 Pn = LLVector3(-dir[1] , -dir[2], -dir[0]); - if (calcHitsEarth(lower, tosun) < 0) + LLColor3 vary_HazeColor(0,0,0); + LLColor3 vary_CloudColorSun(0,0,0); + LLColor3 vary_CloudColorAmbient(0,0,0); + F32 vary_CloudDensity(0); + LLVector2 vary_HorizontalProjection[2]; + vary_HorizontalProjection[0] = LLVector2(0,0); + vary_HorizontalProjection[1] = LLVector2(0,0); + + calcSkyColorWLVert(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient, + vary_CloudDensity, vary_HorizontalProjection); + + LLColor3 sky_color = calcSkyColorWLFrag(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient, + vary_CloudDensity, vary_HorizontalProjection); + if (isShiny) { - air_sca_opt_depth += LLHaze::calcAirSca(lower_h); - air_sca_opt_depth *= 0.5; - haze_sca_opt_depth += mHaze.calcSigSca(lower_h); - haze_sca_opt_depth *= 0.5; - sun_transp += mTransp.calcTransp(up_lower * tosun, lower_h); - sun_transp *= 0.5; + F32 brightness = sky_color.brightness(); + LLColor3 greyscale = smear(brightness); + sky_color = sky_color * saturation + greyscale * (1.0f - saturation); + sky_color *= (0.5f + 0.5f * brightness); } - - res = calcAirPhaseFunc(cos_dir) * air_sca_opt_depth; - res += mHaze.calcPhase(cos_dir) * haze_sca_opt_depth; - res = mSun.getIntensity() * dist * sun_transp * res; + return LLColor4(sky_color, 0.0f); } +// turn on floating point precision +// in vs2003 for this function. Otherwise +// sky is aliased looking 7:10 - 8:50 +#if LL_MSVC && __MSVC_VER__ < 8 +#pragma optimize("p", on) +#endif +void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun, + LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity, + LLVector2 vary_HorizontalProjection[2]) +{ + // project the direction ray onto the sky dome. + F32 phi = acos(Pn[1]); + F32 sinA = sin(F_PI - phi); + F32 Plen = dome_radius * sin(F_PI + phi + asin(dome_offset_ratio * sinA)) / sinA; + Pn *= Plen; + vary_HorizontalProjection[0] = LLVector2(Pn[0], Pn[2]); + vary_HorizontalProjection[0] /= - 2.f * Plen; - -F32 LLVOSky::calcHitsEarth(const LLVector3& orig, const LLVector3& dir) const -{ - const LLVector3 from_earth_center = mEarthCenter - orig; - const F32 tca = dir * from_earth_center; - if ( tca < 0 ) + // Set altitude + if (Pn[1] > 0.f) { - return -1; + Pn *= (max_y / Pn[1]); } - - const F32 thc2 = EARTH_RADIUS * EARTH_RADIUS - - from_earth_center.magVecSquared() + tca * tca; - if (thc2 < 0 ) + else { - return -1; + Pn *= (-32000.f / Pn[1]); } - return tca - sqrt ( thc2 ); -} + Plen = Pn.magVec(); + Pn /= Plen; -F32 LLVOSky::calcHitsAtmEdge(const LLVector3& orig, const LLVector3& dir) const -{ - const LLVector3 from_earth_center = mEarthCenter - orig; - const F32 tca = dir * from_earth_center; + // Initialize temp variables + LLColor3 sunlight = sunlight_color; - const F32 thc2 = (EARTH_RADIUS + mAtmHeight) * (EARTH_RADIUS + mAtmHeight) - - from_earth_center.magVecSquared() + tca * tca; - return tca + sqrt(thc2); -} + // Sunlight attenuation effect (hue and brightness) due to atmosphere + // this is used later for sunlight modulation at various altitudes + LLColor3 light_atten = + (blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y); + // Calculate relative weights + LLColor3 temp2(0.f, 0.f, 0.f); + LLColor3 temp1 = blue_density + smear(haze_density); + LLColor3 blue_weight = componentDiv(blue_density, temp1); + LLColor3 haze_weight = componentDiv(smear(haze_density), temp1); -void LLVOSky::updateBrightestDir() -{ - LLColor3 br_pt, transp; - const S32 test_no = 5; - const F32 step = F_PI_BY_TWO / (test_no + 1); - for (S32 i = 0; i < test_no; ++i) - { - F32 cos_dir = cos ((i + 1) * step); - calcSkyColorInDir(br_pt, transp, move_vec(getToSunLast(), cos_dir)); - const F32 br = color_max(br_pt); - if (br > mBrightnessScaleGuess) - { - mBrightnessScaleGuess = br; - mBrightestPointGuess = br_pt; - } - } -} + // Compute sunlight from P & lightnorm (for long rays like sky) + temp2.mV[1] = llmax(F_APPROXIMATELY_ZERO, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] ); + temp2.mV[1] = 1.f / temp2.mV[1]; + componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); -void LLVOSky::calcBrightnessScaleAndColors() -{ - // new correct normalization. - if (mBrightnessScaleNew < 1e-7) - { - mBrightnessScale = 1; - mBrightestPoint.setToBlack(); - } - else - { - mBrightnessScale = 1.f/mBrightnessScaleNew; - mBrightestPoint = mBrightestPointNew; - } + // Distance + temp2.mV[2] = Plen * density_multiplier; - mBrightnessScaleNew = 0; - // and addition + // Transparency (-> temp1) + temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); - // Calculate Sun and Moon color - const F32 h = llmax(0.0f, mCameraPosAgent.mV[2]); - const LLColor3 sun_color = mSun.getIntensity() * mTransp.calcTransp(getToSunLast().mV[2], h); - const LLColor3 moon_color = mNightColorShift * - mMoon.getIntensity() * mTransp.calcTransp(getToMoonLast().mV[2], h); - F32 intens = color_intens(sun_color); - F32 increase_sun_br = (intens > 0) ? 1.2f * color_intens(mBrightestPoint) / intens : 1; + // Compute haze glow + temp2.mV[0] = Pn * LLVector3(lightnorm); - intens = color_intens(moon_color); - F32 increase_moon_br = (intens > 0) ? 1.2f * llmax(1.0f, color_intens(mBrightestPoint) / intens) : 1; + temp2.mV[0] = 1.f - temp2.mV[0]; + // temp2.x is 0 at the sun and increases away from sun + temp2.mV[0] = llmax(temp2.mV[0], .001f); + // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.mV[0] *= glow.mV[0]; + // Higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.mV[0] = pow(temp2.mV[0], glow.mV[2]); + // glow.z should be negative, so we're doing a sort of (1 / "angle") function - mSun.setColor(mBrightnessScale * increase_sun_br * sun_color); - mMoon.setColor(mBrightnessScale * increase_moon_br * moon_color); + // Add "minimum anti-solar illumination" + temp2.mV[0] += .25f; - const LLColor3 haze_col = color_norm_abs(mHaze.getSigSca()); - for (S32 i = 0; i < 6; ++i) - { - mSkyTex[i].create(mBrightnessScale, mHazeConcentration * mBrightestPoint * haze_col); - } - mBrightnessScaleGuess = mBrightnessScale; - mBrightestPointGuess = mBrightestPoint; + // Haze color above cloud + vary_HazeColor = (blue_horizon * blue_weight * (sunlight + ambient) + + componentMult(haze_horizon.mV[0] * haze_weight, sunlight * temp2.mV[0] + ambient) + ); -// calculateColors(); // MSMSM Moving this down to before generateScatterMap(), per Milo Lindens suggestion, to fix orange flashing bug. + // Increase ambient when there are more clouds + LLColor3 tmpAmbient = ambient + (LLColor3::white - ambient) * cloud_shadow * 0.5f; - mSun.renewDirection(); - mSun.renewColor(); - mMoon.renewDirection(); - mMoon.renewColor(); + // Dim sunlight by cloud shadow percentage + sunlight *= (1.f - cloud_shadow); - LLColor3 transp; + // Haze color below cloud + LLColor3 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient) + + componentMult(haze_horizon.mV[0] * haze_weight, sunlight * temp2.mV[0] + tmpAmbient) + ); - if (calcHitsEarth(mCameraPosAgent, getToSunLast()) < 0) - { - calcSkyColorInDir(mBrightestPointGuess, transp, getToSunLast()); - mBrightnessScaleGuess = color_max(mBrightestPointGuess); - updateBrightestDir(); - mBrightnessScaleGuess = 1.f / llmax(1.0f, mBrightnessScaleGuess); - } - else if (getToSunLast().mV[2] > -0.5) - { - const LLVector3 almost_to_sun = toHorizon(getToSunLast()); - calcSkyColorInDir(mBrightestPointGuess, transp, almost_to_sun); - mBrightnessScaleGuess = color_max(mBrightestPointGuess); - updateBrightestDir(); - mBrightnessScaleGuess = 1.f / llmax(1.0f, mBrightnessScaleGuess); - } - else + // Final atmosphere additive + componentMultBy(vary_HazeColor, LLColor3::white - temp1); + + sunlight = sunlight_color; + temp2.mV[1] = llmax(0.f, lightnorm[1] * 2.f); + temp2.mV[1] = 1.f / temp2.mV[1]; + componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); + + // Attenuate cloud color by atmosphere + temp1 = componentSqrt(temp1); //less atmos opacity (more transparency) below clouds + + // At horizon, blend high altitude sky color towards the darker color below the clouds + vary_HazeColor += + componentMult(additiveColorBelowCloud - vary_HazeColor, LLColor3::white - componentSqrt(temp1)); + + if (Pn[1] < 0.f) { - mBrightestPointGuess.setToBlack(); - mBrightnessScaleGuess = 1; - } + // Eric's original: + // LLColor3 dark_brown(0.143f, 0.129f, 0.114f); + LLColor3 dark_brown(0.082f, 0.076f, 0.066f); + LLColor3 brown(0.430f, 0.386f, 0.322f); + LLColor3 sky_lighting = sunlight + ambient; + F32 haze_brightness = vary_HazeColor.brightness(); - calculateColors(); // MSMSM Moved this down here per Milo Lindens suggestion, to fix orange flashing bug at sunset. + if (Pn[1] < -0.05f) + { + vary_HazeColor = colorMix(dark_brown, brown, -Pn[1] * 0.9f) * sky_lighting * haze_brightness; + } + + if (Pn[1] > -0.1f) + { + vary_HazeColor = colorMix(LLColor3::white * haze_brightness, vary_HazeColor, fabs((Pn[1] + 0.05f) * -20.f)); + } + } } +#if LL_MSVC && __MSVC_VER__ < 8 +#pragma optimize("p", off) +#endif -void LLVOSky::calculateColors() +LLColor3 LLVOSky::calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun, + LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity, + LLVector2 vary_HorizontalProjection[2]) { - const F32 h = -0.1f; - const LLVector3& tosun = getToSunLast(); + LLColor3 res; - F32 full_on, full_off, on, on_cl; - F32 sun_factor = 1; + LLColor3 color0 = vary_HazeColor; - // Sun Diffuse - F32 sun_height = tosun.mV[2]; + if (!gPipeline.canUseWindLightShaders()) + { + LLColor3 color1 = color0 * 2.0f; + color1 = smear(1.f) - componentSaturate(color1); + componentPow(color1, gamma); + res = smear(1.f) - color1; + } + else + { + res = color0; + } + +# ifndef LL_RELEASE_FOR_DOWNLOAD + + LLColor3 color2 = 2.f * color0; + + LLColor3 color3 = LLColor3(1.f, 1.f, 1.f) - componentSaturate(color2); + componentPow(color3, gamma); + color3 = LLColor3(1.f, 1.f, 1.f) - color3; + + static enum { + OUT_DEFAULT = 0, + OUT_SKY_BLUE = 1, + OUT_RED = 2, + OUT_PN = 3, + OUT_HAZE = 4, + } debugOut = OUT_DEFAULT; + + switch(debugOut) + { + case OUT_DEFAULT: + break; + case OUT_SKY_BLUE: + res = LLColor3(0.4f, 0.4f, 0.9f); + break; + case OUT_RED: + res = LLColor3(1.f, 0.f, 0.f); + break; + case OUT_PN: + res = LLColor3(Pn[0], Pn[1], Pn[2]); + break; + case OUT_HAZE: + res = vary_HazeColor; + break; + } +# endif // LL_RELEASE_FOR_DOWNLOAD + return res; +} - if (sun_height <= 0.0) - sun_height = 0.0; - - mSunDiffuse = mBrightnessScaleGuess * mSun.getIntensity() * mTransp.calcTransp(sun_height, h); +LLColor3 LLVOSky::createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient) +{ + return componentMult(diffuse, sundiffuse) * 4.0f + + componentMult(ambient, sundiffuse) * 2.0f + sunambient; +} - mSunDiffuse = 1.0f * color_norm(mSunDiffuse); +LLColor3 LLVOSky::createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient) +{ + return (componentMult(ambient, sundiffuse) + sunambient) * 0.8f; +} - // Sun Ambient - full_off = -0.3f; - full_on = -0.03f; - if (tosun.mV[2] < full_off) - { - mSunAmbient.setToBlack(); - } - else + +void LLVOSky::calcAtmospherics(void) +{ + initAtmospherics(); + + LLColor3 vary_HazeColor; + LLColor3 vary_SunlightColor; + LLColor3 vary_AmbientColor; { - on = (tosun.mV[2] - full_off) / (full_on - full_off); - sun_factor = llmax(0.0f, llmin(on, 1.0f)); + // Initialize temp variables + LLColor3 sunlight = sunlight_color; - LLColor3 sun_amb = mAmbientScale * (0.8f * mSunDiffuse + - 0.2f * mBrightnessScaleGuess * mBrightestPointGuess); + // Sunlight attenuation effect (hue and brightness) due to atmosphere + // this is used later for sunlight modulation at various altitudes + LLColor3 light_atten = + (blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y); - color_norm_pow(sun_amb, 0.1f, TRUE); - sun_factor *= min_intens_factor(sun_amb, 1.9f); - mSunAmbient = LLColor4(sun_factor * sun_amb); - } + // Calculate relative weights + LLColor3 temp2(0.f, 0.f, 0.f); + LLColor3 temp1 = blue_density + smear(haze_density); + LLColor3 blue_weight = componentDiv(blue_density, temp1); + LLColor3 haze_weight = componentDiv(smear(haze_density), temp1); + // Compute sunlight from P & lightnorm (for long rays like sky) + /// USE only lightnorm. + // temp2[1] = llmax(0.f, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] ); + + // and vary_sunlight will work properly with moon light + F32 lighty = unclamped_lightnorm[1]; + if(lighty < NIGHTTIME_ELEVATION_COS) + { + lighty = -lighty; + } - // Moon Diffuse - full_on = 0.3f; - full_off = 0.01f; - if (getToMoonLast().mV[2] < full_off) - { - mMoonDiffuse.setToBlack(); - } - else - { - // Steve: Added moonlight diffuse factor scalar (was constant .3) - F32 diffuse_factor = .1f + sNighttimeBrightness * .2f; // [.1, .5] default = .3 - on = (getToMoonLast().mV[2] - full_off) / (full_on - full_off); - on_cl = llmin(on, 1.0f); - mMoonDiffuse = on_cl * mNightColorShift * diffuse_factor; - } + temp2.mV[1] = llmax(0.f, lighty); + temp2.mV[1] = 1.f / temp2.mV[1]; + componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); - // Moon Ambient + // Distance + temp2.mV[2] = density_multiplier; - F32 moon_amb_factor = 1.f; + // Transparency (-> temp1) + temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); - if (gAgent.inPrelude()) - { - moon_amb_factor *= 2.0f; - } + // vary_AtmosAttenuation = temp1; + + //increase ambient when there are more clouds + LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5f; + + //haze color + vary_HazeColor = + (blue_horizon * blue_weight * (sunlight*(1.f - cloud_shadow) + tmpAmbient) + + componentMult(haze_horizon.mV[0] * haze_weight, sunlight*(1.f - cloud_shadow) * temp2.mV[0] + tmpAmbient) + ); + + //brightness of surface both sunlight and ambient + vary_SunlightColor = componentMult(sunlight, temp1) * 1.f; + vary_SunlightColor.clamp(); + vary_SunlightColor = smear(1.0f) - vary_SunlightColor; + vary_SunlightColor = componentPow(vary_SunlightColor, gamma); + vary_SunlightColor = smear(1.0f) - vary_SunlightColor; + vary_AmbientColor = componentMult(tmpAmbient, temp1) * 0.5; + vary_AmbientColor.clamp(); + vary_AmbientColor = smear(1.0f) - vary_AmbientColor; + vary_AmbientColor = componentPow(vary_AmbientColor, gamma); + vary_AmbientColor = smear(1.0f) - vary_AmbientColor; + + componentMultBy(vary_HazeColor, LLColor3(1.f, 1.f, 1.f) - temp1); - full_on = 0.30f; - full_off = 0.01f; - if (getToMoonLast().mV[2] < full_off) - { - mMoonAmbient.setToBlack(); - } - else - { - on = (getToMoonLast().mV[2] - full_off) / (full_on - full_off); - on_cl = llmax(0.0f, llmin(on, 1.0f)); - mMoonAmbient = on_cl * moon_amb_factor * mMoonDiffuse; } + mSun.setColor(vary_SunlightColor); + mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f)); - // Sun Diffuse - full_off = -0.05f; - full_on = -0.00f; - if (tosun.mV[2] < full_off) + mSun.renewDirection(); + mSun.renewColor(); + mMoon.renewDirection(); + mMoon.renewColor(); + + float dp = getToSunLast() * LLVector3(0,0,1.f); + if (dp < 0) { - mSunDiffuse.setToBlack(); + dp = 0; } - else - { - on = (getToSunLast().mV[2] - full_off) / (full_on - full_off); - sun_factor = llmax(0.0f, llmin(on, 1.0f)); - color_norm_pow(mSunDiffuse, 0.12f, TRUE); - sun_factor *= min_intens_factor(mSunDiffuse, 2.1f); - mSunDiffuse *= sun_factor; - } + // Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio + // between sunlight and point lights in windlight to normalize point lights. + F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f); + LLWLParamManager::instance()->mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp); + mSunDiffuse = vary_SunlightColor; + mSunAmbient = vary_AmbientColor; + mMoonDiffuse = vary_SunlightColor; + mMoonAmbient = vary_AmbientColor; - mTotalAmbient = mSunAmbient + mMoonAmbient; + mTotalAmbient = vary_AmbientColor; mTotalAmbient.setAlpha(1); - //llinfos << "MoonDiffuse: " << mMoonDiffuse << llendl; - //llinfos << "TotalAmbient: " << mTotalAmbient << llendl; - + mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f; mFadeColor.setAlpha(0); } - BOOL LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { return TRUE; @@ -1177,7 +1039,7 @@ BOOL LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) BOOL LLVOSky::updateSky() { - if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))) + if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))) { return TRUE; } @@ -1196,7 +1058,7 @@ BOOL LLVOSky::updateSky() const S32 total_no_tiles = 6 * NUM_TILES; const S32 cycle_frame_no = total_no_tiles + 1; -// if (mUpdateTimer.getElapsedTimeF32() > 0.1f) + if (mUpdateTimer.getElapsedTimeF32() > 0.001f) { mUpdateTimer.reset(); const S32 frame = next_frame; @@ -1205,12 +1067,13 @@ BOOL LLVOSky::updateSky() next_frame = next_frame % cycle_frame_no; sInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no; + // sInterpVal = (F32)next_frame / cycle_frame_no; LLSkyTex::setInterpVal( sInterpVal ); LLHeavenBody::setInterpVal( sInterpVal ); - calculateColors(); + calcAtmospherics(); + if (mForceUpdate || total_no_tiles == frame) { - calcBrightnessScaleAndColors(); LLSkyTex::stepCurrent(); const static F32 LIGHT_DIRECTION_THRESHOLD = (F32) cos(DEG_TO_RAD * 1.f); @@ -1248,7 +1111,7 @@ BOOL LLVOSky::updateSky() } } - calcBrightnessScaleAndColors(); + calcAtmospherics(); for (int side = 0; side < 6; side++) { @@ -1256,21 +1119,42 @@ BOOL LLVOSky::updateSky() LLImageRaw* raw2 = mSkyTex[side].getImageRaw(FALSE); raw2->copy(raw1); mSkyTex[side].createGLImage(mSkyTex[side].getWhich(FALSE)); + + raw1 = mShinyTex[side].getImageRaw(TRUE); + raw2 = mShinyTex[side].getImageRaw(FALSE); + raw2->copy(raw1); + mShinyTex[side].createGLImage(mShinyTex[side].getWhich(FALSE)); } next_frame = 0; } + } + } - std::vector > images; - for (S32 side = 0; side < 6; side++) - { - images.push_back(mSkyTex[side].getImageRaw(FALSE)); - } - mCubeMap->init(images); + /// *TODO really, sky texture and env map should be shared on a single texture + /// I'll let Brad take this at some point + + // update the sky texture + for (S32 i = 0; i < 6; ++i) + { + mSkyTex[i].create(1.0f); + mShinyTex[i].create(1.0f); + } + + // update the environment map + if (mCubeMap) + { + std::vector > images; + images.reserve(6); + for (S32 side = 0; side < 6; side++) + { + images.push_back(mShinyTex[side].getImageRaw(TRUE)); } + mCubeMap->init(images); } gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); - gPipeline.markRebuild(gSky.mVOStarsp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); + // *TODO: decide whether we need to update the stars vertex buffer in LLVOWLSky -Brad. + //gPipeline.markRebuild(gSky.mVOWLSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); mForceUpdate = FALSE; } @@ -1282,15 +1166,13 @@ BOOL LLVOSky::updateSky() } } - - if (mDrawable) + if (mDrawable.notNull() && mDrawable->getFace(0) && mDrawable->getFace(0)->mVertexBuffer.isNull()) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } return TRUE; } - void LLVOSky::updateTextures(LLAgent &agent) { if (mSunTexturep) @@ -1324,12 +1206,61 @@ LLDrawable *LLVOSky::createDrawable(LLPipeline *pipeline) return mDrawable; } +//by bao +//fake vertex buffer updating +//to guaranttee at least updating one VBO buffer every frame +//to walk around the bug caused by ATI card --> DEV-3855 +// +void LLVOSky::createDummyVertexBuffer() +{ + if(!mFace[FACE_DUMMY]) + { + LLDrawPoolSky *poolp = (LLDrawPoolSky*) gPipeline.getPool(LLDrawPool::POOL_SKY); + mFace[FACE_DUMMY] = mDrawable->addFace(poolp, NULL); + } + + if(mFace[FACE_DUMMY]->mVertexBuffer.isNull()) + { + mFace[FACE_DUMMY]->mVertexBuffer = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); + mFace[FACE_DUMMY]->mVertexBuffer->allocateBuffer(1, 1, TRUE); + } +} + +void LLVOSky::updateDummyVertexBuffer() +{ + if(!LLVertexBuffer::sEnableVBOs) + return ; + + if(mHeavenlyBodyUpdated) + { + mHeavenlyBodyUpdated = FALSE ; + return ; + } + + LLFastTimer t(LLFastTimer::FTM_RENDER_FAKE_VBO_UPDATE) ; + + if(!mFace[FACE_DUMMY] || mFace[FACE_DUMMY]->mVertexBuffer.isNull()) + createDummyVertexBuffer() ; + + LLStrider vertices ; + mFace[FACE_DUMMY]->mVertexBuffer->getVertexStrider(vertices, 0); + *vertices = mCameraPosAgent ; + mFace[FACE_DUMMY]->mVertexBuffer->setBuffer(0) ; +} +//---------------------------------- +//end of fake vertex buffer updating +//---------------------------------- + BOOL LLVOSky::updateGeometry(LLDrawable *drawable) { + LLFastTimer ftm(LLFastTimer::FTM_GEO_SKY); if (mFace[FACE_REFLECTION] == NULL) { LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER); - mFace[FACE_REFLECTION] = drawable->addFace(poolp, NULL); + if (gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() != 0) + { + mFace[FACE_REFLECTION] = drawable->addFace(poolp, NULL); + } } mCameraPosAgent = drawable->getPositionAgent(); @@ -1342,14 +1273,14 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) F32 x_sgn = (i&1) ? 1.f : -1.f; F32 y_sgn = (i&2) ? 1.f : -1.f; F32 z_sgn = (i&4) ? 1.f : -1.f; - v_agent[i] = HORIZON_DIST*0.25f * LLVector3(x_sgn, y_sgn, z_sgn); + v_agent[i] = HORIZON_DIST * SKY_BOX_MULT * LLVector3(x_sgn, y_sgn, z_sgn); } LLStrider verticesp; LLStrider normalsp; LLStrider texCoordsp; - LLStrider indicesp; - S32 index_offset; + LLStrider indicesp; + U16 index_offset; LLFace *face; for (S32 side = 0; side < 6; ++side) @@ -1395,6 +1326,8 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) *indicesp++ = index_offset + 0; *indicesp++ = index_offset + 3; *indicesp++ = index_offset + 2; + + face->mVertexBuffer->setBuffer(0); } } @@ -1430,11 +1363,8 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) if (height_above_water > 0) { -#if 1 //1.9.1 BOOL render_ref = gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0; -#else - BOOL render_ref = !(gPipeline.getVertexShaderLevel(LLPipeline::SHADER_ENVIRONMENT) >= LLDrawPoolWater::SHADER_LEVEL_RIPPLE); -#endif + if (sun_flag) { setDrawRefl(0); @@ -1457,24 +1387,29 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) setDrawRefl(-1); } - LLPipeline::sCompiles++; return TRUE; } - BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, const BOOL is_sun, LLHeavenBody& hb, const F32 cos_max_angle, const LLVector3 &up, const LLVector3 &right) { + mHeavenlyBodyUpdated = TRUE ; + LLStrider verticesp; LLStrider normalsp; LLStrider texCoordsp; - LLStrider indicesp; + LLStrider indicesp; S32 index_offset; LLFace *facep; LLVector3 to_dir = hb.getDirection(); + + if (!is_sun) + { + to_dir.mV[2] = llmax(to_dir.mV[2]+0.1f, 0.1f); + } LLVector3 draw_pos = to_dir * HEAVENLY_BODY_DIST; @@ -1521,14 +1456,15 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons if (facep->mVertexBuffer.isNull()) { - facep->setSize(4, 6); - facep->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + facep->setSize(4, 6); + facep->mVertexBuffer = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); facep->mVertexBuffer->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE); facep->setGeomIndex(0); facep->setIndicesIndex(0); } index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp); + if (-1 == index_offset) { return TRUE; @@ -1542,10 +1478,8 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons *(texCoordsp++) = TEX01; *(texCoordsp++) = TEX00; - //*(texCoordsp++) = (t_left > 0) ? LLVector2(0, t_left) : TEX00; *(texCoordsp++) = TEX11; *(texCoordsp++) = TEX10; - //*(texCoordsp++) = (t_right > 0) ? LLVector2(1, t_right) : TEX10; *indicesp++ = index_offset + 0; *indicesp++ = index_offset + 2; @@ -1555,6 +1489,8 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons *indicesp++ = index_offset + 2; *indicesp++ = index_offset + 3; + facep->mVertexBuffer->setBuffer(0); + if (is_sun) { if ((t_left > 0) && (t_right > 0)) @@ -1651,12 +1587,13 @@ F32 clip_side_to_horizon(const LLVector3& V0, const LLVector3& V1, const F32 cos void LLVOSky::updateSunHaloGeometry(LLDrawable *drawable ) { +#if 0 const LLVector3* v_corner = mSun.corners(); LLStrider verticesp; LLStrider normalsp; LLStrider texCoordsp; - LLStrider indicesp; + LLStrider indicesp; S32 index_offset; LLFace *face; @@ -1708,6 +1645,7 @@ void LLVOSky::updateSunHaloGeometry(LLDrawable *drawable ) *indicesp++ = index_offset + 1; *indicesp++ = index_offset + 2; *indicesp++ = index_offset + 3; +#endif } @@ -1932,7 +1870,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, LLStrider verticesp; LLStrider normalsp; LLStrider texCoordsp; - LLStrider indicesp; + LLStrider indicesp; S32 index_offset; index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); @@ -2063,6 +2001,8 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, } } } + + face->mVertexBuffer->setBuffer(0); } @@ -2072,37 +2012,11 @@ void LLVOSky::updateFog(const F32 distance) { if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG)) { - /*gGLSFog.addCap(GL_FOG, FALSE); - gGLSPipeline.addCap(GL_FOG, FALSE); - gGLSPipelineAlpha.addCap(GL_FOG, FALSE); - gGLSPipelinePixieDust.addCap(GL_FOG, FALSE); - gGLSPipelineSelection.addCap(GL_FOG, FALSE); - gGLSPipelineAvatar.addCap(GL_FOG, FALSE); - gGLSPipelineAvatarAlphaOnePass.addCap(GL_FOG, FALSE); - gGLSPipelineAvatarAlphaPass1.addCap(GL_FOG, FALSE); - gGLSPipelineAvatarAlphaPass2.addCap(GL_FOG, FALSE); - gGLSPipelineAvatarAlphaPass3.addCap(GL_FOG, FALSE);*/ glFogf(GL_FOG_DENSITY, 0); glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV); glFogf(GL_FOG_END, 1000000.f); return; } - else - { - /*gGLSFog.addCap(GL_FOG, TRUE); - gGLSPipeline.addCap(GL_FOG, TRUE); - gGLSPipelineAlpha.addCap(GL_FOG, TRUE); - gGLSPipelinePixieDust.addCap(GL_FOG, TRUE); - gGLSPipelineSelection.addCap(GL_FOG, TRUE); - if (!gGLManager.mIsATI) - { - gGLSPipelineAvatar.addCap(GL_FOG, TRUE); - gGLSPipelineAvatarAlphaOnePass.addCap(GL_FOG, TRUE); - gGLSPipelineAvatarAlphaPass1.addCap(GL_FOG, TRUE); - gGLSPipelineAvatarAlphaPass2.addCap(GL_FOG, TRUE); - gGLSPipelineAvatarAlphaPass3.addCap(GL_FOG, TRUE); - }*/ - } const BOOL hide_clip_plane = TRUE; LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f); @@ -2120,7 +2034,6 @@ void LLVOSky::updateFog(const F32 distance) LLColor3 sky_fog_color = LLColor3::white; LLColor3 render_fog_color = LLColor3::white; - LLColor3 transp; LLVector3 tosun = getToSunLast(); const F32 tosun_z = tosun.mV[VZ]; tosun.mV[VZ] = 0.f; @@ -2140,9 +2053,10 @@ void LLVOSky::updateFog(const F32 distance) tosun_45.normVec(); // Sky colors, just slightly above the horizon in the direction of the sun, perpendicular to the sun, and at a 45 degree angle to the sun. - calcSkyColorInDir(res_color[0],transp, tosun); - calcSkyColorInDir(res_color[1],transp, perp_tosun); - calcSkyColorInDir(res_color[2],transp, tosun_45); + initAtmospherics(); + res_color[0] = calcSkyColorInDir(tosun); + res_color[1] = calcSkyColorInDir(perp_tosun); + res_color[2] = calcSkyColorInDir(tosun_45); sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]); @@ -2163,54 +2077,59 @@ void LLVOSky::updateFog(const F32 distance) color_gamma_correct(sky_fog_color); render_fog_color = sky_fog_color; + + F32 fog_density = 0.f; + fog_distance = mFogRatio * distance; if (camera_height > water_height) { - fog_distance = mFogRatio * distance; LLColor4 fog(render_fog_color); glFogfv(GL_FOG_COLOR, fog.mV); mGLFogCol = fog; + + if (hide_clip_plane) + { + // For now, set the density to extend to the cull distance. + const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f))) + fog_density = f_log/fog_distance; + glFogi(GL_FOG_MODE, GL_EXP2); + } + else + { + const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f)) + fog_density = (f_log)/fog_distance; + glFogi(GL_FOG_MODE, GL_EXP); + } } else { - // Interpolate between sky fog and water fog... F32 depth = water_height - camera_height; - F32 depth_frac = 1.f/(1.f + 200.f*depth); - F32 color_frac = 1.f/(1.f + 0.5f* depth)* 0.2f; - fog_distance = (mFogRatio * distance) * depth_frac + 30.f * (1.f-depth_frac); - fog_distance = llmin(75.f, fog_distance); - - F32 brightness = 1.f/(1.f + 0.05f*depth); - F32 sun_brightness = getSunDiffuseColor().magVec() * 0.3f; - brightness = llmin(1.f, brightness); - brightness = llmin(brightness, sun_brightness); - color_frac = llmin(0.7f, color_frac); - - LLColor4 fogCol = brightness * (color_frac * render_fog_color + (1.f - color_frac) * LLColor4(0.f, 0.2f, 0.3f, 1.f)); + + // get the water param manager variables + float water_fog_density = LLWaterParamManager::instance()->getFogDensity(); + LLColor4 water_fog_color = LLDrawPoolWater::sWaterFogColor.mV; + + // adjust the color based on depth. We're doing linear approximations + float depth_scale = gSavedSettings.getF32("WaterGLFogDepthScale"); + float depth_modifier = 1.0f - llmin(llmax(depth / depth_scale, 0.01f), + gSavedSettings.getF32("WaterGLFogDepthFloor")); + + LLColor4 fogCol = water_fog_color * depth_modifier; fogCol.setAlpha(1); + + // set the gl fog color glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV); mGLFogCol = fogCol; + + // set the density based on what the shaders use + fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale"); + glFogi(GL_FOG_MODE, GL_EXP2); } mFogColor = sky_fog_color; mFogColor.setAlpha(1); LLGLSFog gls_fog; - F32 fog_density; - if (hide_clip_plane) - { - // For now, set the density to extend to the cull distance. - const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f))) - fog_density = f_log/fog_distance; - glFogi(GL_FOG_MODE, GL_EXP2); - } - else - { - const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f)) - fog_density = (f_log)/fog_distance; - glFogi(GL_FOG_MODE, GL_EXP); - } - glFogf(GL_FOG_END, fog_distance*2.2f); glFogf(GL_FOG_DENSITY, fog_density); @@ -2279,197 +2198,53 @@ F32 azimuth(const LLVector3 &v) return azimuth; } - -#if 0 -// Not currently used -LLColor3 LLVOSky::calcGroundFog(LLColor3& transp, const LLVector3 &view_dir, F32 obj_dist) const -{ - LLColor3 col; - calcGroundFog(col, transp, view_dir, obj_dist); - col *= mBrightnessScaleGuess; - return col; -} -#endif - -void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity) +void LLVOSky::initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity) { LLVector3 sun_direction = (sun_dir.magVec() == 0) ? LLVector3::x_axis : sun_dir; sun_direction.normVec(); - F32 dp = mSun.getDirection() * sun_direction; mSun.setDirection(sun_direction); + mSun.renewDirection(); mSun.setAngularVelocity(sun_ang_velocity); - mMoon.setDirection(-sun_direction); - if (dp < 0.995f) { //the sun jumped a great deal, update immediately - updateHaze(); - mWeatherChange = FALSE; - mForceUpdate = TRUE; - } - else if (mWeatherChange && (mSun.getDirection().mV[VZ] > -0.5) ) - { - updateHaze(); - init(); - mWeatherChange = FALSE; - } - else if (mSun.getDirection().mV[VZ] < -0.5) - { - mWeatherChange = TRUE; - } -} - -#define INV_WAVELENGTH_R_POW4 (1.f/0.2401f) // = 1/0.7^4 -#define INV_WAVELENGTH_G_POW4 (1.f/0.0789f) // = 1/0.53^4 -#define INV_WAVELENGTH_B_POW4 (1.f/0.03748f) // = 1/0.44^4 - -// Dummy class for globals used below. Replace when KILLERSKY is merged in. -class LLKillerSky -{ -public: - static F32 sRaleighGroundDensity; - static F32 sMieFactor; - static F32 sNearFalloffFactor; - static F32 sSkyContrib; - - static void getRaleighCoefficients(float eye_sun_dp, float density, float *coefficients) - { - float dp = eye_sun_dp; - float angle_dep = density*(1 + dp*dp); - coefficients[0] = angle_dep * INV_WAVELENGTH_R_POW4; - coefficients[1] = angle_dep * INV_WAVELENGTH_G_POW4; - coefficients[2] = angle_dep * INV_WAVELENGTH_B_POW4; - } - - static void getMieCoefficients(float eye_sun_dp, float density, float *coefficient) - { - // TOTALLY ARBITRARY FUNCTION. Seems to work though - // If anyone can replace this with some *actual* mie function, that'd be great - float dp = eye_sun_dp; - float dp_highpower = dp*dp; - float angle_dep = density * (llclamp(dp_highpower*dp, 0.f, 1.f) + 0.4f); - *coefficient = angle_dep; - } -}; - -F32 LLKillerSky::sRaleighGroundDensity = 0.013f; -F32 LLKillerSky::sMieFactor = 50; -F32 LLKillerSky::sNearFalloffFactor = 1.5f; -F32 LLKillerSky::sSkyContrib = 0.06f; - -void LLVOSky::generateScatterMap() -{ - float raleigh[3], mie; - - mScatterMap = new LLImageGL(FALSE); - mScatterMapRaw = new LLImageRaw(256, 256, 4); - U8 *data = mScatterMapRaw->getData(); + mMoon.setDirection(-mSun.getDirection()); + mMoon.renewDirection(); + mLastLightingDirection = mSun.getDirection(); - F32 light_brightness = gSky.getSunDirection().mV[VZ]+0.1f; - LLColor4 light_color; - LLColor4 sky_color; - if (light_brightness > 0) - { - F32 interp = sqrtf(light_brightness); - light_brightness = sqrt(sqrtf(interp)); - light_color = lerp(gSky.getSunDiffuseColor(), LLColor4(1,1,1,1), interp) * light_brightness; - sky_color = lerp(LLColor4(0,0,0,0), LLColor4(0.4f, 0.6f, 1.f, 1.f), light_brightness)*LLKillerSky::sSkyContrib; - } - else - { - light_brightness = /*0.3f*/sqrt(-light_brightness); - light_color = gSky.getMoonDiffuseColor() * light_brightness; - sky_color = LLColor4(0,0,0,1); - } + calcAtmospherics(); - // x = distance [0..1024m] - // y = dot product [-1,1] - for (int y=0;y<256;y++) + if ( !mInitialized ) { - // Accumulate outward - float accum_r = 0, accum_g = 0, accum_b = 0; - - float dp = (((float)y)/255.f)*1.95f - 0.975f; - U8 *scanline = &data[y*256*4]; - for (int x=0;x<256;x++) - { - float dist = ((float)x+1)*4; // x -> 2048 - - float raleigh_density = LLKillerSky::sRaleighGroundDensity * 0.05f; // Arbitrary? Perhaps... - float mie_density = raleigh_density*LLKillerSky::sMieFactor; - - float extinction_factor = dist/LLKillerSky::sNearFalloffFactor; - - LLKillerSky::getRaleighCoefficients(dp, raleigh_density, raleigh); - LLKillerSky::getMieCoefficients(dp, mie_density, &mie); - - float falloff_r = pow(llclamp(0.985f-raleigh[0],0.f,1.f), extinction_factor); - float falloff_g = pow(llclamp(0.985f-raleigh[1],0.f,1.f), extinction_factor); - float falloff_b = pow(llclamp(0.985f-raleigh[2],0.f,1.f), extinction_factor); - - float light_r = light_color.mV[0] * (raleigh[0]+mie+sky_color.mV[0]) * falloff_r; - float light_g = light_color.mV[1] * (raleigh[1]+mie+sky_color.mV[1]) * falloff_g; - float light_b = light_color.mV[2] * (raleigh[2]+mie+sky_color.mV[2]) * falloff_b; - - accum_r += light_r; - accum_g += light_g; - accum_b += light_b; - - scanline[x*4] = (U8)llclamp(accum_r*255.f, 0.f, 255.f); - scanline[x*4+1] = (U8)llclamp(accum_g*255.f, 0.f, 255.f); - scanline[x*4+2] = (U8)llclamp(accum_b*255.f, 0.f, 255.f); - float alpha = ((falloff_r+falloff_g+falloff_b)*0.33f); - scanline[x*4+3] = (U8)llclamp(alpha*255.f, 0.f, 255.f); // Avg falloff - - // Output color Co, Input color Ci, Map channels Mrgb, Ma: - // Co = (Ci * Ma) + Mrgb - } - } - - mScatterMap->createGLTexture(0, mScatterMapRaw); - mScatterMap->bind(0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + init(); + LLSkyTex::stepCurrent(); + } } -#if 0 -// Not currently used -void LLVOSky::calcGroundFog(LLColor3& res, LLColor3& transp, const LLVector3 view_dir, F32 obj_dist) const +void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity) { - const LLVector3& tosun = getToSunLast();//use_old_value ? sunDir() : toSunLast(); - res.setToBlack(); - transp.setToWhite(); - const F32 dist = obj_dist * mWorldScale; - - //LLVector3 view_dir = gCamera->getAtAxis(); - - const F32 cos_dir = view_dir * tosun; - LLVector3 dir = view_dir; - LLVector3 virtual_P = mCameraPosAgent + dist * dir; + LLVector3 sun_direction = (sun_dir.magVec() == 0) ? LLVector3::x_axis : sun_dir; + sun_direction.normVec(); - if (dir.mV[VZ] < 0) - { - dir = -dir; - } + // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping + // on the upward facing faces of cubes. + LLVector3 newDir = sun_direction; - const F32 z_dir = dir.mV[2]; + // Same as dot product with the up direction + clamp. + F32 sunDot = llmax(0.f, newDir.mV[2]); + sunDot *= sunDot; - const F32 h = mCameraPosAgent.mV[2]; + // Create normalized vector that has the sunDir pushed south about an hour and change. + LLVector3 adjustedDir = (newDir + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; - transp = color_div(mTransp.calcTransp(dir * calcUpVec(virtual_P), 0), - mTransp.calcTransp(z_dir, h)); + // Blend between normal sun dir and adjusted sun dir based on how close we are + // to having the sun overhead. + mBumpSunDir = adjustedDir * sunDot + newDir * (1.0f - sunDot); + mBumpSunDir.normVec(); - if (calcHitsEarth(mCameraPosAgent, tosun) > 0) - { - const F32 avg = llmin(1.f, 1.2f * color_avg(transp)); - transp = LLColor3(avg, avg, avg); - return; + F32 dp = mLastLightingDirection * sun_direction; + mSun.setDirection(sun_direction); + mSun.setAngularVelocity(sun_ang_velocity); + mMoon.setDirection(-sun_direction); + calcAtmospherics(); + if (dp < 0.995f) { //the sun jumped a great deal, update immediately + mForceUpdate = TRUE; } - - LLColor3 haze_sca_opt_depth = mHaze.getSigSca(); - LLColor3 sun_transp; - mTransp.calcTransp(tosun.mV[2], -0.1f, sun_transp); - - res = calcAirPhaseFunc(cos_dir) * LLHaze::getAirScaSeaLevel(); - res += mHaze.calcPhase(cos_dir) * mHaze.getSigSca(); - res = mSun.getIntensity() * dist * sun_transp * res; } - -#endif diff --git a/linden/indra/newview/llvosky.h b/linden/indra/newview/llvosky.h index 2600541..70aa3af 100644 --- a/linden/indra/newview/llvosky.h +++ b/linden/indra/newview/llvosky.h @@ -48,6 +48,7 @@ // const F32 HORIZON_DIST = 1024.0f; +const F32 SKY_BOX_MULT = 16.0f; const F32 HEAVENLY_BODY_DIST = HORIZON_DIST - 10.f; const F32 HEAVENLY_BODY_FACTOR = 0.1f; const F32 HEAVENLY_BODY_SCALE = HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR; @@ -85,7 +86,6 @@ LL_FORCE_INLINE LLColor3 color_div(const LLColor3 &col1, const LLColor3 &col2) } LLColor3 color_norm(const LLColor3 &col); -LLVector3 move_vec (const LLVector3& v, F32 cos_max_angle); BOOL clip_quad_to_horizon(F32& t_left, F32& t_right, LLVector3 v_clipped[4], const LLVector3 v_corner[4], const F32 cos_max_angle); F32 clip_side_to_horizon(const LLVector3& v0, const LLVector3& v1, const F32 cos_max_angle); @@ -111,18 +111,6 @@ inline F32 color_min(const LLColor3 &col) return llmin(col.mV[0], col.mV[1], col.mV[2]); } -inline LLColor3 color_norm_abs(const LLColor3 &col) -{ - const F32 m = color_max(col); - if (m > 1e-6) - { - return 1.f/m * col; - } - else return col; -} - - - class LLFace; class LLHaze; @@ -135,7 +123,7 @@ private: static S32 sComponents; LLPointer mImageGL[2]; LLPointer mImageRaw[2]; - LLColor3 *mSkyData; + LLColor4 *mSkyData; LLVector3 *mSkyDirs; // Cache of sky direction vectors static S32 sCurrent; static F32 sInterpVal; @@ -163,7 +151,8 @@ protected: static S32 getWhich(const BOOL curr) { return curr ? sCurrent : getNext(); } void initEmpty(const S32 tex); - void create(F32 brightness_scale, const LLColor3& multiscatt); + + void create(F32 brightness); void setDir(const LLVector3 &dir, const S32 i, const S32 j) { @@ -177,7 +166,7 @@ protected: return mSkyDirs[offset]; } - void setPixel(const LLColor3 &col, const S32 i, const S32 j) + void setPixel(const LLColor4 &col, const S32 i, const S32 j) { S32 offset = i * sResolution + j; mSkyData[offset] = col; @@ -203,7 +192,7 @@ protected: void createGLImage(BOOL curr=TRUE); }; - +/// TODO Move into the stars draw pool (and rename them appropriately). class LLHeavenBody { protected: @@ -261,27 +250,6 @@ public: return sInterpVal * mColor + (1 - sInterpVal) * mColorCached; } -// LLColor3 getDiffuseColor() const -// { -// LLColor3 dif = mColorCached; -// dif.clamp(); -// return 2 * dif; -// } - -// LLColor4 getAmbientColor(const LLColor3& scatt, F32 scale) const -// { -// const F32 min_val = 0.05f; -// LLColor4 col = LLColor4(scale * (0.8f * color_norm_abs(getDiffuseColor()) + 0.2f * scatt)); -// //F32 left = max(0, 1 - col.mV[0]); -// if (col.mV[0] >= 0.9) -// { -// col.mV[1] = llmax(col.mV[1], 2.f * min_val); -// col.mV[2] = llmax(col.mV[2], min_val); -// } -// col.setAlpha(1.f); -// return col; -// } - const F32& getHorizonVisibility() const { return mHorizonVisibility; } void setHorizonVisibility(const F32 c = 1) { mHorizonVisibility = c; } const F32& getVisibility() const { return mVisibility; } @@ -440,82 +408,55 @@ protected: F32 mAbsCoef; }; -class LLTranspMap -{ -public: - LLTranspMap() : mElevation(0), mMaxAngle(0), mStep(5), mHaze(NULL), mT(NULL) {} - ~LLTranspMap() - { - delete[] mT; - mT = NULL; - } - - void init(const F32 elev, const F32 step, const F32 h, const LLHaze* const haze); - - F32 calcHeight(const LLVector3& pos) const - { - return pos.magVec() - EARTH_RADIUS ; - } - - BOOL hasHaze() const - { - return mHaze != NULL; - } - LLColor3 calcSigExt(const F32 h) const - { - return LLHaze::calcAirSca(h) + (hasHaze() ? mHaze->calcSigExt(h) : LLColor3(0, 0, 0)); - } +class LLCubeMap; - inline void calcAirTransp(const F32 cos_angle, LLColor3 &result) const; - LLColor3 calcAirTranspDir(const F32 elevation, const LLVector3 &dir) const; - LLColor3 getHorizonAirTransp () const { return mT[mMapSize-1]; } - F32 hitsAtmEdge(const LLVector3& orig, const LLVector3& dir) const; +// turn on floating point precision +// in vs2003 for this class. Otherwise +// black dots go everywhere from 7:10 - 8:50 +#if LL_MSVC && __MSVC_VER__ < 8 +#pragma optimize("p", on) +#endif -protected: - F32 mAtmHeight; - F32 mElevation; - F32 mMaxAngle; - F32 mCosMaxAngle; - F32 mStep; - F32 mStepInv; - S32 mMapSize; - const LLHaze *mHaze; - LLColor3 *mT; // transparency values in all directions - //starting with mAngleBelowHorz at mElevation -}; -class LLTranspMapSet +class LLVOSky : public LLStaticViewerObject { -protected: - F32 *mHeights; - LLTranspMap *mTransp; - S32 mSize; - F32 mMediaHeight; - const LLHaze *mHaze; - S32 lerp(F32& dt, S32& indx, const F32 h) const; public: - LLTranspMapSet() : mHeights(NULL), mTransp(NULL), mHaze(NULL) {} - ~LLTranspMapSet(); - - void init (S32 size, F32 first_step, F32 media_height, const LLHaze* const haze); - S32 getSize() const { return mSize; } - F32 getMediaHeight() const { return mMediaHeight; } - const LLTranspMap& getLastTransp() const { return mTransp[mSize-1]; } - F32 getLastHeight() const { return mHeights[mSize-1]; } - const LLTranspMap& getMap(const S32 n) const { return mTransp[n]; } - F32 getHeight(const S32 n) const { return mHeights[n]; } - BOOL isReady() const { return mTransp != NULL; } - - inline LLColor3 calcTransp(const F32 cos_angle, const F32 h) const; - inline void calcTransp(const F32 cos_angle, const F32 h, LLColor3 &result) const; -}; + /// WL PARAMS + F32 dome_radius; + F32 dome_offset_ratio; + LLColor3 sunlight_color; + LLColor3 ambient; + F32 gamma; + LLVector4 lightnorm; + LLVector4 unclamped_lightnorm; + LLColor3 blue_density; + LLColor3 blue_horizon; + F32 haze_density; + LLColor3 haze_horizon; + F32 density_multiplier; + F32 max_y; + LLColor3 glow; + F32 cloud_shadow; + LLColor3 cloud_color; + F32 cloud_scale; + LLColor3 cloud_pos_density1; + LLColor3 cloud_pos_density2; + +public: + void initAtmospherics(void); + void calcAtmospherics(void); + LLColor3 createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient); + LLColor3 createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient); -class LLCubeMap; + void calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun, + LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity, + LLVector2 vary_HorizontalProjection[2]); + LLColor3 calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun, + LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity, + LLVector2 vary_HorizontalProjection[2]); -class LLVOSky : public LLStaticViewerObject -{ public: enum { @@ -529,6 +470,7 @@ public: FACE_MOON, // was 7 FACE_BLOOM, // was 8 FACE_REFLECTION, // was 10 + FACE_DUMMY, //for an ATI bug --bao FACE_COUNT }; @@ -539,9 +481,7 @@ public: void init(); void initCubeMap(); void initEmpty(); - BOOL isReady() const { return mTransp.isReady(); } - const LLTranspMapSet& getTransp() const { return mTransp; } - + void cleanupGL(); void restoreGL(); @@ -557,26 +497,12 @@ public: void initSkyTextureDirs(const S32 side, const S32 tile); void createSkyTexture(const S32 side, const S32 tile); - void updateBrightestDir(); - void calcBrightnessScaleAndColors(); - - LLColor3 calcSkyColorInDir(const LLVector3& dir); - void calcSkyColorInDir(LLColor3& res, LLColor3& transp, - const LLVector3& dir) const; - LLColor4 calcInScatter(LLColor4& transp, const LLVector3 &point, F32 exag) const; - void calcInScatter( LLColor3& res, LLColor3& transp, - const LLVector3& P, F32 exag) const; - - // Not currently used. - //LLColor3 calcGroundFog(LLColor3& transp, const LLVector3 &view_dir, F32 obj_dist) const; - //void calcGroundFog(LLColor3& res, LLColor3& transp, const LLVector3 view_dir, F32 dist) const; - + LLColor4 calcSkyColorInDir(const LLVector3& dir, bool isShiny = false); + LLColor3 calcRadianceAtPoint(const LLVector3& pos) const { - const F32 cos_angle = calcUpVec(pos) * getToSunLast(); - LLColor3 tr; - mTransp.calcTransp(cos_angle, calcHeight(pos), tr); - return mBrightnessScaleGuess * mSun.getIntensity() * tr; + F32 radiance = mBrightnessScaleGuess * mSun.getIntensity(); + return LLColor3(radiance, radiance, radiance); } const LLHeavenBody& getSun() const { return mSun; } @@ -597,58 +523,16 @@ public: LLColor4 getFogColor() const { return mFogColor; } LLColor4 getGLFogColor() const { return mGLFogCol; } - LLVector3 calcUpVec(const LLVector3 &pos) const - { - LLVector3 v = pos - mEarthCenter; - v.normVec(); - return v; - } - - F32 calcHeight(const LLVector3& pos) const - { - return dist_vec(pos, mEarthCenter) - EARTH_RADIUS; - } - - // Phase function for atmospheric scattering. - // co = cos ( theta ) - F32 calcAirPhaseFunc(const F32 co) const - { - return (0.75f * (1.f + co*co)); - } - - BOOL isSameFace(S32 idx, const LLFace* face) const { return mFace[idx] == face; } - void initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity) - { - LLVector3 sun_direction = (sun_dir.magVec() == 0) ? LLVector3::x_axis : sun_dir; - sun_direction.normVec(); - mSun.setDirection(sun_direction); - mSun.renewDirection(); - mSun.setAngularVelocity(sun_ang_velocity); - mMoon.setDirection(-mSun.getDirection()); - mMoon.renewDirection(); - mLastLightingDirection = mSun.getDirection(); - - if ( !isReady() ) - { - init(); - LLSkyTex::stepCurrent(); - } - } + void initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity); void setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity); - void updateHaze(); - BOOL updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 side, const BOOL is_sun, LLHeavenBody& hb, const F32 sin_max_angle, const LLVector3 &up, const LLVector3 &right); - LLVector3 toHorizon(const LLVector3& dir, F32 delta = 0) const - { - return move_vec(dir, cosHorizon(delta)); - } F32 cosHorizon(const F32 delta = 0) const { const F32 sin_angle = EARTH_RADIUS/(EARTH_RADIUS + mCameraPosAgent.mV[2]); @@ -681,18 +565,14 @@ public: BOOL isReflFace(const LLFace* face) const { return face == mFace[FACE_REFLECTION]; } LLFace* getReflFace() const { return mFace[FACE_REFLECTION]; } - F32 calcHitsEarth(const LLVector3& orig, const LLVector3& dir) const; - F32 calcHitsAtmEdge(const LLVector3& orig, const LLVector3& dir) const; LLViewerImage* getSunTex() const { return mSunTexturep; } LLViewerImage* getMoonTex() const { return mMoonTexturep; } LLViewerImage* getBloomTex() const { return mBloomTexturep; } - - void generateScatterMap(); - LLImageGL* getScatterMap() { return mScatterMap; } + void forceSkyUpdate(void) { mForceUpdate = TRUE; } public: - static F32 sNighttimeBrightness; // [0,2] default = 1.0 - LLFace *mFace[FACE_COUNT]; + LLFace *mFace[FACE_COUNT]; + LLVector3 mBumpSunDir; protected: ~LLVOSky(); @@ -705,6 +585,7 @@ protected: static S32 sTileResX; static S32 sTileResY; LLSkyTex mSkyTex[6]; + LLSkyTex mShinyTex[6]; LLHeavenBody mSun; LLHeavenBody mMoon; LLVector3 mSunDefaultPosition; @@ -718,7 +599,6 @@ protected: LLColor3 mBrightestPointNew; F32 mBrightnessScaleGuess; LLColor3 mBrightestPointGuess; - LLTranspMapSet mTransp; LLHaze mHaze; F32 mHazeConcentration; BOOL mWeatherChange; @@ -751,10 +631,23 @@ protected: LLFrameTimer mUpdateTimer; - LLPointer mScatterMap; - LLPointer mScatterMapRaw; +public: + //by bao + //fake vertex buffer updating + //to guaranttee at least updating one VBO buffer every frame + //to walk around the bug caused by ATI card --> DEV-3855 + // + void createDummyVertexBuffer() ; + void updateDummyVertexBuffer() ; + + BOOL mHeavenlyBodyUpdated ; }; +// turn it off +#if LL_MSVC && __MSVC_VER__ < 8 +#pragma optimize("p", off) +#endif + // Utility functions F32 azimuth(const LLVector3 &v); F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply = FALSE); @@ -776,161 +669,5 @@ inline void LLHaze::calcAirSca(const F32 h, LLColor3 &result) result *= calcFalloff(h); } -// Given cos of the angle between direction of interest and zenith, -// compute transparency by interpolation of known values. -inline void LLTranspMap::calcAirTransp(const F32 cos_angle, LLColor3 &result) const -{ - if (cos_angle > 1.f) - { - result = mT[0]; - return; - } - if (cos_angle < mCosMaxAngle - 0.1f) - { - result.setVec(0.f, 0.f, 0.f); - return; - } - if (cos_angle < mCosMaxAngle) - { - result = mT[mMapSize-1]; - return; - } - - - const F32 relative = (1 - cos_angle)*mStepInv; - const S32 index = llfloor(relative); - const F32 dt = relative - index; - - if (index >= (mMapSize-1)) - { - result = mT[0]; - return; - } -// result = mT[index]; -// LLColor3 res2(mT[index+1]); -// result *= 1 - dt; -// res2 *= dt; -// result += res2; - - const LLColor3& color1 = mT[index]; - const LLColor3& color2 = mT[index + 1]; - - const F32 x1 = color1.mV[VX]; - const F32 x2 = color2.mV[VX]; - result.mV[VX] = x1 - dt * (x1 - x2); - - const F32 y1 = color1.mV[VY]; - const F32 y2 = color2.mV[VY]; - result.mV[VY] = y1 - dt * (y1 - y2); - - const F32 z1 = color1.mV[VZ]; - const F32 z2 = color2.mV[VZ]; - result.mV[VZ] = z1 - dt * (z1 - z2); -} - - - -// Returns the translucency of the atmosphere along the ray in the sky. -// dir is assumed to be normalized -inline void LLTranspMapSet::calcTransp(const F32 cos_angle, const F32 h, LLColor3 &result) const -{ - S32 indx = 0; - F32 dt = 0.f; - const S32 status = lerp(dt, indx, h); - - if (status < 0) - { - mTransp[0].calcAirTransp(cos_angle, result); - return; - } - if (status > 0) - { - mTransp[NO_STEPS].calcAirTransp(cos_angle, result); - return; - } - - mTransp[indx].calcAirTransp(cos_angle, result); - result *= 1 - dt; - - LLColor3 transp_above; - - mTransp[indx + 1].calcAirTransp(cos_angle, transp_above); - transp_above *= dt; - result += transp_above; -} - - -inline LLColor3 LLTranspMapSet::calcTransp(const F32 cos_angle, const F32 h) const -{ - LLColor3 result; - S32 indx = 0; - F32 dt = 0; - const S32 status = lerp(dt, indx, h); - - if (status < 0) - { - mTransp[0].calcAirTransp(cos_angle, result); - return result; - } - if (status > 0) - { - mTransp[NO_STEPS].calcAirTransp(cos_angle, result); - return result; - } - - mTransp[indx].calcAirTransp(cos_angle, result); - result *= 1 - dt; - - LLColor3 transp_above; - - mTransp[indx + 1].calcAirTransp(cos_angle, transp_above); - transp_above *= dt; - result += transp_above; - return result; -} - - -// Returns -1 if height < 0; +1 if height > max height; 0 if within range -inline S32 LLTranspMapSet::lerp(F32& dt, S32& indx, const F32 h) const -{ - static S32 last_indx = 0; - - if (h < 0) - { - return -1; - } - if (h > getLastHeight()) - { - return 1; - } - - if (h < mHeights[last_indx]) - { - indx = last_indx-1; - while (mHeights[indx] > h) - { - indx--; - } - last_indx = indx; - } - else if (h > mHeights[last_indx+1]) - { - indx = last_indx+1; - while (mHeights[indx+1] < h) - { - indx++; - } - last_indx = indx; - } - else - { - indx = last_indx; - } - - const F32 h_below = mHeights[indx]; - const F32 h_above = mHeights[indx+1]; - dt = (h - h_below) / (h_above - h_below); - return 0; -} #endif diff --git a/linden/indra/newview/llvostars.cpp b/linden/indra/newview/llvostars.cpp deleted file mode 100644 index 80bc74c..0000000 --- a/linden/indra/newview/llvostars.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/** - * @file llvostars.cpp - * @brief LLVOStars class implementation - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llvostars.h" - -#include "lldrawpoolstars.h" -#include "llface.h" -#include "llsky.h" -#include "llvosky.h" -#include "llworld.h" -#include "pipeline.h" - -const U32 NUMBER_OF_STARS = 1000; -const F32 DISTANCE_TO_STARS = (HORIZON_DIST - 10.f)*0.25f; - - -LLVOStars::LLVOStars(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) - : LLStaticViewerObject(id, pcode, regionp) -{ - initStars(); -} - -LLVOStars::~LLVOStars() -{ - delete[] mStarVertices; - mStarVertices = NULL; - delete[] mStarColors; - mStarColors = NULL; - delete[] mStarIntensities; - mStarIntensities = NULL; -} - -LLDrawable *LLVOStars::createDrawable(LLPipeline *pipeline) -{ - pipeline->allocDrawable(this); - mDrawable->setLit(FALSE); - - LLDrawPoolStars *poolp = (LLDrawPoolStars*) gPipeline.getPool(LLDrawPool::POOL_STARS); - - mFace = mDrawable->addFace(poolp, NULL); - mDrawable->setRenderType(LLPipeline::RENDER_TYPE_STARS); - mFace->setSize(NUMBER_OF_STARS, NUMBER_OF_STARS); - - return mDrawable; -} - -BOOL LLVOStars::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) -{ - return TRUE; -} - -BOOL LLVOStars::updateGeometry(LLDrawable *drawable) -{ - updateStarColors(); - updateStarGeometry(drawable); - - LLPipeline::sCompiles++; - return TRUE; -} - -BOOL LLVOStars::updateStarGeometry(LLDrawable *drawable) -{ - LLStrider verticesp; - LLStrider normalsp; - LLStrider texCoordsp; - LLStrider colorsp; - LLStrider indicesp; - S32 index_offset; - - if (mFace->mVertexBuffer.isNull()) - { - mFace->mVertexBuffer = new LLVertexBuffer(LLDrawPoolStars::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - mFace->mVertexBuffer->allocateBuffer(mFace->getGeomCount(), mFace->getIndicesCount(), TRUE); - mFace->setGeomIndex(0); - mFace->setIndicesIndex(0); - } - - index_offset = mFace->getGeometryColors(verticesp,normalsp,texCoordsp,colorsp, indicesp); - - if (-1 == index_offset) - { - return TRUE; - } - - for (U32 vtx = 0; vtx < NUMBER_OF_STARS; ++vtx) - { - *(verticesp++) = mStarVertices[vtx]; - *(colorsp++) = LLColor4U(mStarColors[vtx]); - *(indicesp++) = index_offset + vtx; - } - - return TRUE; -} - - -void LLVOStars::initStars() -{ - // Initialize star map - mStarVertices = new LLVector3 [NUMBER_OF_STARS]; - mStarColors = new LLColor4 [NUMBER_OF_STARS]; - mStarIntensities = new F32 [NUMBER_OF_STARS]; - - LLVector3 * v_p = mStarVertices; - LLColor4 * v_c = mStarColors; - F32 * v_i = mStarIntensities; - - U32 i; - for (i = 0; i < NUMBER_OF_STARS; i++ ) - { - v_p->mV[VX] = ll_frand() - 0.5f; - v_p->mV[VY] = ll_frand() - 0.5f; - - // we only want stars on the top half of the dome! - - v_p->mV[VZ] = ll_frand()/2.f; - - v_p->normVec(); - *v_p *= DISTANCE_TO_STARS; - *v_i = llmin((F32)pow(ll_frand(),2.f) + 0.1f, 1.f); - v_c->mV[VRED] = 0.75f + ll_frand() * 0.25f ; - v_c->mV[VGREEN] = 1.f ; - v_c->mV[VBLUE] = 0.75f + ll_frand() * 0.25f ; - v_c->mV[VALPHA] = 1.f; - v_c->clamp(); - v_p++; - v_c++; - v_i++; - } -} - -void LLVOStars::updateStarColors() -{ - LLColor4 * v_c; - v_c = mStarColors; - F32 * v_i = mStarIntensities; - LLVector3* v_p = mStarVertices; - - const F32 var = 0.15f; - const F32 min = 0.5f; //0.75f; - const F32 sunclose_max = 0.6f; - const F32 sunclose_range = 1 - sunclose_max; - - F32 below_horizon = - llmin(0.0f, gSky.mVOSkyp->getToSunLast().mV[2]); - F32 brightness_factor = llmin(1.0f, below_horizon * 20); - - static S32 swap = 0; - swap++; - - if ((swap % 2) == 1) - { - F32 intensity; // max intensity of each star - U32 x; - for (x = 0; x < NUMBER_OF_STARS; x++) - { - F32 sundir_factor = 1; - LLVector3 tostar = *v_p; - tostar.normVec(); - const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast(); - if (how_close_to_sun > sunclose_max) - { - sundir_factor = (1 - how_close_to_sun) / sunclose_range; - } - intensity = *(v_i); - F32 alpha = v_c->mV[VALPHA] + (ll_frand() - 0.5f) * var * intensity; - if (alpha < min * intensity) - { - alpha = min * intensity; - } - if (alpha > intensity) - { - alpha = intensity; - } - alpha *= brightness_factor * sundir_factor; - alpha = llclamp(alpha, 0.f, 1.f); - v_c->mV[VALPHA] = alpha; - v_c++; - v_i++; - v_p++; - } - } -} diff --git a/linden/indra/newview/llvostars.h b/linden/indra/newview/llvostars.h deleted file mode 100644 index e06d2d9..0000000 --- a/linden/indra/newview/llvostars.h +++ /dev/null @@ -1,67 +0,0 @@ -/** - * @file llvostars.h - * @brief LLVOStars class header file - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLVOSTARS_H -#define LL_LLVOSTARS_H - -#include "stdtypes.h" -#include "v4color.h" -#include "llviewerobject.h" -#include "llframetimer.h" - -class LLFace; - -class LLVOStars : public LLStaticViewerObject -{ -public: - LLVOStars(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); - - /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); - /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); - /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); - - LLColor4* getStarColors() { return mStarColors; } - -protected: - ~LLVOStars(); - - void initStars(); - void updateStarColors(); - BOOL updateStarGeometry(LLDrawable *drawable); - -protected: - LLVector3 *mStarVertices; // Star verticies - LLColor4 *mStarColors; // Star colors - F32 *mStarIntensities; // Star intensities - LLFace *mFace; -}; - -#endif diff --git a/linden/indra/newview/llvosurfacepatch.cpp b/linden/indra/newview/llvosurfacepatch.cpp index 677a8be..3665ec7 100644 --- a/linden/indra/newview/llvosurfacepatch.cpp +++ b/linden/indra/newview/llvosurfacepatch.cpp @@ -46,6 +46,9 @@ #include "llvlcomposition.h" #include "llvovolume.h" #include "pipeline.h" +#include "llspatialpartition.h" + +F32 LLVOSurfacePatch::sLODFactor = 1.f; //============================================================================ @@ -187,6 +190,8 @@ BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TERRAIN); + dirtySpatialGroup(); + S32 min_comp, max_comp, range; min_comp = lltrunc(mPatchp->getMinComposition()); max_comp = lltrunc(ceil(mPatchp->getMaxComposition())); @@ -271,8 +276,6 @@ void LLVOSurfacePatch::updateFaceSize(S32 idx) BOOL LLVOSurfacePatch::updateLOD() { - //mDrawable->updateLightSet(); - mDrawable->setState(LLDrawable::LIGHTING_BUILT); return TRUE; } @@ -281,7 +284,7 @@ void LLVOSurfacePatch::getGeometry(LLStrider &verticesp, LLStrider &colorsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp) + LLStrider &indicesp) { LLFace* facep = mDrawable->getFace(0); @@ -319,7 +322,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, LLStrider &colorsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, + LLStrider &indicesp, U32 &index_offset) { S32 i, j, x, y; @@ -355,10 +358,9 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, x = i * render_stride; y = j * render_stride; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + *colorsp++ = LLColor4U::white; verticesp++; normalsp++; - colorsp++; texCoords0p++; texCoords1p++; } @@ -424,7 +426,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, LLStrider &colorsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, + LLStrider &indicesp, U32 &index_offset) { S32 vertex_count = 0; @@ -459,10 +461,9 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, y = 16 - render_stride; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + *colorsp++ = LLColor4U::white; verticesp++; normalsp++; - colorsp++; texCoords0p++; texCoords1p++; vertex_count++; @@ -474,10 +475,9 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, x = i * render_stride; y = 16; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); verticesp++; normalsp++; - colorsp++; + *colorsp++ = LLColor4U::white; texCoords0p++; texCoords1p++; vertex_count++; @@ -514,10 +514,9 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, y = 16 - render_stride; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); verticesp++; normalsp++; - colorsp++; + *colorsp++ = LLColor4U::white; texCoords0p++; texCoords1p++; vertex_count++; @@ -530,10 +529,9 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, y = 16; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); verticesp++; normalsp++; - colorsp++; + *colorsp++ = LLColor4U::white; texCoords0p++; texCoords1p++; vertex_count++; @@ -577,10 +575,9 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, y = 16 - render_stride; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + *colorsp++ = LLColor4U::white; verticesp++; normalsp++; - colorsp++; texCoords0p++; texCoords1p++; vertex_count++; @@ -593,10 +590,9 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, y = 16; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); verticesp++; normalsp++; - colorsp++; + *colorsp++ = LLColor4U::white; texCoords0p++; texCoords1p++; vertex_count++; @@ -637,7 +633,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, LLStrider &colorsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, + LLStrider &indicesp, U32 &index_offset) { S32 i, x, y; @@ -666,10 +662,9 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, y = i * render_stride; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); verticesp++; normalsp++; - colorsp++; + *colorsp++ = LLColor4U::white; texCoords0p++; texCoords1p++; } @@ -680,10 +675,9 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, x = 16; y = i * render_stride; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); verticesp++; normalsp++; - colorsp++; + *colorsp++ = LLColor4U::white; texCoords0p++; texCoords1p++; } @@ -719,10 +713,9 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, y = i * render_stride; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); verticesp++; normalsp++; - colorsp++; + *colorsp++ = LLColor4U::white; texCoords0p++; texCoords1p++; } @@ -733,10 +726,9 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, y = i * render_stride; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); verticesp++; normalsp++; - colorsp++; + *colorsp++ = LLColor4U::white; texCoords0p++; texCoords1p++; } @@ -778,10 +770,9 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, y = i * east_stride; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); verticesp++; normalsp++; - colorsp++; + *colorsp++ = LLColor4U::white; texCoords0p++; texCoords1p++; } @@ -792,10 +783,9 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, y = i * east_stride; mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); - calcColor(verticesp.get(), normalsp.get(), colorsp.get()); verticesp++; normalsp++; - colorsp++; + *colorsp++ = LLColor4U::white; texCoords0p++; texCoords1p++; } @@ -829,35 +819,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, index_offset += num_vertices; } -void LLVOSurfacePatch::calcColor(const LLVector3* vertex, const LLVector3* normal, LLColor4U* colorp) -{ - LLColor4 color(0,0,0,0); - if (gPipeline.getLightingDetail() >= 2) - { - for (LLDrawable::drawable_set_t::iterator iter = mDrawable->mLightSet.begin(); - iter != mDrawable->mLightSet.end(); ++iter) - { - LLDrawable* light_drawable = *iter; - LLVOVolume* light = light_drawable->getVOVolume(); - if (!light) - { - continue; - } - LLColor4 light_color; - light->calcLightAtPoint(*vertex, *normal, light_color); - color += light_color; - } - - color.mV[3] = 1.0f; - } - colorp->setVecScaleClamp(color); -} - -BOOL LLVOSurfacePatch::updateShadows(BOOL use_shadow_factor) -{ - return FALSE; //terrain updates its shadows during standard relight -} - void LLVOSurfacePatch::setPatch(LLSurfacePatch *patchp) { mPatchp = patchp; @@ -966,16 +927,18 @@ void LLVOSurfacePatch::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax U32 LLVOSurfacePatch::getPartitionType() const { - return LLPipeline::PARTITION_TERRAIN; + return LLViewerRegion::PARTITION_TERRAIN; } LLTerrainPartition::LLTerrainPartition() : LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK) { + mOcclusionEnabled = FALSE; mRenderByGroup = FALSE; + mInfiniteFarClip = FALSE; mBufferUsage = GL_DYNAMIC_DRAW_ARB; mDrawableType = LLPipeline::RENDER_TYPE_TERRAIN; - mPartitionType = LLPipeline::PARTITION_TERRAIN; + mPartitionType = LLViewerRegion::PARTITION_TERRAIN; } LLVertexBuffer* LLTerrainPartition::createVertexBuffer(U32 type_mask, U32 usage) @@ -985,6 +948,8 @@ LLVertexBuffer* LLTerrainPartition::createVertexBuffer(U32 type_mask, U32 usage) void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { + LLFastTimer ftm(LLFastTimer::FTM_REBUILD_TERRAIN_VB); + LLVertexBuffer* buffer = group->mVertexBuffer; //get vertex buffer striders @@ -993,7 +958,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) LLStrider texcoords2; LLStrider texcoords; LLStrider colors; - LLStrider indices; + LLStrider indices; buffer->getVertexStrider(vertices); buffer->getNormalStrider(normals); @@ -1020,6 +985,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) index_offset += facep->getGeomCount(); } + buffer->setBuffer(0); mFaceList.clear(); } diff --git a/linden/indra/newview/llvosurfacepatch.h b/linden/indra/newview/llvosurfacepatch.h index 024ccfd..52c11c9 100644 --- a/linden/indra/newview/llvosurfacepatch.h +++ b/linden/indra/newview/llvosurfacepatch.h @@ -42,6 +42,8 @@ class LLVector2; class LLVOSurfacePatch : public LLStaticViewerObject { public: + static F32 sLODFactor; + enum { VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) | @@ -69,7 +71,7 @@ public: LLStrider &colorsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp); + LLStrider &indicesp); /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area @@ -99,8 +101,6 @@ protected: S32 mLastStride; S32 mLastLength; - void calcColor(const LLVector3* vertex, const LLVector3* normal, LLColor4U* colorp); - BOOL updateShadows(BOOL use_shadow_factor = FALSE); void getGeomSizesMain(const S32 stride, S32 &num_vertices, S32 &num_indices); void getGeomSizesNorth(const S32 stride, const S32 north_stride, S32 &num_vertices, S32 &num_indices); @@ -113,7 +113,7 @@ protected: LLStrider &colorsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, + LLStrider &indicesp, U32 &index_offset); void updateNorthGeometry(LLFace *facep, LLStrider &verticesp, @@ -121,7 +121,7 @@ protected: LLStrider &colorsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, + LLStrider &indicesp, U32 &index_offset); void updateEastGeometry(LLFace *facep, LLStrider &verticesp, @@ -129,7 +129,7 @@ protected: LLStrider &colorsp, LLStrider &texCoords0p, LLStrider &texCoords1p, - LLStrider &indicesp, + LLStrider &indicesp, U32 &index_offset); }; diff --git a/linden/indra/newview/llvotextbubble.cpp b/linden/indra/newview/llvotextbubble.cpp index dabcecb..d4af0da 100644 --- a/linden/indra/newview/llvotextbubble.cpp +++ b/linden/indra/newview/llvotextbubble.cpp @@ -45,6 +45,7 @@ #include "llviewerimagelist.h" #include "llvolume.h" #include "pipeline.h" +#include "llviewerregion.h" LLVOTextBubble::LLVOTextBubble(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) : LLAlphaObject(id, pcode, regionp) @@ -236,7 +237,7 @@ void LLVOTextBubble::getGeometry(S32 idx, LLStrider& normalsp, LLStrider& texcoordsp, LLStrider& colorsp, - LLStrider& indicesp) + LLStrider& indicesp) { if (idx == 0 || idx == 2) { @@ -265,5 +266,5 @@ void LLVOTextBubble::getGeometry(S32 idx, U32 LLVOTextBubble::getPartitionType() const { - return LLPipeline::PARTITION_PARTICLE; + return LLViewerRegion::PARTITION_PARTICLE; } diff --git a/linden/indra/newview/llvotextbubble.h b/linden/indra/newview/llvotextbubble.h index e8b44b7..5f83f56 100644 --- a/linden/indra/newview/llvotextbubble.h +++ b/linden/indra/newview/llvotextbubble.h @@ -54,7 +54,7 @@ public: LLStrider& normalsp, LLStrider& texcoordsp, LLStrider& colorsp, - LLStrider& indicesp); + LLStrider& indicesp); virtual U32 getPartitionType() const; diff --git a/linden/indra/newview/llvotree.cpp b/linden/indra/newview/llvotree.cpp index af68a7a..4630127 100644 --- a/linden/indra/newview/llvotree.cpp +++ b/linden/indra/newview/llvotree.cpp @@ -44,7 +44,6 @@ #include "object_flags.h" #include "llagent.h" -#include "llcylinder.h" #include "lldrawable.h" #include "llface.h" #include "llviewercamera.h" @@ -54,11 +53,17 @@ #include "llworld.h" #include "noise.h" #include "pipeline.h" +#include "llspatialpartition.h" #include "llviewerwindow.h" extern LLPipeline gPipeline; -LLGLuint mLeafDList; +const S32 MAX_SLICES = 32; +const F32 LEAF_LEFT = 0.52f; +const F32 LEAF_RIGHT = 0.98f; +const F32 LEAF_TOP = 1.0f; +const F32 LEAF_BOTTOM = 0.52f; +const F32 LEAF_WIDTH = 1.f; S32 LLVOTree::sLODVertexOffset[4]; S32 LLVOTree::sLODVertexCount[4]; @@ -310,7 +315,6 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys, if (mTreeImagep) { mTreeImagep->bindTexture(0); - mTreeImagep->setClamp(TRUE, TRUE); } mBranchLength = sSpeciesTable[mSpecies]->mBranchLength; mTrunkLength = sSpeciesTable[mSpecies]->mTrunkLength; @@ -447,16 +451,9 @@ const S32 LEAF_VERTICES = 16; BOOL LLVOTree::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TREE); + const F32 SRR3 = 0.577350269f; // sqrt(1/3) + const F32 SRR2 = 0.707106781f; // sqrt(1/2) U32 i, j; - const S32 MAX_SLICES = 32; - - const F32 LEAF_LEFT = 0.52f; - const F32 LEAF_RIGHT = 0.98f; - const F32 LEAF_TOP = 1.0f; - const F32 LEAF_BOTTOM = 0.52f; - - const F32 LEAF_WIDTH = 1.f; - U32 slices = MAX_SLICES; @@ -483,7 +480,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) LLStrider vertices; LLStrider normals; LLStrider tex_coords; - LLStrider indicesp; + LLStrider indicesp; face->setSize(max_vertices, max_indices); @@ -499,23 +496,22 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) S32 index_count = 0; // First leaf - for (i = 0; i < 4; i++) - { - *(normals++) = LLVector3(0.f, 0.f, 1.f); - } - + *(normals++) = LLVector3(-SRR2, -SRR2, 0.f); *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM); *(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 0.f); vertex_count++; + *(normals++) = LLVector3(SRR3, -SRR3, SRR3); *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP); *(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 1.f); vertex_count++; - *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); + *(normals++) = LLVector3(-SRR3, -SRR3, SRR3); + *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); *(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 1.f); vertex_count++; + *(normals++) = LLVector3(SRR2, -SRR2, 0.f); *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM); *(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 0.f); vertex_count++; @@ -536,26 +532,22 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) index_count++; // Same leaf, inverse winding/normals - for (i = 0; i < 4; i++) - { - *(normals++) = LLVector3(0.f, 0.f, 1.f); - } - + *(normals++) = LLVector3(-SRR2, SRR2, 0.f); *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM); *(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 0.f); vertex_count++; - //*(tex_coords++) = LLVector2(1.f, 1.0f); + *(normals++) = LLVector3(SRR3, SRR3, SRR3); *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP); *(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 1.f); vertex_count++; - //*(tex_coords++) = LLVector2(0.52f, 1.0f); + *(normals++) = LLVector3(-SRR3, SRR3, SRR3); *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); *(vertices++) = LLVector3(-0.5f*LEAF_WIDTH, 0.f, 1.f); vertex_count++; - //*(tex_coords++) = LLVector2(1.f, 0.52f); + *(normals++) = LLVector3(SRR2, SRR2, 0.f); *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM); *(vertices++) = LLVector3(0.5f*LEAF_WIDTH, 0.f, 0.f); vertex_count++; @@ -575,23 +567,23 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) index_count++; - for (i = 0; i < 4; i++) - { - *(normals++) = LLVector3(0.f, 0.f, 1.f); - } - + // next leaf + *(normals++) = LLVector3(SRR2, -SRR2, 0.f); *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM); *(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 0.f); vertex_count++; + *(normals++) = LLVector3(SRR3, SRR3, SRR3); *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP); *(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 1.f); vertex_count++; - *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); + *(normals++) = LLVector3(SRR3, -SRR3, SRR3); + *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); *(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 1.f); vertex_count++; + *(normals++) = LLVector3(SRR2, SRR2, 0.f); *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM); *(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 0.f); vertex_count++; @@ -610,28 +602,28 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) *(indicesp++) = 9; index_count++; - for (i = 0; i < 4; i++) - { - *(normals++) = LLVector3(0.f, 0.f, 1.f); - } + // other side of same leaf + *(normals++) = LLVector3(-SRR2, -SRR2, 0.f); *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM); *(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 0.f); vertex_count++; + *(normals++) = LLVector3(-SRR3, SRR3, SRR3); *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP); *(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 1.f); vertex_count++; - *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); + *(normals++) = LLVector3(-SRR3, -SRR3, SRR3); + *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP); *(vertices++) = LLVector3(0.f, -0.5f*LEAF_WIDTH, 1.f); vertex_count++; + *(normals++) = LLVector3(-SRR2, SRR2, 0.f); *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM); *(vertices++) = LLVector3(0.f, 0.5f*LEAF_WIDTH, 0.f); vertex_count++; - *(indicesp++) = 12; index_count++; *(indicesp++) = 14; @@ -786,13 +778,14 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) slices /= 2; } + face->mVertexBuffer->setBuffer(0); llassert(vertex_count == max_vertices); llassert(index_count == max_indices); return TRUE; } -U32 LLVOTree::drawBranchPipeline(U32* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth, F32 scale, F32 twist, F32 droop, F32 branches, F32 alpha) +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; // @@ -810,7 +803,7 @@ U32 LLVOTree::drawBranchPipeline(U32* indicesp, S32 trunk_LOD, S32 stop_level, U constant_twist = 360.f/branches; - if (stop_level >= 0) + if (!LLPipeline::sReflectionRender && stop_level >= 0) { // // Draw the tree using recursion @@ -820,39 +813,46 @@ U32 LLVOTree::drawBranchPipeline(U32* indicesp, S32 trunk_LOD, S32 stop_level, U { llassert(sLODIndexCount[trunk_LOD] > 0); width = scale * length * aspect; - glPushMatrix(); - glScalef(width,width,scale * length); - glDrawElements(GL_TRIANGLES, sLODIndexCount[trunk_LOD], GL_UNSIGNED_INT, indicesp + sLODIndexOffset[trunk_LOD]); - /*glDrawRangeElements(GL_TRIANGLES, - sLODVertexOffset[trunk_LOD], - sLODVertexOffset[trunk_LOD] + sLODVertexCount[trunk_LOD]-1, - sLODIndexCount[trunk_LOD], - GL_UNSIGNED_INT, - indicesp + sLODIndexOffset[trunk_LOD]);*/ + 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; + + glLoadMatrixf((F32*) scale_mat.mMatrix); + glDrawElements(GL_TRIANGLES, sLODIndexCount[trunk_LOD], GL_UNSIGNED_SHORT, indicesp + sLODIndexOffset[trunk_LOD]); + stop_glerror(); ret += sLODIndexCount[trunk_LOD]; - glPopMatrix(); } // Recurse to create more branches for (S32 i=0; i < (S32)branches; i++) { - glPushMatrix(); - glTranslatef(0.f, 0.f, scale * length); - glRotatef((constant_twist + ((i%2==0)?twist:-twist))*i, 0.f, 0.f, 1.f); - glRotatef(droop, 0.f, 1.f, 0.f); - glRotatef(20.f, 0.f, 0.f, 1.f); // rotate 20deg about axis of new branch to add some random variation - ret += drawBranchPipeline(indicesp, trunk_LOD, stop_level, depth - 1, 0, scale*mScaleStep, twist, droop, branches, alpha); - glPopMatrix(); + 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) { - glPushMatrix(); - glTranslatef(0.f, 0.f, scale * length); - glRotatef(70.5f, 0.f, 0.f, 1.f); // rotate a bit around Z when ascending - ret += drawBranchPipeline(indicesp, trunk_LOD, stop_level, depth, trunk_depth-1, scale*mScaleStep, twist, droop, branches, alpha); - glPopMatrix(); + 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 @@ -861,21 +861,19 @@ U32 LLVOTree::drawBranchPipeline(U32* indicesp, S32 trunk_LOD, S32 stop_level, U // Draw leaves as two 90 deg crossed quads with leaf textures // { - glPushMatrix(); - //glRotatef(llFrand(50.0), llFrand(1.0), llFrand(1.0), llFrand(1.0); - //width = scale * (TREE_BRANCH_ASPECT + TREE_LEAF_ASPECT); - glScalef(scale*mLeafScale, scale*mLeafScale, scale*mLeafScale); - //glScalef(1.5f*width*mLeafScale,1,1.5f*scale*mLeafScale); - glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_INT, indicesp); - /*glDrawRangeElements(GL_TRIANGLES, - 0, - LEAF_VERTICES-1, - LEAF_INDICES, - GL_UNSIGNED_INT, - indicesp);*/ + LLMatrix4 scale_mat; + scale_mat.mMatrix[0][0] = + scale_mat.mMatrix[1][1] = + scale_mat.mMatrix[2][2] = scale*mLeafScale; + + scale_mat *= matrix; + + + glLoadMatrixf((F32*) scale_mat.mMatrix); + glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp); + stop_glerror(); ret += LEAF_INDICES; - glPopMatrix(); } } } @@ -885,26 +883,25 @@ U32 LLVOTree::drawBranchPipeline(U32* indicesp, S32 trunk_LOD, S32 stop_level, U // 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; + glMatrixMode(GL_TEXTURE); - glPushMatrix(); glTranslatef(0.0, -0.5, 0.0); glMatrixMode(GL_MODELVIEW); - { - glPushMatrix(); - glScalef(mBillboardScale*mBillboardRatio, mBillboardScale*mBillboardRatio, mBillboardScale); - glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_INT, indicesp); -/* glDrawRangeElements(GL_TRIANGLES, - 0, - LEAF_VERTICES-1, - LEAF_INDICES, - GL_UNSIGNED_INT, - indicesp);*/ - stop_glerror(); - ret += LEAF_INDICES; - glPopMatrix(); - } + + glLoadMatrixf((F32*) scale_mat.mMatrix); + glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp); + + stop_glerror(); + ret += LEAF_INDICES; + glMatrixMode(GL_TEXTURE); - glPopMatrix(); + glLoadIdentity(); glMatrixMode(GL_MODELVIEW); } @@ -923,18 +920,22 @@ void LLVOTree::updateRadius() void LLVOTree::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax) { + F32 radius = getScale().magVec()*0.05f; LLVector3 center = getRenderPosition(); - LLVector3 size = getScale(); - center.mV[2] += size.mV[2]; + F32 sz = mBillboardScale*mBillboardRatio*radius*0.5f; + LLVector3 size(sz,sz,sz); + + center += LLVector3(0, 0, size.mV[2]) * getRotation(); + newMin.setVec(center-size); newMax.setVec(center+size); - mDrawable->setPositionGroup((newMin + newMax) * 0.5f); + mDrawable->setPositionGroup(center); } U32 LLVOTree::getPartitionType() const { - return LLPipeline::PARTITION_TREE; + return LLViewerRegion::PARTITION_TREE; } LLTreePartition::LLTreePartition() @@ -942,7 +943,7 @@ LLTreePartition::LLTreePartition() { mRenderByGroup = FALSE; mDrawableType = LLPipeline::RENDER_TYPE_TREE; - mPartitionType = LLPipeline::PARTITION_TREE; + mPartitionType = LLViewerRegion::PARTITION_TREE; mSlopRatio = 0.f; mLODPeriod = 1; } diff --git a/linden/indra/newview/llvotree.h b/linden/indra/newview/llvotree.h index 1c17e53..180e5b0 100644 --- a/linden/indra/newview/llvotree.h +++ b/linden/indra/newview/llvotree.h @@ -78,10 +78,8 @@ public: void updateRadius(); - U32 drawBranchPipeline(U32* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth, F32 scale, F32 twist, F32 droop, F32 branches, 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); - void drawBranch(S32 stop_level, U16 depth, U16 trunk_depth, F32 scale, F32 twist, F32 droop, F32 branches, F32 alpha, BOOL draw_leaves); - static S32 sMaxTreeSpecies; struct TreeSpeciesData diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp index ff6c502..494e0fa 100644 --- a/linden/indra/newview/llvovolume.cpp +++ b/linden/indra/newview/llvovolume.cpp @@ -48,14 +48,13 @@ #include "object_flags.h" #include "llagent.h" #include "lldrawable.h" -#include "lldrawpoolsimple.h" #include "lldrawpoolbump.h" #include "llface.h" +#include "llspatialpartition.h" // TEMP HACK ventrella #include "llhudmanager.h" #include "llflexibleobject.h" -#include "llanimalcontrols.h" #include "llsky.h" #include "llviewercamera.h" @@ -88,9 +87,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mRelativeXformInvTrans.identity(); mLOD = MIN_LOD; - mInited = FALSE; mTextureAnimp = NULL; - mGlobalVolume = FALSE; mVObjRadius = LLVector3(1,1,0.5f).magVec(); mNumFaces = 0; mLODChanged = FALSE; @@ -296,6 +293,8 @@ void LLVOVolume::animateTextures() for (S32 i = start; i <= end; i++) { LLFace* facep = mDrawable->getFace(i); + if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue; + const LLTextureEntry* te = facep->getTextureEntry(); if (!te) @@ -321,7 +320,12 @@ void LLVOVolume::animateTextures() LLQuaternion quat; quat.setQuat(rot, 0, 0, -1.f); - LLMatrix4& tex_mat = facep->mTextureMatrix; + if (!facep->mTextureMatrix) + { + facep->mTextureMatrix = new LLMatrix4(); + } + + LLMatrix4& tex_mat = *facep->mTextureMatrix; tex_mat.identity(); tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); tex_mat.rotate(quat); @@ -402,7 +406,6 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) void LLVOVolume::updateTextures(LLAgent &agent) { -// LLFastTimer t(LLFastTimer::FTM_TEMP6); const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) { @@ -460,6 +463,29 @@ void LLVOVolume::updateTextures() } mPixelArea = llmax(mPixelArea, face->getPixelArea()); + + F32 old_size = face->getVirtualSize(); + + if (face->getPoolType() == LLDrawPool::POOL_ALPHA) + { + + if (LLPipeline::sFastAlpha && + vsize < MIN_ALPHA_SIZE && old_size > MIN_ALPHA_SIZE || + vsize > MIN_ALPHA_SIZE && old_size < MIN_ALPHA_SIZE) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_COLOR, FALSE); + } + } + + if (face->mTextureMatrix != NULL) + { + if (vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE || + vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD, FALSE); + } + } + face->setVirtualSize(vsize); imagep->addTextureStats(vsize); if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) @@ -492,10 +518,12 @@ void LLVOVolume::updateTextures() mSculptTexture->setBoostLevel(LLViewerImage::BOOST_SCULPTED); } - S32 desired_discard = 0; // lower discard levels have MUCH less resolution - (old=MAX_LOD - mLOD) + S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture S32 current_discard = getVolume()->getSculptLevel(); - - if (desired_discard != current_discard) + + if (texture_discard >= 0 && //texture has some data available + (texture_discard < current_discard || //texture has more data than last rebuild + current_discard < 0)) //no previous rebuild { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE); mSculptChanged = TRUE; @@ -555,20 +583,13 @@ F32 LLVOVolume::getTextureVirtualSize(LLFace* face) BOOL LLVOVolume::isActive() const { - return !mStatic || mTextureAnimp || isAttachment() || (mVolumeImpl && mVolumeImpl->isActive()); + return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()); } BOOL LLVOVolume::setMaterial(const U8 material) { BOOL res = LLViewerObject::setMaterial(material); - if (res) - { - // for deprecated LL_MCODE_LIGHT - if (mDrawable.notNull()) - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_LIGHTING, TRUE); - } - } + return res; } @@ -608,14 +629,13 @@ LLFace* LLVOVolume::addFace(S32 f) LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) { pipeline->allocDrawable(this); + mDrawable->setRenderType(LLPipeline::RENDER_TYPE_VOLUME); S32 max_tes_to_set = getNumTEs(); for (S32 i = 0; i < max_tes_to_set; i++) { - LLFace* face = addFace(i); - // JC - should there be a setViewerObject(this) call here? - face->setTEOffset(i); + addFace(i); } mNumFaces = max_tes_to_set; @@ -666,8 +686,6 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail } } - mGlobalVolume = (mVolumeImpl && mVolumeImpl->isVolumeGlobal()); - if ((LLPrimitive::setVolume(volume_params, mLOD, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged) { mFaceMappingChanged = TRUE; @@ -728,13 +746,16 @@ void LLVOVolume::sculpt() return; LLPointer raw_image = new LLImageRaw(); - mSculptTexture->readBackRaw(discard_level, raw_image, TRUE); + mSculptTexture->readBackRaw(discard_level, raw_image, FALSE); sculpt_height = raw_image->getHeight(); sculpt_width = raw_image->getWidth(); sculpt_components = raw_image->getComponents(); sculpt_data = raw_image->getData(); + + llassert_always(raw_image->getDataSize() >= sculpt_height * sculpt_width * sculpt_components); + getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level); } } @@ -742,9 +763,16 @@ void LLVOVolume::sculpt() S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius) { S32 cur_detail; - // We've got LOD in the profile, and in the twist. Use radius. - F32 tan_angle = (LLVOVolume::sLODFactor*radius)/distance; - cur_detail = LLVolumeLODGroup::getDetailFromTan(llround(tan_angle, 0.01f)); + if (LLPipeline::sDynamicLOD) + { + // We've got LOD in the profile, and in the twist. Use radius. + F32 tan_angle = (LLVOVolume::sLODFactor*radius)/distance; + cur_detail = LLVolumeLODGroup::getDetailFromTan(llround(tan_angle, 0.01f)); + } + else + { + cur_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3); + } return cur_detail; } @@ -755,6 +783,9 @@ BOOL LLVOVolume::calcLOD() return FALSE; } + //update face texture sizes on lod calculation + updateTextures(); + S32 cur_detail = 0; F32 radius = getVolume()->mLODScaleBias.scaledVec(getScale()).magVec(); @@ -860,12 +891,14 @@ void LLVOVolume::updateFaceFlags() void LLVOVolume::setParent(LLViewerObject* parent) { - LLViewerObject::setParent(parent); - if (mDrawable) + if (parent != getParent()) { - gPipeline.markMoved(mDrawable); - mVolumeChanged = TRUE; - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); + LLViewerObject::setParent(parent); + if (mDrawable) + { + gPipeline.markMoved(mDrawable); + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); + } } } @@ -909,7 +942,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) LLFace *face = mDrawable->getFace(i); res &= face->genVolumeBBoxes(*getVolume(), i, mRelativeXform, mRelativeXformInvTrans, - mGlobalVolume | force_global); + (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); if (rebuild) { @@ -939,8 +972,6 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) { mDrawable->setSpatialExtents(min,max); mDrawable->setPositionGroup((min+max)*0.5f); - //bounding boxes changed, update texture priorities - updateTextures(); } updateRadius(); @@ -949,6 +980,14 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) return res; } +void LLVOVolume::preRebuild() +{ + if (mVolumeImpl != NULL) + { + mVolumeImpl->preRebuild(); + } +} + void LLVOVolume::updateRelativeXform() { if (mVolumeImpl) @@ -1012,8 +1051,8 @@ void LLVOVolume::updateRelativeXform() rot *= mParent->getRotation(); } - LLViewerRegion* region = getRegion(); - pos += region->getOriginAgent(); + //LLViewerRegion* region = getRegion(); + //pos += region->getOriginAgent(); LLVector3 x_axis = LLVector3(scale.mV[VX], 0.f, 0.f) * rot; LLVector3 y_axis = LLVector3(0.f, scale.mV[VY], 0.f) * rot; @@ -1045,12 +1084,17 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) if (mVolumeImpl != NULL) { - LLFastTimer t(LLFastTimer::FTM_GEN_FLEX); - BOOL res = mVolumeImpl->doUpdateGeometry(drawable); + BOOL res; + { + LLFastTimer t(LLFastTimer::FTM_GEN_FLEX); + res = mVolumeImpl->doUpdateGeometry(drawable); + } updateFaceFlags(); return res; } + dirtySpatialGroup(); + BOOL compiled = FALSE; updateRelativeXform(); @@ -1063,7 +1107,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) if (mVolumeChanged || mFaceMappingChanged ) { compiled = TRUE; - mInited = TRUE; if (mVolumeChanged) { @@ -1248,6 +1291,17 @@ S32 LLVOVolume::setTEMediaFlags(const U8 te, const U8 media_flags) return res; } +S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow) +{ + S32 res = LLViewerObject::setTEGlow(te, glow); + if (res) + { + gPipeline.markTextured(mDrawable); + mFaceMappingChanged = TRUE; + } + return res; +} + S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t) { S32 res = LLViewerObject::setTEScale(te, s, t); @@ -1314,12 +1368,6 @@ void LLVOVolume::setIsLight(BOOL is_light) { // Not a light. Remove it from the pipeline's light set. gPipeline.setLight(mDrawable, FALSE); - - // Remove this object from any object which has it as a light - if (mDrawable) - { - mDrawable->clearLightSet(); - } } } } @@ -1476,92 +1524,6 @@ F32 LLVOVolume::getLightCutoff() const } } -//---------------------------------------------------------------------------- - -// returns < 0 if inside radius -F32 LLVOVolume::getLightDistance(const LLVector3& pos) const -{ - LLVector3 dpos = getRenderPosition() - pos; - F32 dist = dpos.magVec() - getLightRadius(); - return dist; -} - -// returns intensity, modifies color in result -F32 LLVOVolume::calcLightAtPoint(const LLVector3& pos, const LLVector3& norm, LLColor4& result) -{ - if (!getIsLight()) - { - return 0.0f; - } - F32 light_radius = getLightRadius(); - LLVector3 light_pos = getRenderPosition(); - LLVector3 light_dir = light_pos - pos; - F32 dist = light_dir.normVec(); - F32 dp = norm * light_dir; - if ((gPipeline.getLightingDetail() > 2)) - { - if (dp <= 0) - { - result *= 0; - return 0; - } - - if (dist >= light_radius) - { - result *= 0; - return 0; - } - - F32 mag = 1.0f-(dist/light_radius); - mag = powf(mag, 0.75f); - mag *= dp; - result = getLightColor() * mag; - return mag; - } - else - { - F32 light_radius = getLightRadius(); - LLVector3 light_pos = getRenderPosition(); - LLVector3 light_dir = light_pos - pos; - F32 dist = light_dir.normVec(); - F32 dp = norm * light_dir; - F32 atten = (1.f/.2f) / (light_radius); // 20% of brightness at radius - F32 falloff = 1.f / (dist * atten); - F32 mag = falloff * dp; - mag = llmax(mag, 0.0f); - result = getLightColor() * mag; - return mag; - } -} - -BOOL LLVOVolume::updateLighting(BOOL do_lighting) -{ - LLMemType mt1(LLMemType::MTYPE_DRAWABLE); -#if 0 - if (mDrawable->isStatic()) - { - do_lighting = FALSE; - } - - const LLMatrix4& mat_vert = mDrawable->getWorldMatrix(); - const LLMatrix3& mat_normal = LLMatrix3(mDrawable->getWorldRotation()); - - LLVolume* volume = getVolume(); - - for (S32 i = 0; i < volume->getNumFaces(); i++) - { - LLFace *face = mDrawable->getFace(i); - if (face && face->getGeomCount()) - { - face->genLighting(volume, mDrawable, i, i, mat_vert, mat_normal, do_lighting); - } - } -#endif - return TRUE; -} - -//---------------------------------------------------------------------------- - U32 LLVOVolume::getVolumeInterfaceID() const { if (mVolumeImpl) @@ -1576,7 +1538,8 @@ BOOL LLVOVolume::isFlexible() const { if (getParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE)) { - if (getVolume()->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE) + LLVolume* volume = getVolume(); + if (volume && volume->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE) { LLVolumeParams volume_params = getVolume()->getParams(); U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); @@ -1684,7 +1647,13 @@ void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_p } updateRelativeXform(); - volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, nodep->mSilhouetteSegments, view_vector, mRelativeXform, mRelativeXformInvTrans); + LLMatrix4 trans_mat = mRelativeXform; + if (mDrawable->isStatic()) + { + trans_mat.translate(getRegion()->getOriginAgent()); + } + + volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, nodep->mSilhouetteSegments, view_vector, trans_mat, mRelativeXformInvTrans); nodep->mSilhouetteExists = TRUE; } @@ -1744,137 +1713,6 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const return mDrawable->getWorldMatrix(); } -void LLVOVolume::writeCAL3D(apr_file_t* fp, std::string& path, std::string& file_base, S32 joint_num, LLVector3& pos, LLQuaternion& rot, S32& material_index, S32& texture_index, std::multimap& material_map) -{ -#if 0 - LLImageTGA tga_image; - - if (mDrawable.isNull()) - { - return; - } - - LLVector3 final_pos = getPosition(); - final_pos *= 100.f; - - final_pos = final_pos * rot; - final_pos += pos; - LLQuaternion final_rot; - final_rot = getRotation() * rot; - LLMatrix4 transform; - transform.initAll(getScale(), final_rot, final_pos); - - LLMatrix4 int_transpose_transform; - int_transpose_transform.initAll(LLVector3(1.f / getScale().mV[VX], 1.f / getScale().mV[VY], 1.f / getScale().mV[VZ]), final_rot, LLVector3::zero); - - for (S32 i = 0; i < mDrawable->getNumFaces(); i++) - { - S32 vert_num = 0; - LLFace* facep = mDrawable->getFace(i); - LLDrawPool* poolp = facep->getPool(); - - const LLTextureEntry* tep = facep->getTextureEntry(); - if (!tep) - { - continue; - } - - S32 my_material = -1; - S32 my_texture = -1; - LLColor4 face_color = tep->getColor(); - - typedef std::multimap::iterator material_it_t; - std::pair found_range = material_map.equal_range(tep->getID()); - material_it_t material_it = found_range.first; - - LLMaterialExportInfo* material_info = NULL; - - while(material_it != material_map.end() && material_it != found_range.second) - { - // we've at least found a matching texture, so reuse it - my_texture = material_it->second->mTextureIndex; - if (material_it->second->mColor == face_color) - { - // we've found a matching material - material_info = material_it->second; - } - ++material_it; - } - - if (material_info) - { - // material already exported, just reuse it - my_material = material_info->mMaterialIndex; - my_texture = material_info->mTextureIndex; - } - else - { - // reserve new material number - my_material = material_index++; - - // if we didn't already find a matching texture... - if (my_texture == -1) - { - //...use the next available slot... - my_texture = texture_index++; - - //...and export texture as image file - char filename[MAX_PATH]; /* Flawfinder: ignore */ - snprintf(filename, MAX_PATH, "%s\\%s_material_tex_%d.tga", path.c_str(), file_base.c_str(), my_texture); /* Flawfinder: ignore */ - - LLViewerImage* imagep = facep->getTexture(); - if (imagep->getTexName() == 0) - { - llinfos << "No image data available for " << filename << llendl; - continue; - } - LLImageRaw raw_image; - imagep->readBackRaw(-1, raw_image); - BOOL success = tga_image.encode(raw_image); - success = tga_image.save(filename); - } - - material_info = new LLMaterialExportInfo(my_material, my_texture, face_color); - material_map.insert(std::make_pair(tep->getID(), material_info)); - } - - apr_file_printf(fp, "\t\n", - facep->getGeomCount(), facep->getIndicesCount() / 3, my_material); - - for (S32 vert_index = 0; vert_index < facep->getGeomCount(); vert_index++) - { - LLVector3 vert_pos = poolp->getVertex(facep->getGeomStart() + vert_index); - vert_pos *= 100.f; - vert_pos = vert_pos * transform; - LLVector3 vert_norm = poolp->getNormal(facep->getGeomStart() + vert_index); - vert_norm = vert_norm * int_transpose_transform; - LLVector2 vert_tc = poolp->getTexCoord(facep->getGeomStart() + vert_index, 0); - apr_file_printf(fp, " \n", vert_num++); - apr_file_printf(fp, " %.4f %.4f %.4f\n", vert_pos.mV[VX], vert_pos.mV[VY], vert_pos.mV[VZ]); - apr_file_printf(fp, " %.6f %.6f %.6f\n", vert_norm.mV[VX], vert_norm.mV[VY], vert_norm.mV[VZ]); - apr_file_printf(fp, " %.6f %.6f\n", vert_tc.mV[VX], 1.f - vert_tc.mV[VY]); - apr_file_printf(fp, " 1.0\n", joint_num + 1); - apr_file_printf(fp, " \n"); - } - - for (U32 index_i = 0; index_i < facep->getIndicesCount(); index_i += 3) - { - U32 index_a = poolp->getIndex(facep->getIndicesStart() + index_i) - facep->getGeomStart(); - U32 index_b = poolp->getIndex(facep->getIndicesStart() + index_i + 1) - facep->getGeomStart(); - U32 index_c = poolp->getIndex(facep->getIndicesStart() + index_i + 2) - facep->getGeomStart(); - apr_file_printf(fp, " \n", index_a, index_b, index_c); - } - - apr_file_printf(fp, " \n"); - } - - for (U32 i = 0; i < mChildList.size(); i++) - { - ((LLVOVolume*)(LLViewerObject*)mChildList[i])->writeCAL3D(fp, path, file_base, joint_num, final_pos, final_rot, material_index, texture_index, material_map); - } -#endif -} - //static void LLVOVolume::preUpdateGeom() { @@ -1908,7 +1746,7 @@ void LLVOVolume::setSelected(BOOL sel) LLViewerObject::setSelected(sel); if (mDrawable.notNull()) { - mDrawable->movePartition(); + markForUpdate(TRUE); } } @@ -1929,7 +1767,9 @@ F32 LLVOVolume::getBinRadius() { for (S32 i = 0; i < mDrawable->getNumFaces(); i++) { - if (mDrawable->getFace(i)->getPoolType() == LLDrawPool::POOL_ALPHA) + LLFace* face = mDrawable->getFace(i); + if (face->getPoolType() == LLDrawPool::POOL_ALPHA && + (!LLPipeline::sFastAlpha || face->getVirtualSize() > MIN_ALPHA_SIZE)) { alpha_wrap = TRUE; break; @@ -1954,7 +1794,14 @@ F32 LLVOVolume::getBinRadius() } else if (mDrawable->isStatic()) { - radius = 32.f; + if (mDrawable->getRadius() < 2.0f) + { + radius = 16.f; + } + else + { + radius = 32.f; + } } else { @@ -2049,10 +1896,10 @@ U32 LLVOVolume::getPartitionType() const { if (isHUDAttachment()) { - return LLPipeline::PARTITION_HUD; + return LLViewerRegion::PARTITION_HUD; } - return LLPipeline::PARTITION_VOLUME; + return LLViewerRegion::PARTITION_VOLUME; } LLVolumePartition::LLVolumePartition() @@ -2061,7 +1908,7 @@ LLVolumePartition::LLVolumePartition() mLODPeriod = 16; mDepthMask = FALSE; mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; - mPartitionType = LLPipeline::PARTITION_VOLUME; + mPartitionType = LLViewerRegion::PARTITION_VOLUME; mSlopRatio = 0.25f; mBufferUsage = GL_DYNAMIC_DRAW_ARB; mImageEnabled = TRUE; @@ -2073,7 +1920,7 @@ LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep) mDepthMask = FALSE; mLODPeriod = 16; mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; - mPartitionType = LLPipeline::PARTITION_BRIDGE; + mPartitionType = LLViewerRegion::PARTITION_BRIDGE; mBufferUsage = GL_DYNAMIC_DRAW_ARB; @@ -2099,50 +1946,47 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, type == LLRenderPass::PASS_ALPHA) ? facep->isState(LLFace::FULLBRIGHT) : FALSE; const LLMatrix4* tex_mat = NULL; - if (type != LLRenderPass::PASS_SHINY && facep->isState(LLFace::TEXTURE_ANIM)) + if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) + { + tex_mat = facep->mTextureMatrix; + } + + const LLMatrix4* model_mat = NULL; + + LLDrawable* drawable = facep->getDrawable(); + if (drawable->isActive()) + { + model_mat = &(drawable->getRenderMatrix()); + } + else { - tex_mat = &(facep->mTextureMatrix); + model_mat = &(drawable->getRegion()->mRenderMatrix); } U8 bump = (type == LLRenderPass::PASS_BUMP ? facep->getTextureEntry()->getBumpmap() : 0); - //LLViewerImage* tex = facep->mAppAngle < FORCE_SIMPLE_RENDER_ANGLE ? NULL : facep->getTexture(); LLViewerImage* tex = facep->getTexture(); + U8 glow = 0; + if (type == LLRenderPass::PASS_GLOW) { - U32 start = facep->getGeomIndex(); - U32 end = start + facep->getGeomCount()-1; - U32 offset = facep->getIndicesStart(); - U32 count = facep->getIndicesCount(); - LLPointer draw_info = new LLDrawInfo(start,end,count,offset,tex, - facep->mVertexBuffer, fullbright, bump); - draw_info->mVSize = facep->getVirtualSize(); - draw_vec.push_back(draw_info); - LLVOVolume* volume = (LLVOVolume*) facep->getViewerObject(); - BOOL is_light = volume->mDrawable->isLight(); - - U8 alpha = is_light ? 196 : 160; - LLColor3 col = is_light ? volume->getLightColor() : LLColor3(0,0,0); - LLColor4 col2 = facep->getRenderColor(); - draw_info->mGlowColor.setVec((U8) (col.mV[0]*col2.mV[0]*255), - (U8) (col.mV[1]*col2.mV[1]*255), - (U8) (col.mV[2]*col2.mV[2]*255), - alpha); - draw_info->mTextureMatrix = tex_mat; - validate_draw_info(*draw_info); + glow = (U8) (facep->getTextureEntry()->getGlow() * 255); } - else if (idx >= 0 && + + if (idx >= 0 && draw_vec[idx]->mVertexBuffer == facep->mVertexBuffer && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && - draw_vec[idx]->mTexture == tex && + (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex) && #if LL_DARWIN draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && #endif + draw_vec[idx]->mGlowColor.mV[3] == glow && draw_vec[idx]->mFullbright == fullbright && draw_vec[idx]->mBump == bump && - draw_vec[idx]->mTextureMatrix == tex_mat) + draw_vec[idx]->mTextureMatrix == tex_mat && + draw_vec[idx]->mModelMatrix == model_mat) { draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); @@ -2157,10 +2001,13 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 count = facep->getIndicesCount(); LLPointer draw_info = new LLDrawInfo(start,end,count,offset,tex, facep->mVertexBuffer, fullbright, bump); + draw_info->mGroup = group; draw_info->mVSize = facep->getVirtualSize(); draw_vec.push_back(draw_info); draw_info->mReflectionMap = group->mReflectionMap; draw_info->mTextureMatrix = tex_mat; + draw_info->mModelMatrix = model_mat; + draw_info->mGlowColor.setVec(0,0,0,glow); validate_draw_info(*draw_info); } } @@ -2172,6 +2019,11 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group) void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { + if (LLPipeline::sSkipUpdate) + { + return; + } + if (group->changeLOD()) { group->mLastUpdateDistance = group->mDistance; @@ -2182,6 +2034,60 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (!group->isState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY)) { + if (group->isState(LLSpatialGroup::MESH_DIRTY)) + { + group->mBuilt = 1.f; + LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO); + + LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB); + + for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) + { + LLDrawable* drawablep = *drawable_iter; + if (drawablep->isState(LLDrawable::REBUILD_ALL)) + { + LLVOVolume* vobj = drawablep->getVOVolume(); + vobj->preRebuild(); + LLVolume* volume = vobj->getVolume(); + for (S32 i = 0; i < drawablep->getNumFaces(); ++i) + { + LLFace* face = drawablep->getFace(i); + if (face && face->mVertexBuffer.notNull()) + { + face->getGeometryVolume(*volume, face->getTEOffset(), + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); + } + } + + drawablep->clearState(LLDrawable::REBUILD_ALL); + } + } + + //unmap all the buffers + for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i) + { + LLSpatialGroup::buffer_list_t& list = i->second; + for (LLSpatialGroup::buffer_list_t::iterator j = list.begin(); j != list.end(); ++j) + { + LLVertexBuffer* buffer = *j; + if (buffer->isLocked()) + { + buffer->setBuffer(0); + } + } + } + + // don't forget alpha + if( group != NULL && + !group->mVertexBuffer.isNull() && + group->mVertexBuffer->isLocked()) + { + group->mVertexBuffer->setBuffer(0); + } + + group->clearState(LLSpatialGroup::MESH_DIRTY); + } + return; } @@ -2191,7 +2097,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB); //find reflection map - if (group->mSpatialPartition->mImageEnabled) + if (group->mSpatialPartition->mImageEnabled && LLPipeline::sDynamicReflections) { if (group->mReflectionMap.isNull()) { @@ -2213,6 +2119,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) U32 index_count = 0; U32 useage = group->mSpatialPartition->mBufferUsage; + U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); + max_vertices = llmin(max_vertices, (U32) 65535); + //get all the faces into a list, putting alpha faces in their own list for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) { @@ -2229,6 +2138,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } LLVOVolume* vobj = drawablep->getVOVolume(); + vobj->updateTextures(); + vobj->preRebuild(); //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) @@ -2272,9 +2183,38 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (type == LLDrawPool::POOL_ALPHA) { - vertex_count += facep->getGeomCount(); - index_count += facep->getIndicesCount(); - alpha_faces.push_back(facep); + BOOL alpha_opt = LLPipeline::sFastAlpha && gPipeline.canUseWindLightShadersOnObjects() && facep->getVirtualSize() < MIN_ALPHA_SIZE; + + const LLColor4& col = facep->getTextureEntry()->getColor(); + + if (alpha_opt) + { //if we're applying the alpha optimization, only blend faces that have alpha (0.15, 0.5] + //for faces with alpha (0.5, 1.0], render with an alpha mask + //for faces with alpha [0.0, 0.15], don't render + if (col.mV[3] > 0.5f) + { + mFaceList.push_back(facep); + } + else if (col.mV[3] > 0.15f) + { + vertex_count += facep->getGeomCount(); + index_count += facep->getIndicesCount(); + alpha_faces.push_back(facep); + } + else + { //face has no renderable geometry + facep->mVertexBuffer = NULL; + facep->mLastVertexBuffer = NULL; + //don't alpha wrap drawables that have only tiny tiny alpha faces + facep->setPoolType(LLDrawPool::POOL_SIMPLE); + } + } + else + { + vertex_count += facep->getGeomCount(); + index_count += facep->getIndicesCount(); + alpha_faces.push_back(facep); + } } else { @@ -2291,47 +2231,60 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) facep->mLastVertexBuffer = NULL; //don't alpha wrap drawables that have only tiny tiny alpha faces facep->setPoolType(LLDrawPool::POOL_SIMPLE); - } - - vobj->updateTextures(); + } } } - group->mVertexCount = vertex_count; - group->mIndexCount = index_count; - group->mBufferUsage = useage; + U16 alpha_vertex_count = vertex_count > 65535 ? 65535 : vertex_count; + U32 alpha_index_count = index_count; - LLStrider vertices; - LLStrider normals; - LLStrider texcoords2; - LLStrider texcoords; - LLStrider colors; - LLStrider indices; + group->mBufferUsage = useage; //PROCESS NON-ALPHA FACES { - //sort faces by texture - std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareTextureAndTime()); - + //sort faces by things that break batches + std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareBatchBreaker()); + std::vector::iterator face_iter = mFaceList.begin(); LLSpatialGroup::buffer_map_t buffer_map; + LLViewerImage* last_tex = NULL; + U32 buffer_index = 0; + while (face_iter != mFaceList.end()) { //pull off next face LLFace* facep = *face_iter; LLViewerImage* tex = facep->getTexture(); + if (last_tex == tex) + { + buffer_index++; + } + else + { + last_tex = tex; + buffer_index = 0; + } + U32 index_count = facep->getIndicesCount(); U32 geom_count = facep->getGeomCount(); //sum up vertices needed for this texture std::vector::iterator i = face_iter; ++i; - while (i != mFaceList.end() && (*i)->getTexture() == tex) + + while (i != mFaceList.end() && + (LLPipeline::sTextureBindTest || (*i)->getTexture() == tex)) { facep = *i; + + if (geom_count + facep->getGeomCount() > max_vertices) + { //cut vertex buffers on geom count too big + break; + } + ++i; index_count += facep->getIndicesCount(); geom_count += facep->getGeomCount(); @@ -2342,9 +2295,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLSpatialGroup::buffer_map_t::iterator found_iter = group->mBufferMap.find(tex); if (found_iter != group->mBufferMap.end()) { - buffer = found_iter->second; + if (buffer_index < found_iter->second.size()) + { + buffer = found_iter->second[buffer_index]; + } } - + if (!buffer) { //create new buffer if needed buffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask, @@ -2365,21 +2321,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } - BOOL clean = TRUE; - buffer_map[tex] = buffer; + buffer_map[tex].push_back(buffer); //add face geometry - - //get vertex buffer striders - buffer->getVertexStrider(vertices); - buffer->getNormalStrider(normals); - buffer->getTexCoordStrider(texcoords); - buffer->getTexCoord2Strider(texcoords2); - buffer->getColorStrider(colors); - buffer->getIndexStrider(indices); U32 indices_index = 0; - U32 index_offset = 0; + U16 index_offset = 0; while (face_iter < i) { @@ -2393,60 +2340,82 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) facep->mGeomIndex = index_offset; facep->mVertexBuffer = buffer; { - if (facep->getGeometryVolume(*volume, te_idx, vertices, normals, texcoords, texcoords2, colors, indices, + if (facep->getGeometryVolume(*volume, te_idx, vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset)) { - clean = FALSE; buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(), facep->getIndicesStart(), facep->getIndicesCount()); } } + index_offset += facep->getGeomCount(); indices_index += facep->mIndicesCount; BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA; BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); const LLTextureEntry* te = facep->getTextureEntry(); - if (tex->getPrimaryFormat() == GL_ALPHA) - { - registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); - } - else if (fullbright) + BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE; + + if (!is_alpha + && gPipeline.canUseWindLightShadersOnObjects() + && LLPipeline::sRenderBump + && te->getShiny()) { - registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); + if (tex->getPrimaryFormat() == GL_ALPHA) + { + registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); + registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); + } + else if (fullbright) + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_SHINY); + } } else { - registerFace(group, facep, LLRenderPass::PASS_SIMPLE); - } - - facep->setPoolType(LLDrawPool::POOL_SIMPLE); - - if (te->getShiny()) - { - registerFace(group, facep, LLRenderPass::PASS_SHINY); + if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA) + { + registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); + } + else if (fullbright) + { + registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); + } + else + { + registerFace(group, facep, LLRenderPass::PASS_SIMPLE); + } + + if (!is_alpha && te->getShiny()) + { + registerFace(group, facep, LLRenderPass::PASS_SHINY); + } } - - if (!force_simple && te->getBumpmap()) + + if (!is_alpha) { - registerFace(group, facep, LLRenderPass::PASS_BUMP); + facep->setPoolType(LLDrawPool::POOL_SIMPLE); + + if (!force_simple && te->getBumpmap()) + { + registerFace(group, facep, LLRenderPass::PASS_BUMP); + } } - if (vobj->getIsLight() || - (LLPipeline::sRenderGlow && facep->isState(LLFace::FULLBRIGHT))) + if (LLPipeline::sRenderGlow && te->getGlow() > 0.f) { registerFace(group, facep, LLRenderPass::PASS_GLOW); } - - + ++face_iter; } - if (clean) - { - buffer->markClean(); - } + buffer->setBuffer(0); } group->mBufferMap.clear(); @@ -2467,33 +2436,31 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { group->mVertexBuffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask, group->mBufferUsage); - group->mVertexBuffer->allocateBuffer(group->mVertexCount, group->mIndexCount, true); + group->mVertexBuffer->allocateBuffer(alpha_vertex_count, alpha_index_count, true); stop_glerror(); } else { - group->mVertexBuffer->resizeBuffer(group->mVertexCount, group->mIndexCount); + group->mVertexBuffer->resizeBuffer(alpha_vertex_count, alpha_index_count); stop_glerror(); } //get vertex buffer striders LLVertexBuffer* buffer = group->mVertexBuffer; - BOOL clean = TRUE; - - buffer->getVertexStrider(vertices); - buffer->getNormalStrider(normals); - buffer->getTexCoordStrider(texcoords); - buffer->getTexCoord2Strider(texcoords2); - buffer->getColorStrider(colors); - buffer->getIndexStrider(indices); - U32 index_offset = 0; U32 indices_index = 0; for (std::vector::iterator i = alpha_faces.begin(); i != alpha_faces.end(); ++i) { LLFace* facep = *i; + + if (facep->mGeomCount + index_offset > 65535) + { //cut off alpha nodes at 64k vertices + facep->mVertexBuffer = NULL ; + continue ; + } + LLDrawable* drawablep = facep->getDrawable(); LLVOVolume* vobj = drawablep->getVOVolume(); LLVolume* volume = vobj->getVolume(); @@ -2502,30 +2469,33 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) facep->mIndicesIndex = indices_index; facep->mGeomIndex = index_offset; facep->mVertexBuffer = group->mVertexBuffer; - if (facep->getGeometryVolume(*volume, te_idx, vertices, normals, texcoords, texcoords2, colors, indices, - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset)) + if (facep->getGeometryVolume(*volume, te_idx, + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), + index_offset)) { - clean = FALSE; buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(), facep->getIndicesStart(), facep->getIndicesCount()); } + index_offset += facep->getGeomCount(); indices_index += facep->mIndicesCount; registerFace(group, facep, LLRenderPass::PASS_ALPHA); - } - if (clean) - { - buffer->markClean(); + if (LLPipeline::sRenderGlow && facep->getTextureEntry()->getGlow() > 0.f) + { + registerFace(group, facep, LLRenderPass::PASS_GLOW); + } } + + buffer->setBuffer(0); } else { group->mVertexBuffer = NULL; } - //get all the faces into a list, putting alpha faces in their own list + //drawables have been rebuilt, clear rebuild status for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) { LLDrawable* drawablep = *drawable_iter; @@ -2533,8 +2503,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } group->mLastUpdateTime = gFrameTimeSeconds; - group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MATRIX_DIRTY | - LLSpatialGroup::ALPHA_DIRTY); + group->mBuilt = 1.f; + group->clearState(LLSpatialGroup::GEOM_DIRTY | + LLSpatialGroup::ALPHA_DIRTY | LLSpatialGroup::MESH_DIRTY); mFaceList.clear(); } @@ -2589,7 +2560,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun LLHUDPartition::LLHUDPartition() { - mPartitionType = LLPipeline::PARTITION_HUD; + mPartitionType = LLViewerRegion::PARTITION_HUD; mDrawableType = LLPipeline::RENDER_TYPE_HUD; mSlopRatio = 0.f; mLODPeriod = 16; diff --git a/linden/indra/newview/llvovolume.h b/linden/indra/newview/llvovolume.h index 1250d4b..c3b25bf 100644 --- a/linden/indra/newview/llvovolume.h +++ b/linden/indra/newview/llvovolume.h @@ -33,7 +33,6 @@ #define LL_LLVOVOLUME_H #include "llviewerobject.h" -#include "llspatialpartition.h" #include "llviewerimage.h" #include "llframetimer.h" #include "llapr.h" @@ -67,6 +66,7 @@ public: virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const = 0; virtual void updateRelativeXform() = 0; virtual U32 getID() const = 0; + virtual void preRebuild() = 0; }; // Class which embodies all Volume objects (with pcode LL_PCODE_VOLUME) @@ -105,7 +105,6 @@ public: void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point); /*virtual*/ void setParent(LLViewerObject* parent); - F32 getIndividualRadius() { return mRadius; } S32 getLOD() const { return mLOD; } const LLVector3 getPivotPositionAgent() const; const LLMatrix4& getRelativeXform() const { return mRelativeXform; } @@ -147,6 +146,7 @@ public: /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny); /*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 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); @@ -168,19 +168,10 @@ public: void updateFaceFlags(); void regenFaces(); BOOL genBBoxes(BOOL force_global); + void preRebuild(); virtual void updateSpatialExtents(LLVector3& min, LLVector3& max); virtual F32 getBinRadius(); - virtual void writeCAL3D(apr_file_t* fp, - std::string& path, - std::string& file_base, - S32 joint_num, - LLVector3& pos, - LLQuaternion& rot, - S32& material_index, - S32& texture_index, - std::multimap& material_map); - - + virtual U32 getPartitionType() const; // For Lights @@ -197,8 +188,7 @@ public: F32 getLightRadius() const; F32 getLightFalloff() const; F32 getLightCutoff() const; - F32 getLightDistance(const LLVector3& pos) const; // returns < 0 if inside radius - + // Flexible Objects U32 getVolumeInterfaceID() const; virtual BOOL isFlexible() const; @@ -206,11 +196,7 @@ public: BOOL isVolumeGlobal() const; BOOL canBeFlexible() const; BOOL setIsFlexible(BOOL is_flexible); - - // Lighting - F32 calcLightAtPoint(const LLVector3& pos, const LLVector3& norm, LLColor4& result); - BOOL updateLighting(BOOL do_lighting); - + protected: S32 computeLODDetail(F32 distance, F32 radius); BOOL calcLOD(); @@ -220,17 +206,14 @@ protected: public: LLViewerTextureAnim *mTextureAnimp; U8 mTexAnimMode; -protected: +private: friend class LLDrawable; BOOL mFaceMappingChanged; - BOOL mGlobalVolume; - BOOL mInited; LLFrameTimer mTextureUpdateTimer; S32 mLOD; BOOL mLODChanged; BOOL mSculptChanged; - F32 mRadius; LLMatrix4 mRelativeXform; LLMatrix3 mRelativeXformInvTrans; BOOL mVolumeChanged; diff --git a/linden/indra/newview/llvowater.cpp b/linden/indra/newview/llvowater.cpp index 16bdc2f..1acda16 100644 --- a/linden/indra/newview/llvowater.cpp +++ b/linden/indra/newview/llvowater.cpp @@ -48,6 +48,7 @@ #include "llviewerregion.h" #include "llworld.h" #include "pipeline.h" +#include "llspatialpartition.h" const BOOL gUseRoam = FALSE; @@ -76,6 +77,7 @@ LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regi setScale(LLVector3(256.f, 256.f, 0.f)); // Hack for setting scale for bounding boxes/visibility. mUseTexture = TRUE; + mIsEdgePatch = FALSE; } @@ -106,14 +108,14 @@ void LLVOWater::updateTextures(LLAgent &agent) // Never gets called BOOL LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER))) + /*if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER))) { return TRUE; } - if (mDrawable) + if (mDrawable) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); - } + }*/ return TRUE; } @@ -149,23 +151,23 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) } face = drawable->getFace(0); - LLVector2 uvs[4]; - LLVector3 vtx[4]; +// LLVector2 uvs[4]; +// LLVector3 vtx[4]; LLStrider verticesp, normalsp; LLStrider texCoordsp; - LLStrider indicesp; - S32 index_offset; + LLStrider indicesp; + U16 index_offset; S32 size = 16; + S32 num_quads = size*size; + face->setSize(4*num_quads, 6*num_quads); + if (face->mVertexBuffer.isNull()) { - S32 num_quads = size*size; - face->setSize(4*num_quads, 6*num_quads); - face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); - face->mVertexBuffer->allocateBuffer(4*num_quads, 6*num_quads, TRUE); + face->mVertexBuffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); face->setIndicesIndex(0); face->setGeomIndex(0); } @@ -175,11 +177,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) } index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); - if (-1 == index_offset) - { - return TRUE; - } - + LLVector3 position_agent; position_agent = getPositionAgent(); face->mCenterAgent = position_agent; @@ -204,34 +202,20 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) position_agent.mV[VX] += (x + 0.5f) * step_x; position_agent.mV[VY] += (y + 0.5f) * step_y; - vtx[0] = position_agent - right + up; - vtx[1] = position_agent - right - up; - vtx[2] = position_agent + right + up; - vtx[3] = position_agent + right - up; - - *(verticesp++) = vtx[0]; - *(verticesp++) = vtx[1]; - *(verticesp++) = vtx[2]; - *(verticesp++) = vtx[3]; - - uvs[0].setVec(x*size_inv, (y+1)*size_inv); - uvs[1].setVec(x*size_inv, y*size_inv); - uvs[2].setVec((x+1)*size_inv, (y+1)*size_inv); - uvs[3].setVec((x+1)*size_inv, y*size_inv); - - *(texCoordsp) = uvs[0]; - texCoordsp++; - *(texCoordsp) = uvs[1]; - texCoordsp++; - *(texCoordsp) = uvs[2]; - texCoordsp++; - *(texCoordsp) = uvs[3]; - texCoordsp++; - - *(normalsp++) = normal; - *(normalsp++) = normal; - *(normalsp++) = normal; - *(normalsp++) = normal; + *verticesp++ = position_agent - right + up; + *verticesp++ = position_agent - right - up; + *verticesp++ = position_agent + right + up; + *verticesp++ = position_agent + right - up; + + *texCoordsp++ = LLVector2(x*size_inv, (y+1)*size_inv); + *texCoordsp++ = LLVector2(x*size_inv, y*size_inv); + *texCoordsp++ = LLVector2((x+1)*size_inv, (y+1)*size_inv); + *texCoordsp++ = LLVector2((x+1)*size_inv, y*size_inv); + + *normalsp++ = normal; + *normalsp++ = normal; + *normalsp++ = normal; + *normalsp++ = normal; *indicesp++ = toffset + 0; *indicesp++ = toffset + 1; @@ -243,6 +227,8 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) } } + face->mVertexBuffer->setBuffer(0); + mDrawable->movePartition(); LLPipeline::sCompiles++; return TRUE; @@ -268,6 +254,11 @@ void LLVOWater::setUseTexture(const BOOL use_texture) mUseTexture = use_texture; } +void LLVOWater::setIsEdgePatch(const BOOL edge_patch) +{ + mIsEdgePatch = edge_patch; +} + void LLVOWater::updateSpatialExtents(LLVector3 &newMin, LLVector3& newMax) { LLVector3 pos = getPositionAgent(); @@ -281,13 +272,14 @@ void LLVOWater::updateSpatialExtents(LLVector3 &newMin, LLVector3& newMax) U32 LLVOWater::getPartitionType() const { - return LLPipeline::PARTITION_WATER; + return LLViewerRegion::PARTITION_WATER; } LLWaterPartition::LLWaterPartition() : LLSpatialPartition(0) { mRenderByGroup = FALSE; + mInfiniteFarClip = TRUE; mDrawableType = LLPipeline::RENDER_TYPE_WATER; - mPartitionType = LLPipeline::PARTITION_WATER; + mPartitionType = LLViewerRegion::PARTITION_WATER; } diff --git a/linden/indra/newview/llvowater.h b/linden/indra/newview/llvowater.h index c332a27..fce5258 100644 --- a/linden/indra/newview/llvowater.h +++ b/linden/indra/newview/llvowater.h @@ -75,9 +75,13 @@ public: /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. void setUseTexture(const BOOL use_texture); + void setIsEdgePatch(const BOOL edge_patch); + BOOL getUseTexture() const { return mUseTexture; } + BOOL getIsEdgePatch() const { return mIsEdgePatch; } protected: BOOL mUseTexture; + BOOL mIsEdgePatch; }; #endif // LL_VOSURFACEPATCH_H diff --git a/linden/indra/newview/llvowlsky.cpp b/linden/indra/newview/llvowlsky.cpp new file mode 100644 index 0000000..30d1397 --- /dev/null +++ b/linden/indra/newview/llvowlsky.cpp @@ -0,0 +1,821 @@ +/** + * @file llvowlsky.cpp + * @brief LLVOWLSky class implementation + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "pipeline.h" + +#include "llvowlsky.h" +#include "llsky.h" +#include "lldrawpoolwlsky.h" +#include "llface.h" +#include "llwlparammanager.h" +#include "llviewercontrol.h" + +#define DOME_SLICES 1 +const F32 LLVOWLSky::DISTANCE_TO_STARS = (HORIZON_DIST - 10.f)*0.25f; + +const U32 LLVOWLSky::MIN_SKY_DETAIL = 3; +const U32 LLVOWLSky::MAX_SKY_DETAIL = 180; + +inline U32 LLVOWLSky::getNumStacks(void) +{ + return gSavedSettings.getU32("WLSkyDetail"); +} + +inline U32 LLVOWLSky::getNumSlices(void) +{ + return 2 * gSavedSettings.getU32("WLSkyDetail"); +} + +inline U32 LLVOWLSky::getFanNumVerts(void) +{ + return getNumSlices() + 1; +} + +inline U32 LLVOWLSky::getFanNumIndices(void) +{ + return getNumSlices() * 3; +} + +inline U32 LLVOWLSky::getStripsNumVerts(void) +{ + return (getNumStacks() - 1) * getNumSlices(); +} + +inline U32 LLVOWLSky::getStripsNumIndices(void) +{ + return 2 * ((getNumStacks() - 2) * (getNumSlices() + 1)) + 1 ; +} + +inline U32 LLVOWLSky::getStarsNumVerts(void) +{ + return 1000; +} + +inline U32 LLVOWLSky::getStarsNumIndices(void) +{ + return 1000; +} + +LLVOWLSky::LLVOWLSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) + : LLStaticViewerObject(id, pcode, regionp) +{ + initStars(); +} + +void LLVOWLSky::initSunDirection(LLVector3 const & sun_direction, + LLVector3 const & sun_angular_velocity) +{ +} + +BOOL LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) +{ + return TRUE; +} + +BOOL LLVOWLSky::isActive(void) const +{ + return FALSE; +} + +LLDrawable * LLVOWLSky::createDrawable(LLPipeline * pipeline) +{ + pipeline->allocDrawable(this); + + //LLDrawPoolWLSky *poolp = static_cast( + gPipeline.getPool(LLDrawPool::POOL_WL_SKY); + + mDrawable->setRenderType(LLPipeline::RENDER_TYPE_WL_SKY); + + return mDrawable; +} + +inline F32 LLVOWLSky::calcPhi(U32 i) +{ + // i should range from [0..SKY_STACKS] so t will range from [0.f .. 1.f] + F32 t = float(i) / float(getNumStacks()); + + // ^4 the parameter of the tesselation to bias things toward 0 (the dome's apex) + t = t*t*t*t; + + // invert and square the parameter of the tesselation to bias things toward 1 (the horizon) + t = 1.f - t; + t = t*t; + t = 1.f - t; + + return (F_PI / 8.f) * t; +} + +#if !DOME_SLICES +static const F32 Q = (1.f + sqrtf(5.f))/2.f; //golden ratio + +//icosahedron verts (based on asset b0c7b76e-28c6-1f87-a1de-752d5e3cd264, contact Runitai Linden for a copy) +static const LLVector3 icosahedron_vert[] = +{ + LLVector3(0,1.f,Q), + LLVector3(0,-1.f,Q), + LLVector3(0,-1.f,-Q), + LLVector3(0,1.f,-Q), + + LLVector3(Q,0,1.f), + LLVector3(-Q,0,1.f), + LLVector3(-Q,0,-1.f), + LLVector3(Q,0,-1.f), + + LLVector3(1,-Q,0.f), + LLVector3(-1,-Q,0.f), + LLVector3(-1,Q,0.f), + LLVector3(1,Q,0.f), +}; + +//indices +static const U32 icosahedron_ind[] = +{ + 5,0,1, + 10,0,5, + 5,1,9, + 10,5,6, + 6,5,9, + 11,0,10, + 3,11,10, + 3,10,6, + 3,6,2, + 7,3,2, + 8,7,2, + 4,7,8, + 1,4,8, + 9,8,2, + 9,2,6, + 11,3,7, + 4,0,11, + 4,11,7, + 1,0,4, + 1,8,9, +}; + + +//split every triangle in LLVertexBuffer into even fourths (assumes index triangle lists) +void subdivide(LLVertexBuffer& in, LLVertexBuffer* ret) +{ + S32 tri_in = in.getNumIndices()/3; + + ret->allocateBuffer(tri_in*4*3, tri_in*4*3, TRUE); + + LLStrider vin, vout; + LLStrider indin, indout; + + ret->getVertexStrider(vout); + in.getVertexStrider(vin); + + ret->getIndexStrider(indout); + in.getIndexStrider(indin); + + + for (S32 i = 0; i < tri_in; i++) + { + LLVector3 v0 = vin[*indin++]; + LLVector3 v1 = vin[*indin++]; + LLVector3 v2 = vin[*indin++]; + + LLVector3 v3 = (v0 + v1) * 0.5f; + LLVector3 v4 = (v1 + v2) * 0.5f; + LLVector3 v5 = (v2 + v0) * 0.5f; + + *vout++ = v0; + *vout++ = v3; + *vout++ = v5; + + *vout++ = v3; + *vout++ = v4; + *vout++ = v5; + + *vout++ = v3; + *vout++ = v1; + *vout++ = v4; + + *vout++ = v5; + *vout++ = v4; + *vout++ = v2; + } + + for (S32 i = 0; i < ret->getNumIndices(); i++) + { + *indout++ = i; + } + +} + +void chop(LLVertexBuffer& in, LLVertexBuffer* out) +{ + //chop off all triangles below horizon + F32 d = LLWLParamManager::sParamMgr->getDomeOffset() * LLWLParamManager::sParamMgr->getDomeRadius(); + + std::vector vert; + + LLStrider vin; + LLStrider index; + + in.getVertexStrider(vin); + in.getIndexStrider(index); + + U32 tri_count = in.getNumIndices()/3; + for (U32 i = 0; i < tri_count; i++) + { + LLVector3 &v1 = vin[index[i*3+0]]; + LLVector3 &v2 = vin[index[i*3+1]]; + LLVector3 &v3 = vin[index[i*3+2]]; + + if (v1.mV[1] > d || + v2.mV[1] > d || + v3.mV[1] > d) + { + v1.mV[1] = llmax(v1.mV[1], d); + v2.mV[1] = llmax(v1.mV[1], d); + v3.mV[1] = llmax(v1.mV[1], d); + + vert.push_back(v1); + vert.push_back(v2); + vert.push_back(v3); + } + } + + out->allocateBuffer(vert.size(), vert.size(), TRUE); + + LLStrider vout; + out->getVertexStrider(vout); + out->getIndexStrider(index); + + for (U32 i = 0; i < vert.size(); i++) + { + *vout++ = vert[i]; + *index++ = i; + } +} +#endif // !DOME_SLICES + +void LLVOWLSky::resetVertexBuffers() +{ + mFanVerts = NULL; + mStripsVerts.clear(); + mStarsVerts = NULL; + + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); +} + +void LLVOWLSky::cleanupGL() +{ + mFanVerts = NULL; + mStripsVerts.clear(); + mStarsVerts = NULL; + + LLDrawPoolWLSky::cleanupGL(); +} + +void LLVOWLSky::restoreGL() +{ + LLDrawPoolWLSky::restoreGL(); + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); +} + +BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) +{ + LLFastTimer ftm(LLFastTimer::FTM_GEO_SKY); + LLStrider vertices; + LLStrider texCoords; + LLStrider indices; + +#if DOME_SLICES + { + mFanVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); + mFanVerts->allocateBuffer(getFanNumVerts(), getFanNumIndices(), TRUE); + + BOOL success = mFanVerts->getVertexStrider(vertices) + && mFanVerts->getTexCoordStrider(texCoords) + && mFanVerts->getIndexStrider(indices); + + if(!success) + { + llerrs << "Failed updating WindLight sky geometry." << llendl; + } + + buildFanBuffer(vertices, texCoords, indices); + + mFanVerts->setBuffer(0); + } + + { + const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024; + const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK; + const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcStride(data_mask); + + const U32 total_stacks = getNumStacks(); + + const U32 verts_per_stack = getNumSlices(); + + // each seg has to have one more row of verts than it has stacks + // then round down + const U32 stacks_per_seg = (max_verts - verts_per_stack) / verts_per_stack; + + // round up to a whole number of segments + const U32 strips_segments = (total_stacks+stacks_per_seg-1) / stacks_per_seg; + + llinfos << "WL Skydome strips in " << strips_segments << " batches." << llendl; + + mStripsVerts.resize(strips_segments, NULL); + + for (U32 i = 0; i < strips_segments ;++i) + { + LLVertexBuffer * segment = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); + mStripsVerts[i] = segment; + + U32 num_stacks_this_seg = stacks_per_seg; + if ((i == strips_segments - 1) && (total_stacks % stacks_per_seg) != 0) + { + // for the last buffer only allocate what we'll use + num_stacks_this_seg = total_stacks % stacks_per_seg; + } + + // figure out what range of the sky we're filling + const U32 begin_stack = i * stacks_per_seg; + const U32 end_stack = begin_stack + num_stacks_this_seg; + llassert(end_stack <= total_stacks); + + const U32 num_verts_this_seg = verts_per_stack * (num_stacks_this_seg+1); + llassert(num_verts_this_seg <= max_verts); + + const U32 num_indices_this_seg = 1+num_stacks_this_seg*(2+2*verts_per_stack); + llassert(num_indices_this_seg * sizeof(U16) <= max_buffer_bytes); + + segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE); + + // lock the buffer + BOOL success = segment->getVertexStrider(vertices) + && segment->getTexCoordStrider(texCoords) + && segment->getIndexStrider(indices); + + if(!success) + { + llerrs << "Failed updating WindLight sky geometry." << llendl; + } + + // fill it + buildStripsBuffer(begin_stack, end_stack, vertices, texCoords, indices); + + // and unlock the buffer + segment->setBuffer(0); + } + } +#else + mStripsVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); + + const F32 RADIUS = LLWLParamManager::sParamMgr->getDomeRadius(); + + LLPointer temp = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0); + temp->allocateBuffer(12, 60, TRUE); + + BOOL success = temp->getVertexStrider(vertices) + && temp->getIndexStrider(indices); + + if (success) + { + for (U32 i = 0; i < 12; i++) + { + *vertices++ = icosahedron_vert[i]; + } + + for (U32 i = 0; i < 60; i++) + { + *indices++ = icosahedron_ind[i]; + } + } + + + LLPointer temp2; + + for (U32 i = 0; i < 8; i++) + { + temp2 = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0); + subdivide(*temp, temp2); + temp = temp2; + } + + temp->getVertexStrider(vertices); + for (S32 i = 0; i < temp->getNumVerts(); i++) + { + LLVector3 v = vertices[i]; + v.normVec(); + vertices[i] = v*RADIUS; + } + + temp2 = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0); + chop(*temp, temp2); + + mStripsVerts->allocateBuffer(temp2->getNumVerts(), temp2->getNumIndices(), TRUE); + + success = mStripsVerts->getVertexStrider(vertices) + && mStripsVerts->getTexCoordStrider(texCoords) + && mStripsVerts->getIndexStrider(indices); + + LLStrider v; + temp2->getVertexStrider(v); + LLStrider ind; + temp2->getIndexStrider(ind); + + if (success) + { + for (S32 i = 0; i < temp2->getNumVerts(); ++i) + { + LLVector3 vert = *v++; + vert.normVec(); + F32 z0 = vert.mV[2]; + F32 x0 = vert.mV[0]; + + vert *= RADIUS; + + *vertices++ = vert; + *texCoords++ = LLVector2((-z0 + 1.f) / 2.f, (-x0 + 1.f) / 2.f); + } + + for (S32 i = 0; i < temp2->getNumIndices(); ++i) + { + *indices++ = *ind++; + } + } + + mStripsVerts->setBuffer(0); +#endif + + updateStarColors(); + updateStarGeometry(drawable); + + LLPipeline::sCompiles++; + + return TRUE; +} + +void LLVOWLSky::drawStars(void) +{ + glEnableClientState(GL_COLOR_ARRAY); + + // render the stars as a sphere centered at viewer camera + if (mStarsVerts.notNull()) + { + mStarsVerts->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK); + U16* indicesp = (U16*) mStarsVerts->getIndicesPointer(); + glDrawElements(GL_POINTS, getStarsNumIndices(), GL_UNSIGNED_SHORT, indicesp); + } + + glDisableClientState(GL_COLOR_ARRAY); +} + +void LLVOWLSky::drawDome(void) +{ + if (mStripsVerts.empty()) + { + updateGeometry(mDrawable); + } + + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + + const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK; + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + +#if DOME_SLICES + //mFanVerts->setBuffer(data_mask); + //glDrawRangeElements( + // GL_TRIANGLES, + // 0, getFanNumVerts()-1, getFanNumIndices(), + // GL_UNSIGNED_SHORT, + // mFanVerts->getIndicesPointer()); + + //gPipeline.addTrianglesDrawn(getFanNumIndices()/3); + + std::vector< LLPointer >::const_iterator strips_vbo_iter, end_strips; + end_strips = mStripsVerts.end(); + for(strips_vbo_iter = mStripsVerts.begin(); strips_vbo_iter != end_strips; ++strips_vbo_iter) + { + LLVertexBuffer * strips_segment = strips_vbo_iter->get(); + + strips_segment->setBuffer(data_mask); + + glDrawRangeElements( + //GL_TRIANGLES, + GL_TRIANGLE_STRIP, + 0, strips_segment->getRequestedVerts()-1, strips_segment->getRequestedIndices(), + GL_UNSIGNED_SHORT, + strips_segment->getIndicesPointer()); + + gPipeline.addTrianglesDrawn(strips_segment->getRequestedIndices() - 2); + } + +#else + mStripsVerts->setBuffer(data_mask); + glDrawRangeElements( + GL_TRIANGLES, + 0, mStripsVerts->getNumVerts()-1, mStripsVerts->getNumIndices(), + GL_UNSIGNED_SHORT, + mStripsVerts->getIndicesPointer()); +#endif + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + LLVertexBuffer::unbind(); +} + +void LLVOWLSky::initStars() +{ + // Initialize star map + mStarVertices.resize(getStarsNumVerts()); + mStarColors.resize(getStarsNumVerts()); + mStarIntensities.resize(getStarsNumVerts()); + + std::vector::iterator v_p = mStarVertices.begin(); + std::vector::iterator v_c = mStarColors.begin(); + std::vector::iterator v_i = mStarIntensities.begin(); + + U32 i; + for (i = 0; i < getStarsNumVerts(); ++i) + { + v_p->mV[VX] = ll_frand() - 0.5f; + v_p->mV[VY] = ll_frand() - 0.5f; + + // we only want stars on the top half of the dome! + + v_p->mV[VZ] = ll_frand()/2.f; + + v_p->normVec(); + *v_p *= DISTANCE_TO_STARS; + *v_i = llmin((F32)pow(ll_frand(),2.f) + 0.1f, 1.f); + v_c->mV[VRED] = 0.75f + ll_frand() * 0.25f ; + v_c->mV[VGREEN] = 1.f ; + v_c->mV[VBLUE] = 0.75f + ll_frand() * 0.25f ; + v_c->mV[VALPHA] = 1.f; + v_c->clamp(); + v_p++; + v_c++; + v_i++; + } +} + +void LLVOWLSky::buildFanBuffer(LLStrider & vertices, + LLStrider & texCoords, + LLStrider & indices) +{ + const F32 RADIUS = LLWLParamManager::instance()->getDomeRadius(); + + U32 i, num_slices; + F32 phi0, theta, x0, y0, z0; + + // paranoia checking for SL-55986/SL-55833 + U32 count_verts = 0; + U32 count_indices = 0; + + // apex + *vertices++ = LLVector3(0.f, RADIUS, 0.f); + *texCoords++ = LLVector2(0.5f, 0.5f); + ++count_verts; + + num_slices = getNumSlices(); + + // and fan in a circle around the apex + phi0 = calcPhi(1); + for(i = 0; i < num_slices; ++i) { + theta = 2.f * F_PI * float(i) / float(num_slices); + + // standard transformation from spherical to + // rectangular coordinates + x0 = sin(phi0) * cos(theta); + y0 = cos(phi0); + z0 = sin(phi0) * sin(theta); + + *vertices++ = LLVector3(x0 * RADIUS, y0 * RADIUS, z0 * RADIUS); + // generate planar uv coordinates + // note: x and z are transposed in order for things to animate + // correctly in the global coordinate system where +x is east and + // +y is north + *texCoords++ = LLVector2((-z0 + 1.f) / 2.f, (-x0 + 1.f) / 2.f); + ++count_verts; + + if (i > 0) + { + *indices++ = 0; + *indices++ = i; + *indices++ = i+1; + count_indices += 3; + } + } + + // the last vertex of the last triangle should wrap around to + // the beginning + *indices++ = 0; + *indices++ = num_slices; + *indices++ = 1; + count_indices += 3; + + // paranoia checking for SL-55986/SL-55833 + llassert(getFanNumVerts() == count_verts); + llassert(getFanNumIndices() == count_indices); +} + +void LLVOWLSky::buildStripsBuffer(U32 begin_stack, U32 end_stack, + LLStrider & vertices, + LLStrider & texCoords, + LLStrider & indices) +{ + const F32 RADIUS = LLWLParamManager::instance()->getDomeRadius(); + + U32 i, j, num_slices, num_stacks; + F32 phi0, theta, x0, y0, z0; + + // paranoia checking for SL-55986/SL-55833 + U32 count_verts = 0; + U32 count_indices = 0; + + num_slices = getNumSlices(); + num_stacks = getNumStacks(); + + llassert(end_stack <= num_stacks); + + // stacks are iterated one-indexed since phi(0) was handled by the fan above + for(i = begin_stack + 1; i <= end_stack+1; ++i) + { + phi0 = calcPhi(i); + + for(j = 0; j < num_slices; ++j) + { + theta = F_TWO_PI * (float(j) / float(num_slices)); + + // standard transformation from spherical to + // rectangular coordinates + x0 = sin(phi0) * cos(theta); + y0 = cos(phi0); + z0 = sin(phi0) * sin(theta); + + if (i == num_stacks-2) + { + *vertices++ = LLVector3(x0*RADIUS, y0*RADIUS-1024.f*2.f, z0*RADIUS); + } + else if (i == num_stacks-1) + { + *vertices++ = LLVector3(0, y0*RADIUS-1024.f*2.f, 0); + } + else + { + *vertices++ = LLVector3(x0 * RADIUS, y0 * RADIUS, z0 * RADIUS); + } + ++count_verts; + + // generate planar uv coordinates + // note: x and z are transposed in order for things to animate + // correctly in the global coordinate system where +x is east and + // +y is north + *texCoords++ = LLVector2((-z0 + 1.f) / 2.f, (-x0 + 1.f) / 2.f); + } + } + + //build triangle strip... + *indices++ = 0 ; + count_indices++ ; + S32 k = 0 ; + for(i = 1; i <= end_stack - begin_stack; ++i) + { + *indices++ = i * num_slices + k ; + count_indices++ ; + + k = (k+1) % num_slices ; + for(j = 0; j < num_slices ; ++j) + { + *indices++ = (i-1) * num_slices + k ; + *indices++ = i * num_slices + k ; + + count_indices += 2 ; + + k = (k+1) % num_slices ; + } + + if((--k) < 0) + { + k = num_slices - 1 ; + } + + *indices++ = i * num_slices + k ; + count_indices++ ; + } +} + +void LLVOWLSky::updateStarColors() +{ + std::vector::iterator v_c = mStarColors.begin(); + std::vector::iterator v_i = mStarIntensities.begin(); + std::vector::iterator v_p = mStarVertices.begin(); + + const F32 var = 0.15f; + const F32 min = 0.5f; //0.75f; + const F32 sunclose_max = 0.6f; + const F32 sunclose_range = 1 - sunclose_max; + + //F32 below_horizon = - llmin(0.0f, gSky.mVOSkyp->getToSunLast().mV[2]); + //F32 brightness_factor = llmin(1.0f, below_horizon * 20); + + static S32 swap = 0; + swap++; + + if ((swap % 2) == 1) + { + F32 intensity; // max intensity of each star + U32 x; + for (x = 0; x < getStarsNumVerts(); ++x) + { + F32 sundir_factor = 1; + LLVector3 tostar = *v_p; + tostar.normVec(); + const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast(); + if (how_close_to_sun > sunclose_max) + { + sundir_factor = (1 - how_close_to_sun) / sunclose_range; + } + intensity = *(v_i); + F32 alpha = v_c->mV[VALPHA] + (ll_frand() - 0.5f) * var * intensity; + if (alpha < min * intensity) + { + alpha = min * intensity; + } + if (alpha > intensity) + { + alpha = intensity; + } + //alpha *= brightness_factor * sundir_factor; + + alpha = llclamp(alpha, 0.f, 1.f); + v_c->mV[VALPHA] = alpha; + v_c++; + v_i++; + v_p++; + } + } +} + +BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable) +{ + LLStrider verticesp; + LLStrider colorsp; + LLStrider indicesp; + + if (mStarsVerts.isNull()) + { + mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW); + mStarsVerts->allocateBuffer(getStarsNumVerts(), getStarsNumIndices(), TRUE); + } + + BOOL success = mStarsVerts->getVertexStrider(verticesp) + && mStarsVerts->getIndexStrider(indicesp) + && mStarsVerts->getColorStrider(colorsp); + + if(!success) + { + llerrs << "Failed updating star geometry." << llendl; + } + + // *TODO: fix LLStrider with a real prefix increment operator so it can be + // used as a model of OutputIterator. -Brad + // std::copy(mStarVertices.begin(), mStarVertices.end(), verticesp); + for (U32 vtx = 0; vtx < getStarsNumVerts(); ++vtx) + { + *(verticesp++) = mStarVertices[vtx]; + *(colorsp++) = LLColor4U(mStarColors[vtx]); + *(indicesp++) = vtx; + } + + mStarsVerts->setBuffer(0); + return TRUE; +} diff --git a/linden/indra/newview/llvowlsky.h b/linden/indra/newview/llvowlsky.h new file mode 100644 index 0000000..3a5cb3a --- /dev/null +++ b/linden/indra/newview/llvowlsky.h @@ -0,0 +1,110 @@ +/** + * @file llvowlsky.h + * @brief LLVOWLSky class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_VOWLSKY_H +#define LL_VOWLSKY_H + +#include "llviewerobject.h" + +class LLVOWLSky : public LLStaticViewerObject { +private: + static const F32 DISTANCE_TO_STARS; + + // anything less than 3 makes it impossible to create a closed dome. + static const U32 MIN_SKY_DETAIL; + // anything bigger than about 180 will cause getStripsNumVerts() to exceed 65535. + static const U32 MAX_SKY_DETAIL; + + inline static U32 getNumStacks(void); + inline static U32 getNumSlices(void); + inline static U32 getFanNumVerts(void); + inline static U32 getFanNumIndices(void); + inline static U32 getStripsNumVerts(void); + inline static U32 getStripsNumIndices(void); + inline static U32 getStarsNumVerts(void); + inline static U32 getStarsNumIndices(void); + +public: + LLVOWLSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); + + void initSunDirection(LLVector3 const & sun_direction, + LLVector3 const & sun_angular_velocity); + + /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); + /*virtual*/ BOOL isActive(void) const; + /*virtual*/ LLDrawable * createDrawable(LLPipeline *pipeline); + /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); + + void drawStars(void); + void drawDome(void); + void resetVertexBuffers(void); + + void cleanupGL(); + void restoreGL(); + +private: + // a tiny helper function for controlling the sky dome tesselation. + static F32 calcPhi(U32 i); + + // helper function for initializing the stars. + void initStars(); + + // helper function for building the fan vertex buffer. + static void buildFanBuffer(LLStrider & vertices, + LLStrider & texCoords, + LLStrider & indices); + + // helper function for building the strips vertex buffer. + // note begin_stack and end_stack follow stl iterator conventions, + // begin_stack is the first stack to be included, end_stack is the first + // stack not to be included. + static void buildStripsBuffer(U32 begin_stack, U32 end_stack, + LLStrider & vertices, + LLStrider & texCoords, + LLStrider & indices); + + // helper function for updating the stars colors. + void updateStarColors(); + + // helper function for updating the stars geometry. + BOOL updateStarGeometry(LLDrawable *drawable); + +private: + LLPointer mFanVerts; + std::vector< LLPointer > mStripsVerts; + LLPointer mStarsVerts; + + std::vector mStarVertices; // Star verticies + std::vector mStarColors; // Star colors + std::vector mStarIntensities; // Star intensities +}; + +#endif // LL_VOWLSKY_H diff --git a/linden/indra/newview/llwaterparammanager.cpp b/linden/indra/newview/llwaterparammanager.cpp new file mode 100644 index 0000000..ae913af --- /dev/null +++ b/linden/indra/newview/llwaterparammanager.cpp @@ -0,0 +1,433 @@ +/** + * @file llwaterparammanager.cpp + * @brief Implementation for the LLWaterParamManager class. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llwaterparammanager.h" + +#include "pipeline.h" +#include "llsky.h" + +#include "llsliderctrl.h" +#include "llspinctrl.h" +#include "llcheckboxctrl.h" +#include "llvieweruictrlfactory.h" +#include "llviewercontrol.h" +#include "llviewercamera.h" +#include "llcombobox.h" +#include "lllineeditor.h" +#include "llsdserialize.h" + +#include "v4math.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "lldrawpoolwater.h" +#include "llagent.h" +#include "llviewerregion.h" + +#include "llwlparammanager.h" +#include "llwaterparamset.h" +#include "llpostprocess.h" +#include "llfloaterwater.h" + +#include "curl/curl.h" + +LLWaterParamManager * LLWaterParamManager::sInstance = NULL; + +LLWaterParamManager::LLWaterParamManager() : + mFogColor(22.f/255.f, 43.f/255.f, 54.f/255.f, 0.0f, 0.0f, "waterFogColor", "WaterFogColor"), + mFogDensity(4, "waterFogDensity", 2), + mUnderWaterFogMod(0.25, "underWaterFogMod"), + mNormalScale(2.f, 2.f, 2.f, "normScale"), + mFresnelScale(0.5f, "fresnelScale"), + mFresnelOffset(0.4f, "fresnelOffset"), + mScaleAbove(0.025f, "scaleAbove"), + mScaleBelow(0.2f, "scaleBelow"), + mBlurMultiplier(0.1f, "blurMultiplier"), + mWave1Dir(.5f, .5f, "wave1Dir"), + mWave2Dir(.5f, .5f, "wave2Dir"), + mDensitySliderValue(1.0f) +{ +} + +LLWaterParamManager::~LLWaterParamManager() +{ +} + +void LLWaterParamManager::loadAllPresets(const LLString& file_name) +{ + LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", "")); + llinfos << "Loading water settings from " << path_name << llendl; + + //mParamList.clear(); + + bool found = true; + while(found) + { + std::string name; + found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name, false); + + llinfos << "name: " << name << llendl; + + // if we have one + if(found) + { + // bugfix for SL-46920: preventing filenames that break stuff. + char * curl_str = curl_unescape(name.c_str(), name.size()); + std::string unescaped_name(curl_str); + curl_free(curl_str); + curl_str = NULL; + + // not much error checking here since we're getting rid of this + std::string water_name = unescaped_name.substr(0, unescaped_name.size() - 4); + + LLString cur_path(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", name)); + llinfos << "Loading water from " << cur_path << llendl; + + std::ifstream water_xml(cur_path.c_str()); + if (water_xml) + { + LLSD water_data(LLSD::emptyMap()); + LLPointer parser = new LLSDXMLParser(); + parser->parse(water_xml, water_data, LLSDSerialize::SIZE_UNLIMITED); + + addParamSet(water_name, water_data); + } + } + } +} + +void LLWaterParamManager::loadPreset(const LLString & name) +{ + // bugfix for SL-46920: preventing filenames that break stuff. + char * curl_str = curl_escape(name.c_str(), name.size()); + std::string escaped_filename(curl_str); + curl_free(curl_str); + curl_str = NULL; + + escaped_filename += ".xml"; + + std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", escaped_filename)); + llinfos << "Loading water settings from " << pathName << llendl; + + std::ifstream presetsXML(pathName.c_str()); + + if (presetsXML) + { + LLSD paramsData(LLSD::emptyMap()); + + LLPointer parser = new LLSDXMLParser(); + + parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED); + + std::map::iterator mIt = mParamList.find(name); + if(mIt == mParamList.end()) + { + addParamSet(name, paramsData); + } + else + { + setParamSet(name, paramsData); + } + } + else + { + llwarns << "Can't find " << name << llendl; + return; + } + + getParamSet(name, mCurParams); + + propagateParameters(); +} + +void LLWaterParamManager::savePreset(const LLString & name) +{ + // bugfix for SL-46920: preventing filenames that break stuff. + char * curl_str = curl_escape(name.c_str(), name.size()); + std::string escaped_filename(curl_str); + curl_free(curl_str); + curl_str = NULL; + + escaped_filename += ".xml"; + + // make an empty llsd + LLSD paramsData(LLSD::emptyMap()); + std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", escaped_filename)); + + // fill it with LLSD windlight params + paramsData = mParamList[name].getAll(); + + // write to file + std::ofstream presetsXML(pathName.c_str()); + LLPointer formatter = new LLSDXMLFormatter(); + formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY); + presetsXML.close(); + + propagateParameters(); +} + + +void LLWaterParamManager::propagateParameters(void) +{ + // bind the variables only if we're using shaders + if(gPipeline.canUseVertexShaders()) + { + LLShaderMgr::shader_iter shaders_iter, end_shaders; + end_shaders = LLShaderMgr::endShaders(); + for(shaders_iter = LLShaderMgr::beginShaders(); shaders_iter != end_shaders; ++shaders_iter) + { + if (shaders_iter->mProgramObject != 0 + && shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER) + { + shaders_iter->mUniformsDirty = TRUE; + } + } + } + + bool err; + F32 fog_density_slider = + log(mCurParams.getFloat(mFogDensity.mName, err)) / + log(mFogDensity.mBase); + + setDensitySliderValue(fog_density_slider); +} + +void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader) +{ + if (shader->mShaderGroup == LLGLSLShader::SG_WATER) + { + shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, LLWLParamManager::instance()->getRotatedLightDir().mV); + shader->uniform3fv("camPosLocal", 1, gCamera->getOrigin().mV); + shader->uniform4fv("waterFogColor", 1, LLDrawPoolWater::sWaterFogColor.mV); + shader->uniform4fv("waterPlane", 1, mWaterPlane.mV); + shader->uniform1f("waterFogDensity", getFogDensity()); + shader->uniform1f("waterFogKS", mWaterFogKS); + shader->uniform4f("distance_multiplier", 0, 0, 0, 0); + } +} + +void LLWaterParamManager::update(LLViewerCamera * cam) +{ + LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM); + + // update the shaders and the menu + propagateParameters(); + + // sync menus if they exist + if(LLFloaterWater::isOpen()) + { + LLFloaterWater::instance()->syncMenu(); + } + + stop_glerror(); + + // only do this if we're dealing with shaders + if(gPipeline.canUseVertexShaders()) + { + //transform water plane to eye space + glh::vec3f norm(0, 0, 1); + glh::vec3f p(0, 0, gAgent.getRegion()->getWaterHeight()+0.1f); + + F32 modelView[16]; + for (U32 i = 0; i < 16; i++) + { + modelView[i] = (F32) gGLModelView[i]; + } + + glh::matrix4f mat(modelView); + glh::matrix4f invtrans = mat.inverse().transpose(); + glh::vec3f enorm; + glh::vec3f ep; + invtrans.mult_matrix_vec(norm, enorm); + enorm.normalize(); + mat.mult_matrix_vec(p, ep); + + mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); + + LLVector3 sunMoonDir; + if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS) + { + sunMoonDir = gSky.getSunDirection(); + } + else + { + sunMoonDir = gSky.getMoonDirection(); + } + sunMoonDir.normVec(); + mWaterFogKS = 1.f/llmax(sunMoonDir.mV[2], WATER_FOG_LIGHT_CLAMP); + + LLShaderMgr::shader_iter shaders_iter, end_shaders; + end_shaders = LLShaderMgr::endShaders(); + for(shaders_iter = LLShaderMgr::beginShaders(); shaders_iter != end_shaders; ++shaders_iter) + { + if (shaders_iter->mProgramObject != 0 + && shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER) + { + shaders_iter->mUniformsDirty = TRUE; + } + } + } +} + +// static +void LLWaterParamManager::initClass(void) +{ + instance(); +} + +// static +void LLWaterParamManager::cleanupClass(void) +{ + delete sInstance; + sInstance = NULL; +} + +bool LLWaterParamManager::addParamSet(const std::string& name, LLWaterParamSet& param) +{ + // add a new one if not one there already + std::map::iterator mIt = mParamList.find(name); + if(mIt == mParamList.end()) + { + mParamList[name] = param; + return true; + } + + return false; +} + +BOOL LLWaterParamManager::addParamSet(const std::string& name, LLSD const & param) +{ + // add a new one if not one there already + std::map::const_iterator finder = mParamList.find(name); + if(finder == mParamList.end()) + { + mParamList[name].setAll(param); + return TRUE; + } + else + { + return FALSE; + } +} + +bool LLWaterParamManager::getParamSet(const std::string& name, LLWaterParamSet& param) +{ + // find it and set it + std::map::iterator mIt = mParamList.find(name); + if(mIt != mParamList.end()) + { + param = mParamList[name]; + param.mName = name; + return true; + } + + return false; +} + +bool LLWaterParamManager::setParamSet(const std::string& name, LLWaterParamSet& param) +{ + mParamList[name] = param; + + return true; +} + +bool LLWaterParamManager::setParamSet(const std::string& name, const LLSD & param) +{ + // quick, non robust (we won't be working with files, but assets) check + if(!param.isMap()) + { + return false; + } + + mParamList[name].setAll(param); + + return true; +} + +bool LLWaterParamManager::removeParamSet(const std::string& name, bool delete_from_disk) +{ + // remove from param list + std::map::iterator mIt = mParamList.find(name); + if(mIt != mParamList.end()) + { + mParamList.erase(mIt); + } + + if(delete_from_disk) + { + LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", "")); + + // use full curl escaped name + char * curl_str = curl_escape(name.c_str(), name.size()); + std::string escaped_name(curl_str); + curl_free(curl_str); + curl_str = NULL; + + gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml"); + } + + return true; +} + +F32 LLWaterParamManager::getFogDensity(void) +{ + bool err; + + F32 fogDensity = mCurParams.getFloat("waterFogDensity", err); + + // modify if we're underwater + const F32 water_height = gAgent.getRegion()->getWaterHeight(); + F32 camera_height = gAgent.getCameraPositionAgent().mV[2]; + if(camera_height <= water_height) + { + // raise it to the underwater fog density modifier + fogDensity = pow(fogDensity, mCurParams.getFloat("underWaterFogMod", err)); + } + + return fogDensity; +} + +// static +LLWaterParamManager * LLWaterParamManager::instance() +{ + if(NULL == sInstance) + { + sInstance = new LLWaterParamManager(); + + sInstance->loadAllPresets(""); + + sInstance->getParamSet("Default", sInstance->mCurParams); + } + + return sInstance; +} diff --git a/linden/indra/newview/llwaterparammanager.h b/linden/indra/newview/llwaterparammanager.h new file mode 100644 index 0000000..ad40c12 --- /dev/null +++ b/linden/indra/newview/llwaterparammanager.h @@ -0,0 +1,401 @@ +/** + * @file llwaterparammanager.h + * @brief Implementation for the LLWaterParamManager class. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_WATER_PARAMMANAGER_H +#define LL_WATER_PARAMMANAGER_H + +#include +#include +#include "llwaterparamset.h" +#include "llviewercamera.h" +#include "v4color.h" + +const F32 WATER_FOG_LIGHT_CLAMP = 0.3f; + +// color control +struct WaterColorControl { + + F32 mR, mG, mB, mA, mI; /// the values + char const * mName; /// name to use to dereference params + std::string mSliderName; /// name of the slider in menu + bool mHasSliderName; /// only set slider name for true color types + + inline WaterColorControl(F32 red, F32 green, F32 blue, F32 alpha, + F32 intensity, char const * n, char const * sliderName = "") + : mR(red), mG(green), mB(blue), mA(alpha), mI(intensity), mName(n), mSliderName(sliderName) + { + // if there's a slider name, say we have one + mHasSliderName = false; + if (mSliderName != "") { + mHasSliderName = true; + } + } + + inline WaterColorControl & operator = (LLColor4 const & val) + { + mR = val.mV[0]; + mG = val.mV[1]; + mB = val.mV[2]; + mA = val.mV[3]; + return *this; + } + + inline operator LLColor4 (void) const + { + return LLColor4(mR, mG, mB, mA); + } + + inline WaterColorControl & operator = (LLVector4 const & val) + { + mR = val.mV[0]; + mG = val.mV[1]; + mB = val.mV[2]; + mA = val.mV[3]; + return *this; + } + + inline operator LLVector4 (void) const + { + return LLVector4(mR, mG, mB, mA); + } + + inline operator LLVector3 (void) const + { + return LLVector3(mR, mG, mB); + } + + inline void update(LLWaterParamSet & params) const + { + params.set(mName, mR, mG, mB, mA); + } +}; + +struct WaterVector3Control +{ + F32 mX; + F32 mY; + F32 mZ; + + char const * mName; + + // basic constructor + inline WaterVector3Control(F32 valX, F32 valY, F32 valZ, char const * n) + : mX(valX), mY(valY), mZ(valZ), mName(n) + { + } + + inline WaterVector3Control & operator = (LLVector3 const & val) + { + mX = val.mV[0]; + mY = val.mV[1]; + mZ = val.mV[2]; + + return *this; + } + + inline void update(LLWaterParamSet & params) const + { + params.set(mName, mX, mY, mZ); + } + +}; + +struct WaterVector2Control +{ + F32 mX; + F32 mY; + + char const * mName; + + // basic constructor + inline WaterVector2Control(F32 valX, F32 valY, char const * n) + : mX(valX), mY(valY), mName(n) + { + } + + inline WaterVector2Control & operator = (LLVector2 const & val) + { + mX = val.mV[0]; + mY = val.mV[1]; + + return *this; + } + + inline void update(LLWaterParamSet & params) const + { + params.set(mName, mX, mY); + } +}; + +// float slider control +struct WaterFloatControl +{ + F32 mX; + char const * mName; + F32 mMult; + + inline WaterFloatControl(F32 val, char const * n, F32 m=1.0f) + : mX(val), mName(n), mMult(m) + { + } + + inline WaterFloatControl & operator = (LLVector4 const & val) + { + mX = val.mV[0]; + + return *this; + } + + inline operator F32 (void) const + { + return mX; + } + + inline void update(LLWaterParamSet & params) const + { + params.set(mName, mX); + } +}; + +// float slider control +struct WaterExpFloatControl +{ + F32 mExp; + char const * mName; + F32 mBase; + + inline WaterExpFloatControl(F32 val, char const * n, F32 b) + : mExp(val), mName(n), mBase(b) + { + } + + inline WaterExpFloatControl & operator = (F32 val) + { + mExp = log(val) / log(mBase); + + return *this; + } + + inline operator F32 (void) const + { + return pow(mBase, mExp); + } + + inline void update(LLWaterParamSet & params) const + { + params.set(mName, pow(mBase, mExp)); + } +}; + + +/// WindLight parameter manager class - what controls all the wind light shaders +class LLWaterParamManager +{ +public: + + LLWaterParamManager(); + ~LLWaterParamManager(); + + /// load a preset file + void loadAllPresets(const LLString & fileName); + + /// load an individual preset into the sky + void loadPreset(const LLString & name); + + /// save the parameter presets to file + void savePreset(const LLString & name); + + /// send the parameters to the shaders + void propagateParameters(void); + + /// update information for the shader + void update(LLViewerCamera * cam); + + /// Update shader uniforms that have changed. + void updateShaderUniforms(LLGLSLShader * shader); + + /// Perform global initialization for this class. + static void initClass(void); + + // Cleanup of global data that's only inited once per class. + static void cleanupClass(); + + /// add a param to the list + bool addParamSet(const std::string& name, LLWaterParamSet& param); + + /// add a param to the list + BOOL addParamSet(const std::string& name, LLSD const & param); + + /// get a param from the list + bool getParamSet(const std::string& name, LLWaterParamSet& param); + + /// set the param in the list with a new param + bool setParamSet(const std::string& name, LLWaterParamSet& param); + + /// set the param in the list with a new param + bool setParamSet(const std::string& name, LLSD const & param); + + /// gets rid of a parameter and any references to it + /// returns true if successful + bool removeParamSet(const std::string& name, bool delete_from_disk); + + /// set the normap map we want for water + bool setNormalMapID(const LLUUID& img); + + void setDensitySliderValue(F32 val); + + /// getters for all the different things water param manager maintains + LLUUID getNormalMapID(void); + LLVector2 getWave1Dir(void); + LLVector2 getWave2Dir(void); + F32 getScaleAbove(void); + F32 getScaleBelow(void); + LLVector3 getNormalScale(void); + F32 getFresnelScale(void); + F32 getFresnelOffset(void); + F32 getBlurMultiplier(void); + F32 getFogDensity(void); + LLColor4 getFogColor(void); + + // singleton pattern implementation + static LLWaterParamManager * instance(); + +public: + + LLWaterParamSet mCurParams; + + /// Atmospherics + WaterColorControl mFogColor; + WaterExpFloatControl mFogDensity; + WaterFloatControl mUnderWaterFogMod; + + /// wavelet scales and directions + WaterVector3Control mNormalScale; + WaterVector2Control mWave1Dir; + WaterVector2Control mWave2Dir; + + // controls how water is reflected and refracted + WaterFloatControl mFresnelScale; + WaterFloatControl mFresnelOffset; + WaterFloatControl mScaleAbove; + WaterFloatControl mScaleBelow; + WaterFloatControl mBlurMultiplier; + + // list of all the parameters, listed by name + std::map mParamList; + + F32 mDensitySliderValue; + +private: + // our parameter manager singleton instance + static LLWaterParamManager * sInstance; + +private: + + LLVector4 mWaterPlane; + F32 mWaterFogKS; +}; + +inline void LLWaterParamManager::setDensitySliderValue(F32 val) +{ + val /= 10; + val = 1.0f - val; + val *= val * val; +// val *= val; + mDensitySliderValue = val; +} + +inline LLUUID LLWaterParamManager::getNormalMapID() +{ + return mCurParams.mParamValues["normalMap"].asUUID(); +} + +inline bool LLWaterParamManager::setNormalMapID(const LLUUID& id) +{ + mCurParams.mParamValues["normalMap"] = id; + return true; +} + +inline LLVector2 LLWaterParamManager::getWave1Dir(void) +{ + bool err; + return mCurParams.getVector2("wave1Dir", err); +} + +inline LLVector2 LLWaterParamManager::getWave2Dir(void) +{ + bool err; + return mCurParams.getVector2("wave2Dir", err); +} + +inline F32 LLWaterParamManager::getScaleAbove(void) +{ + bool err; + return mCurParams.getFloat("scaleAbove", err); +} + +inline F32 LLWaterParamManager::getScaleBelow(void) +{ + bool err; + return mCurParams.getFloat("scaleBelow", err); +} + +inline LLVector3 LLWaterParamManager::getNormalScale(void) +{ + bool err; + return mCurParams.getVector3("normScale", err); +} + +inline F32 LLWaterParamManager::getFresnelScale(void) +{ + bool err; + return mCurParams.getFloat("fresnelScale", err); +} + +inline F32 LLWaterParamManager::getFresnelOffset(void) +{ + bool err; + return mCurParams.getFloat("fresnelOffset", err); +} + +inline F32 LLWaterParamManager::getBlurMultiplier(void) +{ + bool err; + return mCurParams.getFloat("blurMultiplier", err); +} + +inline LLColor4 LLWaterParamManager::getFogColor(void) +{ + bool err; + return LLColor4(mCurParams.getVector4("waterFogColor", err)); +} + +#endif diff --git a/linden/indra/newview/llwaterparamset.cpp b/linden/indra/newview/llwaterparamset.cpp new file mode 100644 index 0000000..d3068a7 --- /dev/null +++ b/linden/indra/newview/llwaterparamset.cpp @@ -0,0 +1,233 @@ +/** + * @file llwaterparamset.cpp + * @brief Implementation for the LLWaterParamSet class. + * + * $LicenseInfo:firstyear=2005&license=viewergpl$ + * + * Copyright (c) 2005-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llwaterparamset.h" +#include "llsd.h" + +#include "llfloaterwater.h" +#include "llwaterparammanager.h" +#include "lluictrlfactory.h" +#include "llsliderctrl.h" +#include "llviewerimagelist.h" +#include "llviewercontrol.h" +#include "lluuid.h" + +#include + +#include + +LLWaterParamSet::LLWaterParamSet(void) : + mName("Unnamed Preset") +{ + LLSD vec4; + LLSD vec3; + LLSD real(0.0f); + + vec4 = LLSD::emptyArray(); + vec4.append(22.f/255.f); + vec4.append(43.f/255.f); + vec4.append(54.f/255.f); + vec4.append(0.f/255.f); + + vec3 = LLSD::emptyArray(); + vec3.append(2); + vec3.append(2); + vec3.append(2); + + LLSD wave1, wave2; + wave1 = LLSD::emptyArray(); + wave2 = LLSD::emptyArray(); + wave1.append(0.5f); + wave1.append(-.17f); + wave2.append(0.58f); + wave2.append(-.67f); + + LLUUID normalMap = LLUUID(gViewerArt.getString("water_normal.tga")); + + mParamValues.insert("waterFogColor", vec4); + mParamValues.insert("waterFogDensity", 16.0f); + mParamValues.insert("underWaterFogMod", 0.25f); + mParamValues.insert("normScale", vec3); + mParamValues.insert("fresnelScale", 0.5f); + mParamValues.insert("fresnelOffset", 0.4f); + mParamValues.insert("scaleAbove", 0.025f); + mParamValues.insert("scaleBelow", 0.2f); + mParamValues.insert("blurMultiplier", 0.01f); + mParamValues.insert("wave1Dir", wave1); + mParamValues.insert("wave2Dir", wave2); + mParamValues.insert("normalMap", normalMap); + +} + +void LLWaterParamSet::set(const char * paramName, float x) +{ + // handle case where no array + if(mParamValues[paramName].isReal()) + { + mParamValues[paramName] = x; + } + + // handle array + else if(mParamValues[paramName].isArray() && + mParamValues[paramName][0].isReal()) + { + mParamValues[paramName][0] = x; + } +} + +void LLWaterParamSet::set(const char * paramName, float x, float y) { + mParamValues[paramName][0] = x; + mParamValues[paramName][1] = y; +} + +void LLWaterParamSet::set(const char * paramName, float x, float y, float z) +{ + mParamValues[paramName][0] = x; + mParamValues[paramName][1] = y; + mParamValues[paramName][2] = z; +} + +void LLWaterParamSet::set(const char * paramName, float x, float y, float z, float w) +{ + mParamValues[paramName][0] = x; + mParamValues[paramName][1] = y; + mParamValues[paramName][2] = z; + mParamValues[paramName][3] = w; +} + +void LLWaterParamSet::set(const char * paramName, const float * val) +{ + mParamValues[paramName][0] = val[0]; + mParamValues[paramName][1] = val[1]; + mParamValues[paramName][2] = val[2]; + mParamValues[paramName][3] = val[3]; +} + +void LLWaterParamSet::set(const char * paramName, const LLVector4 & val) +{ + mParamValues[paramName][0] = val.mV[0]; + mParamValues[paramName][1] = val.mV[1]; + mParamValues[paramName][2] = val.mV[2]; + mParamValues[paramName][3] = val.mV[3]; +} + +void LLWaterParamSet::set(const char * paramName, const LLColor4 & val) +{ + mParamValues[paramName][0] = val.mV[0]; + mParamValues[paramName][1] = val.mV[1]; + mParamValues[paramName][2] = val.mV[2]; + mParamValues[paramName][3] = val.mV[3]; +} + +LLVector4 LLWaterParamSet::getVector4(const char * paramName, bool& error) +{ + + // test to see if right type + LLSD cur_val = mParamValues.get(paramName); + if (!cur_val.isArray() || cur_val.size() != 4) + { + error = true; + return LLVector4(0,0,0,0); + } + + LLVector4 val; + val.mV[0] = (F32) cur_val[0].asReal(); + val.mV[1] = (F32) cur_val[1].asReal(); + val.mV[2] = (F32) cur_val[2].asReal(); + val.mV[3] = (F32) cur_val[3].asReal(); + + error = false; + return val; +} + +LLVector3 LLWaterParamSet::getVector3(const char * paramName, bool& error) +{ + + // test to see if right type + LLSD cur_val = mParamValues.get(paramName); + if (!cur_val.isArray()|| cur_val.size() != 3) + { + error = true; + return LLVector3(0,0,0); + } + + LLVector3 val; + val.mV[0] = (F32) cur_val[0].asReal(); + val.mV[1] = (F32) cur_val[1].asReal(); + val.mV[2] = (F32) cur_val[2].asReal(); + + error = false; + return val; +} + +LLVector2 LLWaterParamSet::getVector2(const char * paramName, bool& error) +{ + // test to see if right type + int ttest; + ttest = mParamValues.size(); + LLSD cur_val = mParamValues.get(paramName); + if (!cur_val.isArray() || cur_val.size() != 2) + { + error = true; + return LLVector2(0,0); + } + + LLVector2 val; + val.mV[0] = (F32) cur_val[0].asReal(); + val.mV[1] = (F32) cur_val[1].asReal(); + + error = false; + return val; +} + +F32 LLWaterParamSet::getFloat(const char * paramName, bool& error) +{ + + // test to see if right type + LLSD cur_val = mParamValues.get(paramName); + if (cur_val.isArray() && cur_val.size() != 0) + { + error = false; + return (F32) cur_val[0].asReal(); + } + + if(cur_val.isReal()) + { + error = false; + return (F32) cur_val.asReal(); + } + + error = true; + return 0; +} + diff --git a/linden/indra/newview/llwaterparamset.h b/linden/indra/newview/llwaterparamset.h new file mode 100644 index 0000000..5d2581a --- /dev/null +++ b/linden/indra/newview/llwaterparamset.h @@ -0,0 +1,156 @@ +/** + * @file llwlparamset.h + * @brief Interface for the LLWaterParamSet class. + * + * $LicenseInfo:firstyear=2005&license=viewergpl$ + * + * Copyright (c) 2005-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_WATER_PARAM_SET_H +#define LL_WATER_PARAM_SET_H + +#include +#include + +#include "v4math.h" +#include "v4color.h" +#include "llglslshader.h" + +class LLFloaterWater; +class LLWaterParamSet; + +/// A class representing a set of parameter values for the Water shaders. +class LLWaterParamSet +{ + friend class LLWaterParamManager; + +public: + LLString mName; + +private: + + LLSD mParamValues; + +public: + + LLWaterParamSet(); + + /// Bind this set of parameter values to the uniforms of a particular shader. + void update(LLGLSLShader * shader) const; + + /// set the total llsd + void setAll(const LLSD& val); + + /// get the total llsd + const LLSD& getAll(); + + /// Set a float parameter. + /// \param paramName The name of the parameter to set. + /// \param x The float value to set. + void set(const char * paramName, float x); + + /// Set a float2 parameter. + /// \param paramName The name of the parameter to set. + /// \param x The x component's value to set. + /// \param y The y component's value to set. + void set(const char * paramName, float x, float y); + + /// Set a float3 parameter. + /// \param paramName The name of the parameter to set. + /// \param x The x component's value to set. + /// \param y The y component's value to set. + /// \param z The z component's value to set. + void set(const char * paramName, float x, float y, float z); + + /// Set a float4 parameter. + /// \param paramName The name of the parameter to set. + /// \param x The x component's value to set. + /// \param y The y component's value to set. + /// \param z The z component's value to set. + /// \param w The w component's value to set. + void set(const char * paramName, float x, float y, float z, float w); + + /// Set a float4 parameter. + /// \param paramName The name of the parameter to set. + /// \param val An array of the 4 float values to set the parameter to. + void set(const char * paramName, const float * val); + + /// Set a float4 parameter. + /// \param paramName The name of the parameter to set. + /// \param val A struct of the 4 float values to set the parameter to. + void set(const char * paramName, const LLVector4 & val); + + /// Set a float4 parameter. + /// \param paramName The name of the parameter to set. + /// \param val A struct of the 4 float values to set the parameter to. + void set(const char * paramName, const LLColor4 & val); + + /// Get a float4 parameter. + /// \param paramName The name of the parameter to set. + /// \param error A flag to set if it's not the proper return type + LLVector4 getVector4(const char * paramName, bool& error); + + /// Get a float3 parameter. + /// \param paramName The name of the parameter to set. + /// \param error A flag to set if it's not the proper return type + LLVector3 getVector3(const char * paramName, bool& error); + + /// Get a float2 parameter. + /// \param paramName The name of the parameter to set. + /// \param error A flag to set if it's not the proper return type + LLVector2 getVector2(const char * paramName, bool& error); + + /// Get an integer parameter + /// \param paramName The name of the parameter to set. + /// \param error A flag to set if it's not the proper return type + F32 getFloat(const char * paramName, bool& error); + + /// interpolate two parameter sets + /// \param src The parameter set to start with + /// \param dest The parameter set to end with + /// \param weight The amount to interpolate + void mix(LLWaterParamSet& src, LLWaterParamSet& dest, + F32 weight); + +}; + +inline void LLWaterParamSet::setAll(const LLSD& val) +{ + if(val.isMap()) { + LLSD::map_const_iterator mIt = val.beginMap(); + for(; mIt != val.endMap(); mIt++) + { + mParamValues[mIt->first] = mIt->second; + } + } +} + +inline const LLSD& LLWaterParamSet::getAll() +{ + return mParamValues; +} + +#endif // LL_WaterPARAM_SET_H diff --git a/linden/indra/newview/llwearable.cpp b/linden/indra/newview/llwearable.cpp index 0cadd5c..9365eeb 100644 --- a/linden/indra/newview/llwearable.cpp +++ b/linden/indra/newview/llwearable.cpp @@ -132,8 +132,6 @@ LLWearable::LLWearable(const LLAssetID& asset_id) : LLWearable::~LLWearable() { - mVisualParamMap.deleteAllData(); - mTEMap.deleteAllData(); } @@ -227,35 +225,37 @@ BOOL LLWearable::exportFile( FILE* file ) } // parameters - S32 num_parameters = mVisualParamMap.getLength(); + S32 num_parameters = mVisualParamMap.size(); if( fprintf( file, "parameters %d\n", num_parameters ) < 0 ) { return FALSE; } char s[ MAX_STRING ]; /* Flawfinder: ignore */ - for( F32* param_weightp = mVisualParamMap.getFirstData(); param_weightp; param_weightp = mVisualParamMap.getNextData() ) + for (param_map_t::iterator iter = mVisualParamMap.begin(); + iter != mVisualParamMap.end(); ++iter) { - S32 param_id = mVisualParamMap.getCurrentKeyWithoutIncrement(); - if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( *param_weightp, s ) ) < 0 ) + S32 param_id = iter->first; + F32 param_weight = iter->second; + if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight, s ) ) < 0 ) { return FALSE; } } // texture entries - S32 num_textures = mTEMap.getLength(); + S32 num_textures = mTEMap.size(); if( fprintf( file, "textures %d\n", num_textures ) < 0 ) { return FALSE; } - for( LLUUID* image_id = mTEMap.getFirstData(); image_id; image_id = mTEMap.getNextData() ) + for (te_map_t::iterator iter = mTEMap.begin(); + iter != mTEMap.end(); ++iter) { - S32 te = mTEMap.getCurrentKeyWithoutIncrement(); - char image_id_string[UUID_STR_LENGTH]; /* Flawfinder: ignore */ - image_id->toString( image_id_string ); - if( fprintf( file, "%d %s\n", te, image_id_string) < 0 ) + S32 te = iter->first; + LLUUID& image_id = iter->second; + if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 ) { return FALSE; } @@ -418,7 +418,7 @@ BOOL LLWearable::importFile( FILE* file ) llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl; return FALSE; } - mVisualParamMap.addData( param_id, new F32(param_weight) ); + mVisualParamMap[param_id] = param_weight; } // textures header @@ -450,7 +450,7 @@ BOOL LLWearable::importFile( FILE* file ) return FALSE; } - mTEMap.addData( te, new LLUUID( text_buffer ) ); + mTEMap[te] = LLUUID(text_buffer ); } return TRUE; @@ -488,13 +488,13 @@ BOOL LLWearable::isOldVersion() if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { param_count++; - if( !mVisualParamMap.checkKey( param->getID() ) ) + if( !is_in_map(mVisualParamMap, param->getID() ) ) { return TRUE; } } } - if( param_count != mVisualParamMap.getLength() ) + if( param_count != mVisualParamMap.size() ) { return TRUE; } @@ -506,13 +506,13 @@ BOOL LLWearable::isOldVersion() if( LLVOAvatar::getTEWearableType( te ) == mType ) { te_count++; - if( !mTEMap.checkKey( te ) ) + if( !is_in_map(mTEMap, te ) ) { return TRUE; } } } - if( te_count != mTEMap.getLength() ) + if( te_count != mTEMap.size() ) { return TRUE; } @@ -543,16 +543,8 @@ BOOL LLWearable::isDirty() { if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { - F32* weightp = mVisualParamMap.getIfThere( param->getID() ); - F32 weight; - if( weightp ) - { - weight = llclamp( *weightp, param->getMinWeight(), param->getMaxWeight() ); - } - else - { - weight = param->getDefaultWeight(); - } + F32 weight = get_if_there(mVisualParamMap, param->getID(), param->getDefaultWeight()); + weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() ); U8 a = F32_to_U8( param->getWeight(), param->getMinWeight(), param->getMaxWeight() ); U8 b = F32_to_U8( weight, param->getMinWeight(), param->getMaxWeight() ); @@ -573,8 +565,7 @@ BOOL LLWearable::isDirty() llassert( 0 ); continue; } - LLUUID* mapped_image_id = mTEMap.getIfThere( te ); - const LLUUID& image_id = mapped_image_id ? *mapped_image_id : LLVOAvatar::getDefaultTEImageID( te ); + const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatar::getDefaultTEImageID( te ) ); if( avatar_image->getID() != image_id ) { return TRUE; @@ -603,24 +594,24 @@ void LLWearable::setParamsToDefaults() return; } - mVisualParamMap.deleteAllData(); + mVisualParamMap.clear(); for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { - mVisualParamMap.addData( param->getID(), new F32( param->getDefaultWeight() ) ); + mVisualParamMap[param->getID()] = param->getDefaultWeight(); } } } void LLWearable::setTexturesToDefaults() { - mTEMap.deleteAllData(); + mTEMap.clear(); for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ ) { if( LLVOAvatar::getTEWearableType( te ) == mType ) { - mTEMap.addData( te, new LLUUID( LLVOAvatar::getDefaultTEImageID( te ) ) ); + mTEMap[te] = LLVOAvatar::getDefaultTEImageID( te ); } } } @@ -643,30 +634,15 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { S32 param_id = param->getID(); - F32* weight = mVisualParamMap.getIfThere( param_id ); - if( weight ) + F32 weight = get_if_there(mVisualParamMap, param_id, param->getDefaultWeight()); + // only animate with user-originated changes + if (set_by_user) { - // only animate with user-originated changes - if (set_by_user) - { - param->setAnimationTarget(*weight, set_by_user); - } - else - { - avatar->setVisualParamWeight( param_id, *weight, set_by_user ); - } + param->setAnimationTarget(weight, set_by_user); } else { - // only animate with user-originated changes - if (set_by_user) - { - param->setAnimationTarget(param->getDefaultWeight(), set_by_user); - } - else - { - avatar->setVisualParamWeight( param_id, param->getDefaultWeight(), set_by_user ); - } + avatar->setVisualParamWeight( param_id, weight, set_by_user ); } } } @@ -682,8 +658,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) { if( LLVOAvatar::getTEWearableType( te ) == mType ) { - LLUUID* mapped_image_id = mTEMap.getIfThere( te ); - const LLUUID& image_id = mapped_image_id ? *mapped_image_id : LLVOAvatar::getDefaultTEImageID( te ); + const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatar::getDefaultTEImageID( te ) ); LLViewerImage* image = gImageList.getImage( image_id ); avatar->setLocTexTE( te, image, set_by_user ); } @@ -792,16 +767,16 @@ void LLWearable::readFromAvatar() mDefinitionVersion = LLWearable::sCurrentDefinitionVersion; - mVisualParamMap.deleteAllData(); + mVisualParamMap.clear(); for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) { if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { - mVisualParamMap.addData( param->getID(), new F32( param->getWeight() ) ); + mVisualParamMap[param->getID()] = param->getWeight(); } } - mTEMap.deleteAllData(); + mTEMap.clear(); for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ ) { if( LLVOAvatar::getTEWearableType( te ) == mType ) @@ -809,7 +784,7 @@ void LLWearable::readFromAvatar() LLViewerImage* image = avatar->getTEImage( te ); if( image ) { - mTEMap.addData( te, new LLUUID( image->getID() ) ); + mTEMap[te] = image->getID(); } } } @@ -847,9 +822,8 @@ void LLWearable::copyDataFrom( LLWearable* src ) if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) ) { S32 id = param->getID(); - F32* weightp = src->mVisualParamMap.getIfThere( id ); - F32 weight = weightp ? *weightp : param->getDefaultWeight(); - mVisualParamMap.addData( id, new F32( weight ) ); + F32 weight = get_if_there(src->mVisualParamMap, id, param->getDefaultWeight() ); + mVisualParamMap[id] = weight; } } @@ -858,9 +832,8 @@ void LLWearable::copyDataFrom( LLWearable* src ) { if( LLVOAvatar::getTEWearableType( te ) == mType ) { - LLUUID* mapped_image_id = src->mTEMap.getIfThere( te ); - const LLUUID& image_id = mapped_image_id ? *mapped_image_id : LLVOAvatar::getDefaultTEImageID( te ); - mTEMap.addData( te, new LLUUID( image_id ) ); + const LLUUID& image_id = get_if_there(src->mTEMap, te, LLVOAvatar::getDefaultTEImageID( te ) ); + mTEMap[te] = image_id; } } } @@ -985,21 +958,21 @@ void LLWearable::dump() //mSaleInfo llinfos << " Params:" << llendl; - for( F32* param_weightp = mVisualParamMap.getFirstData(); - param_weightp; - param_weightp = mVisualParamMap.getNextData() ) + for (param_map_t::iterator iter = mVisualParamMap.begin(); + iter != mVisualParamMap.end(); ++iter) { - S32 param_id = mVisualParamMap.getCurrentKeyWithoutIncrement(); - llinfos << " " << param_id << " " << *param_weightp << llendl; + S32 param_id = iter->first; + F32 param_weight = iter->second; + llinfos << " " << param_id << " " << param_weight << llendl; } llinfos << " Textures:" << llendl; - for( LLUUID* image_id = mTEMap.getFirstData(); - image_id; - image_id = mTEMap.getNextData() ) + for (te_map_t::iterator iter = mTEMap.begin(); + iter != mTEMap.end(); ++iter) { - S32 te = mTEMap.getCurrentKeyWithoutIncrement(); - llinfos << " " << te << " " << *image_id << llendl; + S32 te = iter->first; + LLUUID& image_id = iter->second; + llinfos << " " << te << " " << image_id << llendl; } } diff --git a/linden/indra/newview/llwearable.h b/linden/indra/newview/llwearable.h index da259a0..aa4b3dd 100644 --- a/linden/indra/newview/llwearable.h +++ b/linden/indra/newview/llwearable.h @@ -33,7 +33,6 @@ #define LL_LLWEARABLE_H #include "lluuid.h" -#include "llptrskipmap.h" #include "llstring.h" #include "llpermissions.h" #include "llsaleinfo.h" @@ -132,8 +131,10 @@ private: LLTransactionID mTransactionID; EWearableType mType; - LLPtrSkipMap mVisualParamMap; // maps visual param id to weight - LLPtrSkipMap mTEMap; // maps TE to Image ID + typedef std::map param_map_t; + param_map_t mVisualParamMap; // maps visual param id to weight + typedef std::map te_map_t; + te_map_t mTEMap; // maps TE to Image ID static const char* sTypeName[ WT_COUNT ]; static const char* sTypeLabel[ WT_COUNT ]; diff --git a/linden/indra/newview/llwearablelist.cpp b/linden/indra/newview/llwearablelist.cpp index e1dabea..22b8142 100644 --- a/linden/indra/newview/llwearablelist.cpp +++ b/linden/indra/newview/llwearablelist.cpp @@ -73,13 +73,14 @@ struct LLWearableArrivedData LLWearableList::~LLWearableList() { - mList.deleteAllData(); + for_each(mList.begin(), mList.end(), DeletePairedPointer()); + mList.clear(); } void LLWearableList::getAsset( const LLAssetID& assetID, const LLString& wearable_name, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLWearable*, void* userdata), void* userdata ) { llassert( (asset_type == LLAssetType::AT_CLOTHING) || (asset_type == LLAssetType::AT_BODYPART) ); - LLWearable* instance = mList.getIfThere( assetID ); + LLWearable* instance = get_if_there(mList, assetID, (LLWearable*)NULL ); if( instance ) { asset_arrived_callback( instance, userdata ); diff --git a/linden/indra/newview/llwearablelist.h b/linden/indra/newview/llwearablelist.h index e7acdd5..cd15b78 100644 --- a/linden/indra/newview/llwearablelist.h +++ b/linden/indra/newview/llwearablelist.h @@ -33,7 +33,6 @@ #define LL_LLWEARABLELIST_H #include "llwearable.h" -#include "llskiplist.h" #include "lluuid.h" #include "llassetstorage.h" @@ -43,9 +42,7 @@ public: LLWearableList() {} ~LLWearableList(); - S32 getLength() { return mList.getLength(); } - const LLWearable* getFirst() { return mList.getFirstData(); } - const LLWearable* getNext() { return mList.getNextData(); } + S32 getLength() { return mList.size(); } void getAsset( const LLAssetID& assetID, @@ -65,7 +62,7 @@ public: static void processGetAssetReply(const char* filename, const LLAssetID& assetID, void* user_data, S32 status, LLExtStat ext_status); protected: - LLPtrSkipMap< const LLUUID, LLWearable* > mList; + std::map< LLUUID, LLWearable* > mList; }; extern LLWearableList gWearableList; diff --git a/linden/indra/newview/llweb.cpp b/linden/indra/newview/llweb.cpp index 97d2cbf..dcae7a0 100644 --- a/linden/indra/newview/llweb.cpp +++ b/linden/indra/newview/llweb.cpp @@ -36,8 +36,8 @@ #include "llwindow.h" -//#include "llfloaterhtml.h" #include "llviewercontrol.h" +#include "llfloaterhtmlhelp.h" // static void LLWeb::initClass() @@ -48,7 +48,14 @@ void LLWeb::initClass() // static void LLWeb::loadURL(const std::string& url) { - loadURLExternal(url); + if (gSavedSettings.getBOOL("UseExternalBrowser")) + { + loadURLExternal(url); + } + else + { + LLFloaterMediaBrowser::showInstance(url); + } } @@ -56,9 +63,7 @@ void LLWeb::loadURL(const std::string& url) void LLWeb::loadURLExternal(const std::string& url) { std::string escaped_url = escapeURL(url); -#if LL_LIBXUL_ENABLED spawn_web_browser(escaped_url.c_str()); -#endif } diff --git a/linden/indra/newview/llwebbrowserctrl.cpp b/linden/indra/newview/llwebbrowserctrl.cpp index 858c88c..763f73d 100644 --- a/linden/indra/newview/llwebbrowserctrl.cpp +++ b/linden/indra/newview/llwebbrowserctrl.cpp @@ -31,7 +31,6 @@ #include "llviewerprecompiledheaders.h" -#if LL_LIBXUL_ENABLED #include "llwebbrowserctrl.h" @@ -45,6 +44,7 @@ #include "llviewercontrol.h" #include "llviewerwindow.h" #include "llweb.h" +#include "llglimmediate.h" // linden library includes #include "llfocusmgr.h" @@ -57,44 +57,50 @@ const S32 MAX_TEXTURE_DIMENSION = 2048; LLWebBrowserCtrl::LLWebBrowserCtrl( const std::string& name, const LLRect& rect ) : LLUICtrl( name, rect, FALSE, NULL, NULL ), mTextureDepthBytes( 4 ), + mWebBrowserImage( 0 ), mEmbeddedBrowserWindowId( 0 ), mBorder(NULL), mFrequentUpdates( true ), + mForceUpdate( false ), mOpenLinksInExternalBrowser( false ), mOpenLinksInInternalBrowser( false ), mOpenAppSLURLs( false ), mHomePageUrl( "" ), mIgnoreUIScale( true ), - mAlwaysRefresh( false ) -{ - S32 screen_width = mIgnoreUIScale ? llround((F32)mRect.getWidth() * LLUI::sGLScaleFactor.mV[VX]) : llround((F32)mRect.getWidth() * gViewerWindow->getDisplayScale().mV[VX]); - S32 screen_height = mIgnoreUIScale ? llround((F32)mRect.getHeight() * LLUI::sGLScaleFactor.mV[VY]) : llround((F32)mRect.getHeight() * gViewerWindow->getDisplayScale().mV[VY]); - - // create a new browser window - { -#if LL_LINUX - // Yuck, Mozilla init plays with the locale - push/pop - // the locale to protect it, as exotic/non-C locales - // causes our code lots of general critical weirdness - // and crashness. (SL-35450) - std::string saved_locale = setlocale(LC_ALL, NULL); -#endif // LL_LINUX - mEmbeddedBrowserWindowId = LLMozLib::getInstance()->createBrowserWindow( gViewerWindow->getPlatformWindow(), screen_width, screen_height ); -#if LL_LINUX - setlocale(LC_ALL, saved_locale.c_str() ); -#endif // LL_LINUX + mAlwaysRefresh( false ), + mMediaSource( 0 ) +{ + S32 screen_width = mIgnoreUIScale ? + llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth(); + S32 screen_height = mIgnoreUIScale ? + llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight(); + + + LLMediaManager *mgr = LLMediaManager::getInstance(); + + if (!mgr) + { + llwarns << "cannot get media manager" << llendl; + return; + } + + mMediaSource = mgr->createSourceFromMimeType("http", "text/html" ); + if ( !mMediaSource ) + { + llwarns << "media source create failed " << llendl; + return; } - // change color to black so transisitons aren't so noticable (this should be in XML eventually) - LLMozLib::getInstance()->setBackgroundColor( mEmbeddedBrowserWindowId, 0x00, 0x00, 0x00 ); + // mMediaSource->init(); + mMediaSource->addCommand( LLMediaBase::COMMAND_START ); // observe the browser so we can trap HREF events) - LLMozLib::getInstance()->addObserver( mEmbeddedBrowserWindowId, this ); + mMediaSource->addObserver(this); // create a new texture (based on LLDynamic texture) that will be used to display the output - mWebBrowserImage = new LLWebBrowserTexture( screen_width, screen_height, this, mEmbeddedBrowserWindowId ); + mWebBrowserImage = new LLWebBrowserTexture( screen_width, screen_height, this, mMediaSource ); - LLRect border_rect( 0, mRect.getHeight() + 2, mRect.getWidth() + 2, 0 ); + LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 ); mBorder = new LLViewBorder( "web control border", border_rect, LLViewBorder::BEVEL_IN ); addChild( mBorder ); } @@ -103,9 +109,19 @@ LLWebBrowserCtrl::LLWebBrowserCtrl( const std::string& name, const LLRect& rect // note: this is now a singleton and destruction happens via initClass() now LLWebBrowserCtrl::~LLWebBrowserCtrl() { - LLMozLib::getInstance()->remObserver( mEmbeddedBrowserWindowId, this ); + LLMediaManager *mgr = LLMediaManager::getInstance(); - LLMozLib::getInstance()->destroyBrowserWindow( mEmbeddedBrowserWindowId ); + if (!mgr) + { + llwarns << "cannot get media manager" << llendl; + return; + } + + if (mMediaSource) + { + mgr->destroySource(mMediaSource); + mMediaSource = NULL; + } if ( mWebBrowserImage ) { @@ -163,7 +179,9 @@ void LLWebBrowserCtrl::setOpenAppSLURLs( bool valIn ) BOOL LLWebBrowserCtrl::handleHover( S32 x, S32 y, MASK mask ) { convertInputCoords(x, y); - LLMozLib::getInstance()->mouseMove( mEmbeddedBrowserWindowId, x, y ); + + if (mMediaSource) + mMediaSource->mouseMove(x, y); return TRUE; } @@ -172,12 +190,8 @@ BOOL LLWebBrowserCtrl::handleHover( S32 x, S32 y, MASK mask ) // BOOL LLWebBrowserCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks ) { - LLMozLib::getInstance()->scrollByLines( mEmbeddedBrowserWindowId, clicks ); - - // note: this isn't really necessary right now since the page is updated - // on a timer but if that becomes too burdensome and the page is only updated - // once after load then this will be necessary - LLMozLib::getInstance()->grabBrowserWindow( mEmbeddedBrowserWindowId ); + if (mMediaSource) + mMediaSource->scrollByLines(clicks); return TRUE; } @@ -187,8 +201,10 @@ BOOL LLWebBrowserCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks ) BOOL LLWebBrowserCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) { convertInputCoords(x, y); - LLMozLib::getInstance()->mouseUp( mEmbeddedBrowserWindowId, x, y ); + if (mMediaSource) + mMediaSource->mouseUp(x, y); + gViewerWindow->setMouseCapture( NULL ); return TRUE; @@ -199,8 +215,10 @@ BOOL LLWebBrowserCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) BOOL LLWebBrowserCtrl::handleMouseDown( S32 x, S32 y, MASK mask ) { convertInputCoords(x, y); - LLMozLib::getInstance()->mouseDown( mEmbeddedBrowserWindowId, x, y ); + if (mMediaSource) + mMediaSource->mouseDown(x, y); + gViewerWindow->setMouseCapture( this ); setFocus( TRUE ); @@ -213,7 +231,9 @@ BOOL LLWebBrowserCtrl::handleMouseDown( S32 x, S32 y, MASK mask ) BOOL LLWebBrowserCtrl::handleDoubleClick( S32 x, S32 y, MASK mask ) { convertInputCoords(x, y); - LLMozLib::getInstance()->mouseLeftDoubleClick( mEmbeddedBrowserWindowId, x, y ); + + if (mMediaSource) + mMediaSource->mouseLeftDoubleClick( x, y ); gViewerWindow->setMouseCapture( this ); @@ -226,7 +246,9 @@ BOOL LLWebBrowserCtrl::handleDoubleClick( S32 x, S32 y, MASK mask ) // void LLWebBrowserCtrl::onFocusReceived() { - LLMozLib::getInstance()->focusBrowser( mEmbeddedBrowserWindowId, true ); + if (mMediaSource) + mMediaSource->focus(true); + LLUICtrl::onFocusReceived(); } @@ -235,7 +257,8 @@ void LLWebBrowserCtrl::onFocusReceived() // void LLWebBrowserCtrl::onFocusLost() { - LLMozLib::getInstance()->focusBrowser( mEmbeddedBrowserWindowId, false ); + if (mMediaSource) + mMediaSource->focus(false); gViewerWindow->focusClient(); @@ -246,7 +269,7 @@ void LLWebBrowserCtrl::onFocusLost() // BOOL LLWebBrowserCtrl::handleKey( KEY key, MASK mask, BOOL called_from_parent ) { - unsigned long nskey; + unsigned long media_key; // First, turn SL internal keycode enum into Mozilla keycode enum @@ -254,46 +277,48 @@ BOOL LLWebBrowserCtrl::handleKey( KEY key, MASK mask, BOOL called_from_parent ) // go through handleUnicodeChar(). This table could be more complete // than it is, but I think this covers all of the important // non-printables. + switch (key) { case KEY_BACKSPACE: - nskey = LL_DOM_VK_BACK_SPACE; break; + media_key = LL_MEDIA_KEY_BACKSPACE; break; case KEY_TAB: - nskey = LL_DOM_VK_TAB; break; + media_key = LL_MEDIA_KEY_TAB; break; case KEY_RETURN: - nskey = LL_DOM_VK_RETURN; break; + media_key = LL_MEDIA_KEY_RETURN; break; case KEY_PAD_RETURN: - nskey = LL_DOM_VK_ENTER; break; + media_key = LL_MEDIA_KEY_PAD_RETURN; break; case KEY_ESCAPE: - nskey = LL_DOM_VK_ESCAPE; break; + media_key = LL_MEDIA_KEY_ESCAPE; break; case KEY_PAGE_UP: - nskey = LL_DOM_VK_PAGE_UP; break; + media_key = LL_MEDIA_KEY_PAGE_UP; break; case KEY_PAGE_DOWN: - nskey = LL_DOM_VK_PAGE_DOWN; break; + media_key = LL_MEDIA_KEY_PAGE_DOWN; break; case KEY_END: - nskey = LL_DOM_VK_END; break; + media_key = LL_MEDIA_KEY_END; break; case KEY_HOME: - nskey = LL_DOM_VK_HOME; break; + media_key = LL_MEDIA_KEY_HOME; break; case KEY_LEFT: - nskey = LL_DOM_VK_LEFT; break; + media_key = LL_MEDIA_KEY_LEFT; break; case KEY_UP: - nskey = LL_DOM_VK_UP; break; + media_key = LL_MEDIA_KEY_UP; break; case KEY_RIGHT: - nskey = LL_DOM_VK_RIGHT; break; + media_key = LL_MEDIA_KEY_RIGHT; break; case KEY_DOWN: - nskey = LL_DOM_VK_DOWN; break; + media_key = LL_MEDIA_KEY_DOWN; break; case KEY_INSERT: - nskey = LL_DOM_VK_INSERT; break; + media_key = LL_MEDIA_KEY_INSERT; break; case KEY_DELETE: - nskey = LL_DOM_VK_DELETE; break; + media_key = LL_MEDIA_KEY_DELETE; break; default: llinfos << "Don't know how to map LL keycode " << U32(key) << " to DOM key. Ignoring." << llendl; return FALSE; // don't know how to map this key. } - LLMozLib::getInstance()->keyPress( mEmbeddedBrowserWindowId, nskey ); - + if (mMediaSource) + mMediaSource->keyPress(media_key); + return TRUE; } @@ -303,7 +328,8 @@ BOOL LLWebBrowserCtrl::handleUnicodeChar(llwchar uni_char, BOOL called_from_pare if (uni_char >= 32 // discard 'control' characters && uni_char != 127) // SDL thinks this is 'delete' - yuck. { - LLMozLib::getInstance()->unicodeInput( mEmbeddedBrowserWindowId, uni_char ); + if (mMediaSource) + mMediaSource->unicodeInput(uni_char); } return TRUE; @@ -329,13 +355,14 @@ void LLWebBrowserCtrl::onVisibilityChange ( BOOL new_visibility ) // void LLWebBrowserCtrl::reshape( S32 width, S32 height, BOOL called_from_parent ) { - S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : llround((F32)width * gViewerWindow->getDisplayScale().mV[VX]); - S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : llround((F32)height * gViewerWindow->getDisplayScale().mV[VY]); + S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width; + S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height; // when floater is minimized, these sizes are negative - if ( screen_height > 0 && screen_width > 0 ) + if ( mWebBrowserImage && screen_height > 0 && screen_width > 0 ) { mWebBrowserImage->resize( screen_width, screen_height ); + mForceUpdate = true; } LLUICtrl::reshape( width, height, called_from_parent ); @@ -345,42 +372,51 @@ void LLWebBrowserCtrl::reshape( S32 width, S32 height, BOOL called_from_parent ) // void LLWebBrowserCtrl::navigateBack() { - LLMozLib::getInstance()->navigateBack( mEmbeddedBrowserWindowId ); + if (mMediaSource) + mMediaSource->navigateBack(); } //////////////////////////////////////////////////////////////////////////////// // void LLWebBrowserCtrl::navigateForward() { - LLMozLib::getInstance()->navigateForward( mEmbeddedBrowserWindowId ); + if (mMediaSource) + mMediaSource->navigateForward(); } //////////////////////////////////////////////////////////////////////////////// // bool LLWebBrowserCtrl::canNavigateBack() { - return LLMozLib::getInstance()->canNavigateBack( mEmbeddedBrowserWindowId ); + if (mMediaSource) + return mMediaSource->canNavigateBack(); + else + return false; } //////////////////////////////////////////////////////////////////////////////// // bool LLWebBrowserCtrl::canNavigateForward() { - return LLMozLib::getInstance()->canNavigateForward( mEmbeddedBrowserWindowId ); + if (mMediaSource) + return mMediaSource->canNavigateForward(); + else + return false; } //////////////////////////////////////////////////////////////////////////////// // + bool LLWebBrowserCtrl::set404RedirectUrl( std::string redirect_url ) { - return LLMozLib::getInstance()->set404RedirectUrl( mEmbeddedBrowserWindowId, redirect_url ); + return mMediaSource->set404RedirectUrl( redirect_url ); } //////////////////////////////////////////////////////////////////////////////// // bool LLWebBrowserCtrl::clr404RedirectUrl() { - return LLMozLib::getInstance()->clr404RedirectUrl( mEmbeddedBrowserWindowId ); + return mMediaSource->clr404RedirectUrl(); } //////////////////////////////////////////////////////////////////////////////// @@ -395,19 +431,22 @@ void LLWebBrowserCtrl::navigateTo( std::string urlIn ) { if ( LLString::compareInsensitive( urlIn.substr( 0, protocol.length() ).c_str(), protocol.c_str() ) != 0 ) { - LLMozLib::getInstance()->navigateTo( mEmbeddedBrowserWindowId, urlIn ); + if (mMediaSource) + mMediaSource->navigateTo(urlIn); } } else if ( urlIn.length() >= protocol2.length() ) { if ( LLString::compareInsensitive( urlIn.substr( 0, protocol2.length() ).c_str(), protocol2.c_str() ) != 0 ) { - LLMozLib::getInstance()->navigateTo( mEmbeddedBrowserWindowId, urlIn ); + if (mMediaSource) + mMediaSource->navigateTo(urlIn); } } else { - LLMozLib::getInstance()->navigateTo( mEmbeddedBrowserWindowId, urlIn ); + if (mMediaSource) + mMediaSource->navigateTo(urlIn); } } @@ -455,7 +494,8 @@ void LLWebBrowserCtrl::navigateHome() { if( mHomePageUrl.length() ) { - LLMozLib::getInstance()->navigateTo( mEmbeddedBrowserWindowId, mHomePageUrl ); + if (mMediaSource) + mMediaSource->navigateTo(mHomePageUrl); }; } @@ -468,6 +508,15 @@ void LLWebBrowserCtrl::setHomePageUrl( const std::string urlIn ) //////////////////////////////////////////////////////////////////////////////// // +bool LLWebBrowserCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned int blue) +{ + if (mMediaSource) + return mMediaSource->setCaretColor(red, green, blue); + else + return false; +} +//////////////////////////////////////////////////////////////////////////////// +// std::string LLWebBrowserCtrl::getHomePageUrl() { return mHomePageUrl; @@ -480,9 +529,12 @@ void LLWebBrowserCtrl::draw() if ( ! getVisible() ) return; + if ( ! mWebBrowserImage ) + return; + // NOTE: optimization needed here - probably only need to do this once // unless tearoffs change the parent which they probably do. - LLUICtrl* ptr = (LLUICtrl*)findRootMostFocusRoot(); + const LLUICtrl* ptr = findRootMostFocusRoot(); if ( ptr && ptr->hasFocus() ) { setFrequentUpdates( true ); @@ -510,29 +562,29 @@ void LLWebBrowserCtrl::draw() // scale texture to fit the space using texture coords mWebBrowserImage->bindTexture(); - glColor4fv( LLColor4::white.mV ); + gGL.color4fv( LLColor4::white.mV ); F32 max_u = ( F32 )mWebBrowserImage->getBrowserWidth() / ( F32 )mWebBrowserImage->getWidth(); F32 max_v = ( F32 )mWebBrowserImage->getBrowserHeight() / ( F32 )mWebBrowserImage->getHeight(); // draw the browser - glBlendFunc( GL_ONE, GL_ZERO ); - glBegin( GL_QUADS ); + gGL.blendFunc( GL_ONE, GL_ZERO ); + gGL.begin( GL_QUADS ); { // render using web browser reported width and height, instead of trying to invert GL scale - glTexCoord2f( max_u, 0.f ); - glVertex2i( mWebBrowserImage->getBrowserWidth(), mWebBrowserImage->getBrowserHeight() ); + gGL.texCoord2f( max_u, max_v ); + gGL.vertex2i( mWebBrowserImage->getBrowserWidth(), mWebBrowserImage->getBrowserHeight() ); - glTexCoord2f( 0.f, 0.f ); - glVertex2i( 0, mWebBrowserImage->getBrowserHeight() ); + gGL.texCoord2f( 0.f, max_v ); + gGL.vertex2i( 0, mWebBrowserImage->getBrowserHeight() ); - glTexCoord2f( 0.f, max_v ); - glVertex2i( 0, 0 ); + gGL.texCoord2f( 0.f, 0.f ); + gGL.vertex2i( 0, 0 ); - glTexCoord2f( max_u, max_v ); - glVertex2i( mWebBrowserImage->getBrowserWidth(), 0 ); + gGL.texCoord2f( max_u, 0.f ); + gGL.vertex2i( mWebBrowserImage->getBrowserWidth(), 0 ); } - glEnd(); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + gGL.end(); + gGL.blendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); } glPopMatrix(); @@ -546,15 +598,15 @@ void LLWebBrowserCtrl::draw() void LLWebBrowserCtrl::convertInputCoords(S32& x, S32& y) { - x = mIgnoreUIScale ? llround((F32)x * LLUI::sGLScaleFactor.mV[VX]) : llround((F32)x * gViewerWindow->getDisplayScale().mV[VX]); - y = mIgnoreUIScale ? llround((F32)(mRect.getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]) : llround((F32)(mRect.getHeight() - y) * gViewerWindow->getDisplayScale().mV[VY]); + x = mIgnoreUIScale ? llround((F32)x * LLUI::sGLScaleFactor.mV[VX]) : x; + y = mIgnoreUIScale ? llround((F32)(getRect().getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight() - y; } //////////////////////////////////////////////////////////////////////////////// // virtual void LLWebBrowserCtrl::onNavigateBegin( const EventType& eventIn ) { - LLWebBrowserCtrlEvent event; + LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); mEventEmitter.update( &LLWebBrowserCtrlObserver::onNavigateBegin, event ); } @@ -563,7 +615,7 @@ void LLWebBrowserCtrl::onNavigateBegin( const EventType& eventIn ) void LLWebBrowserCtrl::onNavigateComplete( const EventType& eventIn ) { // chain this event on to observers of an instance of LLWebBrowserCtrl - LLWebBrowserCtrlEvent event; + LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); mEventEmitter.update( &LLWebBrowserCtrlObserver::onNavigateComplete, event ); } @@ -606,16 +658,29 @@ void LLWebBrowserCtrl::onLocationChange( const EventType& eventIn ) //////////////////////////////////////////////////////////////////////////////// // virtual +void LLWebBrowserCtrl::onMediaContentsChange( const EventType& event_in ) +{ + if ( mWebBrowserImage ) + { + mWebBrowserImage->setNeedsUpdate(); + mForceUpdate = true; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual void LLWebBrowserCtrl::onClickLinkHref( const EventType& eventIn ) { - const std::string protocol( "http://" ); + const std::string protocol1( "http://" ); + const std::string protocol2( "https://" ); if( mOpenLinksInExternalBrowser ) { if ( eventIn.getStringValue().length() ) { - if ( LLString::compareInsensitive( eventIn.getStringValue().substr( 0, protocol.length() ).c_str(), protocol.c_str() ) == 0 ) + if ( LLString::compareInsensitive( eventIn.getStringValue().substr( 0, protocol1.length() ).c_str(), protocol1.c_str() ) == 0 || + LLString::compareInsensitive( eventIn.getStringValue().substr( 0, protocol2.length() ).c_str(), protocol2.c_str() ) == 0 ) { - LLWeb::loadURL( eventIn.getStringValue() ); + LLWeb::loadURLExternal( eventIn.getStringValue() ); }; }; } @@ -624,15 +689,14 @@ void LLWebBrowserCtrl::onClickLinkHref( const EventType& eventIn ) { if ( eventIn.getStringValue().length() ) { - if ( LLString::compareInsensitive( eventIn.getStringValue().substr( 0, protocol.length() ).c_str(), protocol.c_str() ) == 0 ) + if ( LLString::compareInsensitive( eventIn.getStringValue().substr( 0, protocol1.length() ).c_str(), protocol1.c_str() ) == 0 || + LLString::compareInsensitive( eventIn.getStringValue().substr( 0, protocol2.length() ).c_str(), protocol2.c_str() ) == 0 ) { // If we spawn a new LLFloaterHTML, assume we want it to // follow this LLWebBrowserCtrl's setting for whether or // not to open secondlife:///app/ links. JC. - LLFloaterHtml::getInstance()->show( - eventIn.getStringValue(), - "Second Life Browser", - mOpenAppSLURLs); + bool open_links_externally = false; + LLFloaterHtml::getInstance()->show( eventIn.getStringValue(), "Second Life Browser", mOpenAppSLURLs, open_links_externally); }; }; }; @@ -644,7 +708,7 @@ void LLWebBrowserCtrl::onClickLinkHref( const EventType& eventIn ) //////////////////////////////////////////////////////////////////////////////// // virtual -void LLWebBrowserCtrl::onClickLinkSecondLife( const EventType& eventIn ) +void LLWebBrowserCtrl::onClickLinkNoFollow( const EventType& eventIn ) { std::string url = eventIn.getStringValue(); if (LLURLDispatcher::isSLURLCommand(url) @@ -659,17 +723,18 @@ void LLWebBrowserCtrl::onClickLinkSecondLife( const EventType& eventIn ) // chain this event on to observers of an instance of LLWebBrowserCtrl LLWebBrowserCtrlEvent event( eventIn.getStringValue() ); - mEventEmitter.update( &LLWebBrowserCtrlObserver::onClickLinkSecondLife, event ); + mEventEmitter.update( &LLWebBrowserCtrlObserver::onClickLinkNoFollow, event ); } //////////////////////////////////////////////////////////////////////////////// // -LLWebBrowserTexture::LLWebBrowserTexture( S32 width, S32 height, LLWebBrowserCtrl* browserCtrl, int browserWindowId ) : +LLWebBrowserTexture::LLWebBrowserTexture( S32 width, S32 height, LLWebBrowserCtrl* browserCtrl, LLMediaBase *media_source ) : LLDynamicTexture( 512, 512, 4, ORDER_FIRST, TRUE ), mLastBrowserDepth( 0 ), + mNeedsUpdate( true ), mWebBrowserCtrl( browserCtrl ), - mEmbeddedBrowserWindowId( browserWindowId ) + mMediaSource(media_source) { mElapsedTime.start(); @@ -685,35 +750,71 @@ LLWebBrowserTexture::~LLWebBrowserTexture() //////////////////////////////////////////////////////////////////////////////// // -BOOL LLWebBrowserTexture::render() +BOOL LLWebBrowserTexture::needsRender() { - // frequent updates turned on? - if ( mWebBrowserCtrl->getFrequentUpdates() || mWebBrowserCtrl->getAlwaysRefresh() ) + if ( mWebBrowserCtrl->getFrequentUpdates() || + mWebBrowserCtrl->getAlwaysRefresh() || + mWebBrowserCtrl->getForceUpdate() ) { // only update mozilla/texture occasionally if ( mElapsedTime.getElapsedTimeF32() > ( 1.0f / 15.0f ) ) { - mElapsedTime.reset(); + return TRUE; + } + } + + return FALSE; +} - const unsigned char* pixels = LLMozLib::getInstance()->grabBrowserWindow( mEmbeddedBrowserWindowId ); +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLWebBrowserTexture::render() +{ + if (!mMediaSource) + return FALSE; + + // frequent updates turned on? + if ( mWebBrowserCtrl->getFrequentUpdates() || + mWebBrowserCtrl->getAlwaysRefresh() || + mWebBrowserCtrl->getForceUpdate() ) + { - S32 actual_rowspan = LLMozLib::getInstance()->getBrowserRowSpan( mEmbeddedBrowserWindowId ); - S32 browser_depth = LLMozLib::getInstance()->getBrowserDepth( mEmbeddedBrowserWindowId ); + if ( mNeedsUpdate ) + { + const unsigned char* pixels = mMediaSource->getMediaData(); + if ( ! pixels ) + return FALSE; + + mNeedsUpdate = false; + mWebBrowserCtrl->setForceUpdate(false); + + S32 media_depth = mMediaSource->getMediaDepth(); + S32 media_width = mMediaSource->getMediaWidth(); + S32 media_height = mMediaSource->getMediaHeight(); + // these are both invalid conditions and should never happen but SL-27583 indicates it does - if ( actual_rowspan < 1 || browser_depth < 2 ) + if ((media_width < 1) || (media_depth < 2)) return FALSE; - // width can change after it's rendered - (Mozilla bug# 24721) - S32 pagebuffer_width = actual_rowspan / browser_depth; - // Browser depth hasn't changed. - if(mLastBrowserDepth == browser_depth) + if(mLastBrowserDepth == media_depth) { + S32 width = llmin(media_width, mBrowserWidth); + S32 height = llmin(media_height, mBrowserHeight); + + S32 media_data_width = mMediaSource->getMediaDataWidth(); + S32 media_data_height = mMediaSource->getMediaDataHeight(); + // Just grab the pixels. - mTexture->setSubImage( pixels, - pagebuffer_width, mBrowserHeight, - 0, 0, pagebuffer_width, mBrowserHeight ); + if ( media_data_width > 0 && media_data_height > 0 && + media_data_width < MAX_DIMENSION && media_data_height < MAX_DIMENSION ) + { + mTexture->setSubImage( pixels, + media_data_width, media_data_height, + 0, 0, + width, height ); + }; } else { @@ -740,11 +841,20 @@ S32 LLWebBrowserTexture::getBrowserHeight() return mBrowserHeight; } +//////////////////////////////////////////////////////////////////////////////// +// +void LLWebBrowserTexture::setNeedsUpdate() +{ + mNeedsUpdate = true; +} //////////////////////////////////////////////////////////////////////////////// // void LLWebBrowserTexture::resize( S32 new_width, S32 new_height ) { + if (!mMediaSource) + return; + F32 scale_ratio = 1.f; if (new_width > MAX_DIMENSION) { @@ -758,23 +868,25 @@ void LLWebBrowserTexture::resize( S32 new_width, S32 new_height ) mBrowserWidth = llround(scale_ratio * (F32)new_width); mBrowserHeight = llround(scale_ratio * (F32)new_height); - LLMozLib::getInstance()->setSize( mEmbeddedBrowserWindowId, mBrowserWidth, mBrowserHeight ); + mMediaSource->setRequestedMediaSize(mBrowserWidth, mBrowserHeight); - const unsigned char* pixels = LLMozLib::getInstance()->grabBrowserWindow( mEmbeddedBrowserWindowId ); + // HACK - this code is executing a render - resize should call render() instead + // (and render() should be refactored so it doesn't call resize()) + + const unsigned char* pixels = mMediaSource->getMediaData(); - S32 actual_rowspan = LLMozLib::getInstance()->getBrowserRowSpan( mEmbeddedBrowserWindowId ); - S32 browser_depth = LLMozLib::getInstance()->getBrowserDepth( mEmbeddedBrowserWindowId ); + S32 media_width = mMediaSource->getMediaWidth(); + S32 media_height = mMediaSource->getMediaHeight(); + S32 media_depth = mMediaSource->getMediaDepth(); // these are both invalid conditions and should never happen but SL-27583 indicates it does - if ( actual_rowspan < 1 || browser_depth < 2 ) + if ( media_width < 1 || media_depth < 2 ) return; - - releaseGLTexture(); - S32 pagebuffer_width = actual_rowspan / browser_depth; + releaseGLTexture(); // calculate the next power of 2 bigger than reqquested size for width and height - for ( mWidth = 1; mWidth < pagebuffer_width; mWidth <<= 1 ) + for ( mWidth = 1; mWidth < mBrowserWidth; mWidth <<= 1 ) { if ( mWidth >= MAX_TEXTURE_DIMENSION ) { @@ -795,7 +907,7 @@ void LLWebBrowserTexture::resize( S32 new_width, S32 new_height ) LLGLenum type_format; BOOL swap_bytes = FALSE; - switch(browser_depth) + switch(media_depth) { default: case 4: @@ -831,12 +943,21 @@ void LLWebBrowserTexture::resize( S32 new_width, S32 new_height ) // will create mWidth * mHeight sized texture, using BGR ordering LLDynamicTexture::generateGLTexture(internal_format, primary_format, type_format, swap_bytes); + + + S32 width = llmin(media_width, mBrowserWidth); + S32 height = llmin(media_height, mBrowserHeight); + + S32 media_data_width = mMediaSource->getMediaDataWidth(); + S32 media_data_height = mMediaSource->getMediaDataHeight(); + + if (pixels) + { + mTexture->setSubImage( pixels, media_data_width, media_data_height, + 0, 0, width, height ); + } - mTexture->setSubImage( pixels, - pagebuffer_width, mBrowserHeight, - 0, 0, pagebuffer_width, mBrowserHeight ); - - mLastBrowserDepth = browser_depth; + mLastBrowserDepth = media_depth; } LLView* LLWebBrowserCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) @@ -860,7 +981,7 @@ LLView* LLWebBrowserCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac LLColor4 color; LLUICtrlFactory::getAttributeColor(node, "caret_color", color); LLColor4U colorU = LLColor4U(color); - LLMozLib::getInstance()->setCaretColor( web_browser->mEmbeddedBrowserWindowId, colorU.mV[0], colorU.mV[1], colorU.mV[2] ); + web_browser->setCaretColor( colorU.mV[0], colorU.mV[1], colorU.mV[2] ); } BOOL ignore_ui_scale = web_browser->getIgnoreUIScale(); @@ -878,4 +999,4 @@ LLView* LLWebBrowserCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac return web_browser; } -#endif // LL_LIBXUL_ENABLED + diff --git a/linden/indra/newview/llwebbrowserctrl.h b/linden/indra/newview/llwebbrowserctrl.h index 20dfbd7..251d453 100644 --- a/linden/indra/newview/llwebbrowserctrl.h +++ b/linden/indra/newview/llwebbrowserctrl.h @@ -85,15 +85,14 @@ class LLWebBrowserCtrlObserver virtual void onStatusTextChange( const EventType& eventIn ) { }; virtual void onLocationChange( const EventType& eventIn ) { }; virtual void onClickLinkHref( const EventType& eventIn ) { }; - virtual void onClickLinkSecondLife( const EventType& eventIn ) { }; + virtual void onClickLinkNoFollow( const EventType& eventIn ) { }; }; -#if LL_LIBXUL_ENABLED - #include "lluictrl.h" #include "llframetimer.h" #include "lldynamictexture.h" -#include "llmozlib.h" +#include "llmediamanager.h" +#include "llmediaobserver.h" class LLViewBorder; class LLWebBrowserTexture; @@ -163,7 +162,7 @@ class LLUICtrlFactory; // class LLWebBrowserCtrl : public LLUICtrl, - public LLEmbeddedBrowserWindowObserver + public LLMediaObserver { public: LLWebBrowserCtrl( const std::string& name, const LLRect& rect ); @@ -219,6 +218,12 @@ class LLWebBrowserCtrl : void setAlwaysRefresh(bool refresh) { mAlwaysRefresh = refresh; } bool getAlwaysRefresh() { return mAlwaysRefresh; } + + void setForceUpdate(bool force_update) { mForceUpdate = force_update; } + bool getForceUpdate() { return mForceUpdate; } + + bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue ); + // over-rides virtual BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent ); @@ -242,7 +247,8 @@ class LLWebBrowserCtrl : virtual void onStatusTextChange( const EventType& eventIn ); virtual void onLocationChange( const EventType& eventIn ); virtual void onClickLinkHref( const EventType& eventIn ); - virtual void onClickLinkSecondLife( const EventType& eventIn ); + virtual void onClickLinkNoFollow( const EventType& eventIn ); + virtual void onMediaContentsChange( const EventType& event_in ); protected: void convertInputCoords(S32& x, S32& y); @@ -254,12 +260,14 @@ class LLWebBrowserCtrl : LLWebBrowserTexture* mWebBrowserImage; LLViewBorder* mBorder; bool mFrequentUpdates; + bool mForceUpdate; bool mOpenLinksInExternalBrowser; bool mOpenLinksInInternalBrowser; bool mOpenAppSLURLs; std::string mHomePageUrl; bool mIgnoreUIScale; bool mAlwaysRefresh; + LLMediaBase* mMediaSource; }; //////////////////////////////////////////////////////////////////////////////// @@ -267,15 +275,17 @@ class LLWebBrowserCtrl : class LLWebBrowserTexture : public LLDynamicTexture { public: - LLWebBrowserTexture( S32 width, S32 height, LLWebBrowserCtrl* browserCtrl, int browserWindow ); + LLWebBrowserTexture( S32 width, S32 height, LLWebBrowserCtrl* browserCtrl, LLMediaBase *media_source ); virtual ~LLWebBrowserTexture(); + virtual BOOL needsRender(); virtual void preRender( BOOL clear_depth = TRUE ) {}; virtual void postRender( BOOL success ) {}; virtual BOOL render(); S32 getBrowserWidth(); S32 getBrowserHeight(); + void setNeedsUpdate(); void resize( S32 new_width, S32 new_height ); @@ -283,11 +293,10 @@ class LLWebBrowserTexture : public LLDynamicTexture S32 mBrowserWidth; S32 mBrowserHeight; S32 mLastBrowserDepth; + bool mNeedsUpdate; LLFrameTimer mElapsedTime; LLWebBrowserCtrl* mWebBrowserCtrl; - int mEmbeddedBrowserWindowId; + LLMediaBase *mMediaSource; }; -#endif // // LL_LIBXUL_ENABLED - #endif // LL_LLWEBBROWSERCTRL_H diff --git a/linden/indra/newview/llwindebug.cpp b/linden/indra/newview/llwindebug.cpp index cf30f34..e6c11d8 100644 --- a/linden/indra/newview/llwindebug.cpp +++ b/linden/indra/newview/llwindebug.cpp @@ -121,6 +121,172 @@ MODULE32_NEST Module32Next_; #define CALL_TRACE_MAX ((DUMP_SIZE_MAX - 2000) / (MAX_PATH + 40)) //max number of traced calls #define NL L"\r\n" //new line +BOOL WINAPI Get_Module_By_Ret_Addr(PBYTE Ret_Addr, LPWSTR Module_Name, PBYTE & Module_Addr); + + +void printError( CHAR* msg ) +{ + DWORD eNum; + TCHAR sysMsg[256]; + TCHAR* p; + + eNum = GetLastError( ); + FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, eNum, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + sysMsg, 256, NULL ); + + // Trim the end of the line and terminate it with a null + p = sysMsg; + while( ( *p > 31 ) || ( *p == 9 ) ) + ++p; + do { *p-- = 0; } while( ( p >= sysMsg ) && + ( ( *p == '.' ) || ( *p < 33 ) ) ); + + // Display the message + printf( "\n WARNING: %s failed with error %d (%s)", msg, eNum, sysMsg ); +} + +BOOL GetProcessThreadIDs(DWORD process_id, std::vector& thread_ids) +{ + HANDLE hThreadSnap = INVALID_HANDLE_VALUE; + THREADENTRY32 te32; + + // Take a snapshot of all running threads + hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); + if( hThreadSnap == INVALID_HANDLE_VALUE ) + return( FALSE ); + + // Fill in the size of the structure before using it. + te32.dwSize = sizeof(THREADENTRY32 ); + + // Retrieve information about the first thread, + // and exit if unsuccessful + if( !Thread32First( hThreadSnap, &te32 ) ) + { + printError( "Thread32First" ); // Show cause of failure + CloseHandle( hThreadSnap ); // Must clean up the snapshot object! + return( FALSE ); + } + + // Now walk the thread list of the system, + // and display information about each thread + // associated with the specified process + do + { + if( te32.th32OwnerProcessID == process_id ) + { + thread_ids.push_back(te32.th32ThreadID); + } + } while( Thread32Next(hThreadSnap, &te32 ) ); + +// Don't forget to clean up the snapshot object. + CloseHandle( hThreadSnap ); + return( TRUE ); +} + +void WINAPI GetCallStackData(const CONTEXT* context_struct, LLSD& info) +{ + // Fill Str with call stack info. + // pException can be either GetExceptionInformation() or NULL. + // If pException = NULL - get current call stack. + + LPWSTR Module_Name = new WCHAR[MAX_PATH]; + PBYTE Module_Addr = 0; + + typedef struct STACK + { + STACK * Ebp; + PBYTE Ret_Addr; + DWORD Param[0]; + } STACK, * PSTACK; + + PSTACK Ebp; + + if(context_struct) + { + Ebp = (PSTACK)context_struct->Ebp; + } + else + { + // The context struct is NULL, + // so we will use the current stack. + Ebp = (PSTACK)&context_struct - 1; + + // Skip frame of GetCallStackData(). + if (!IsBadReadPtr(Ebp, sizeof(PSTACK))) + Ebp = Ebp->Ebp; //caller ebp + } + + // Trace CALL_TRACE_MAX calls maximum - not to exceed DUMP_SIZE_MAX. + // Break trace on wrong stack frame. + for (int Ret_Addr_I = 0, i = 0; + (Ret_Addr_I < CALL_TRACE_MAX) && !IsBadReadPtr(Ebp, sizeof(PSTACK)) && !IsBadCodePtr(FARPROC(Ebp->Ret_Addr)); + Ret_Addr_I++, Ebp = Ebp->Ebp, ++i) + { + // If module with Ebp->Ret_Addr found. + + if (Get_Module_By_Ret_Addr(Ebp->Ret_Addr, Module_Name, Module_Addr)) + { + // Save module's address and full path. + info["CallStack"][i]["ModuleName"] = ll_convert_wide_to_string(Module_Name); + info["CallStack"][i]["ModuleAddress"] = (int)Module_Addr; + info["CallStack"][i]["CallOffset"] = (int)(Ebp->Ret_Addr - Module_Addr); + + LLSD params; + // Save 5 params of the call. We don't know the real number of params. + if (!IsBadReadPtr(Ebp, sizeof(PSTACK) + 5 * sizeof(DWORD))) + { + for(int j = 0; j < 5; ++j) + { + params[j] = (int)Ebp->Param[j]; + } + } + info["CallStack"][i]["Parameters"] = params; + } + info["CallStack"][i]["ReturnAddress"] = (int)Ebp->Ret_Addr; + } +} + +BOOL GetThreadCallStack(DWORD thread_id, LLSD& info) +{ + if(GetCurrentThreadId() == thread_id) + { + // Early exit for the current thread. + // Suspending the current thread would be a bad idea. + // Plus you can't retrieve a valid current thread context. + return false; + } + + HANDLE thread_handle = INVALID_HANDLE_VALUE; + thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id); + if(INVALID_HANDLE_VALUE == thread_handle) + { + return FALSE; + } + + BOOL result = false; + if(-1 != SuspendThread(thread_handle)) + { + CONTEXT context_struct; + context_struct.ContextFlags = CONTEXT_FULL; + if(GetThreadContext(thread_handle, &context_struct)) + { + GetCallStackData(&context_struct, info); + result = true; + } + ResumeThread(thread_handle); + } + else + { + // Couldn't suspend thread. + } + + CloseHandle(thread_handle); + return result; +} + + //Windows Call Stack Construction idea from //http://www.codeproject.com/tools/minidump.asp @@ -490,7 +656,33 @@ LONG LLWinDebug::handleException(struct _EXCEPTION_POINTERS *exception_infop) LLSD info; info = Get_Exception_Info(exception_infop); - if (info) + + + LLSD threads; + std::vector thread_ids; + GetProcessThreadIDs(GetCurrentProcessId(), thread_ids); + + for(std::vector::iterator th_itr = thread_ids.begin(); + th_itr != thread_ids.end(); + ++th_itr) + { + LLSD thread_info; + if(*th_itr != GetCurrentThreadId()) + { + GetThreadCallStack(*th_itr, thread_info); + } + + if(thread_info) + { + + threads[llformat("ID %d", *th_itr)] = thread_info; + } + } + + + info["Threads"] = threads; + + if (info) { std::ofstream out_file(log_path.c_str()); LLSDSerialize::toPrettyXML(info, out_file); diff --git a/linden/indra/newview/llwlanimator.cpp b/linden/indra/newview/llwlanimator.cpp new file mode 100644 index 0000000..d87c379 --- /dev/null +++ b/linden/indra/newview/llwlanimator.cpp @@ -0,0 +1,168 @@ +/** + * @file llwlanimator.cpp + * @brief Implementation for the LLWLAnimator class. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llwlanimator.h" +#include "llsky.h" +#include "pipeline.h" +#include "llwlparammanager.h" + +LLWLAnimator::LLWLAnimator() : mStartTime(0), mDayRate(1), mDayTime(0), + mIsRunning(FALSE), mUseLindenTime(false) +{ + mDayTime = 0; +} + +void LLWLAnimator::update(LLWLParamSet& curParams) +{ + F64 curTime; + curTime = getDayTime(); + + // don't do anything if empty + if(mTimeTrack.size() == 0) { + return; + } + + // start it off + mFirstIt = mTimeTrack.begin(); + mSecondIt = mTimeTrack.begin(); + mSecondIt++; + + // grab the two tween iterators + while(mSecondIt != mTimeTrack.end() && curTime > mSecondIt->first) { + mFirstIt++; + mSecondIt++; + } + + // scroll it around when you get to the end + if(mSecondIt == mTimeTrack.end() || mFirstIt->first > curTime) { + mSecondIt = mTimeTrack.begin(); + mFirstIt = mTimeTrack.end(); + mFirstIt--; + } + + F32 weight = 0; + + if(mFirstIt->first < mSecondIt->first) { + + // get the delta time and the proper weight + weight = F32 (curTime - mFirstIt->first) / + (mSecondIt->first - mFirstIt->first); + + // handle the ends + } else if(mFirstIt->first > mSecondIt->first) { + + // right edge of time line + if(curTime >= mFirstIt->first) { + weight = F32 (curTime - mFirstIt->first) / + ((1 + mSecondIt->first) - mFirstIt->first); + + // left edge of time line + } else { + weight = F32 ((1 + curTime) - mFirstIt->first) / + ((1 + mSecondIt->first) - mFirstIt->first); + } + + + // handle same as whatever the last one is + } else { + weight = 1; + } + + // do the interpolation and set the parameters + curParams.mix(LLWLParamManager::instance()->mParamList[mFirstIt->second], + LLWLParamManager::instance()->mParamList[mSecondIt->second], weight); +} + +F64 LLWLAnimator::getDayTime() +{ + if(!mIsRunning) { + return mDayTime; + } + + if(mUseLindenTime) { + + F32 phase = gSky.getSunPhase() / F_PI; + + // we're not solving the non-linear equation that determines sun phase + // we're just linearly interpolating between the major points + if (phase <= 5.0 / 4.0) { + mDayTime = (1.0 / 3.0) * phase + (1.0 / 3.0); + } else { + mDayTime = phase - (1.0 / 2.0); + } + + if(mDayTime > 1) { + mDayTime--; + } + + return mDayTime; + } + + // get the time; + mDayTime = (LLTimer::getElapsedSeconds() - mStartTime) / mDayRate; + + // clamp it + if(mDayTime < 0) { + mDayTime = 0; + } + while(mDayTime > 1) { + mDayTime--; + } + + return (F32)mDayTime; +} + +void LLWLAnimator::setDayTime(F64 dayTime) +{ + //retroactively set start time; + mStartTime = LLTimer::getElapsedSeconds() - dayTime * mDayRate; + mDayTime = dayTime; + + // clamp it + if(mDayTime < 0) { + mDayTime = 0; + } else if(mDayTime > 1) { + mDayTime = 1; + } +} + + +void LLWLAnimator::setTrack(std::map& curTrack, + F32 dayRate, F64 dayTime, bool run) +{ + mTimeTrack = curTrack; + mDayRate = dayRate; + setDayTime(dayTime); + + mIsRunning = run; +} diff --git a/linden/indra/newview/llwlanimator.h b/linden/indra/newview/llwlanimator.h new file mode 100644 index 0000000..18c730a --- /dev/null +++ b/linden/indra/newview/llwlanimator.h @@ -0,0 +1,76 @@ +/** + * @file llwlanimator.h + * @brief Interface for the LLWLAnimator class. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_WL_ANIMATOR_H +#define LL_WL_ANIMATOR_H + +#include "llwlparamset.h" +#include +#include + +class LLWLAnimator { +public: + F64 mStartTime; + F32 mDayRate; + F64 mDayTime; + + // track to play + std::map mTimeTrack; + std::map::iterator mFirstIt, mSecondIt; + + // params to use + //std::map mParamList; + + bool mIsRunning; + bool mUseLindenTime; + + // simple constructor + LLWLAnimator(); + + // update the parameters + void update(LLWLParamSet& curParams); + + // get time in seconds + //F64 getTime(void); + + // returns a float 0 - 1 saying what time of day is it? + F64 getDayTime(void); + + // sets a float 0 - 1 saying what time of day it is + void setDayTime(F64 dayTime); + + // set an animation track + void setTrack(std::map& track, + F32 dayRate, F64 dayTime = 0, bool run = true); + +}; + +#endif // LL_WL_ANIMATOR_H diff --git a/linden/indra/newview/llwldaycycle.cpp b/linden/indra/newview/llwldaycycle.cpp new file mode 100644 index 0000000..4626160 --- /dev/null +++ b/linden/indra/newview/llwldaycycle.cpp @@ -0,0 +1,233 @@ +/** + * @file llwldaycycle.cpp + * @brief Implementation for the LLWLDayCycle class. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llwldaycycle.h" +#include "llsdserialize.h" +#include "llwlparammanager.h" + +#include "llviewerwindow.h" + +#include + +LLWLDayCycle::LLWLDayCycle() : mDayRate(120) +{ +} + + +LLWLDayCycle::~LLWLDayCycle() +{ +} + +void LLWLDayCycle::loadDayCycle(const LLString & fileName) +{ + // clear the first few things + mTimeMap.clear(); + + // now load the file + LLString pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, + "windlight/days", fileName)); + llinfos << "Loading DayCycle settings from " << pathName << llendl; + + llifstream day_cycle_xml(pathName.c_str()); + if (day_cycle_xml.is_open()) + { + // load and parse it + LLSD day_data(LLSD::emptyArray()); + LLPointer parser = new LLSDXMLParser(); + parser->parse(day_cycle_xml, day_data, LLSDSerialize::SIZE_UNLIMITED); + + // add each key + for(S32 i = 0; i < day_data.size(); ++i) + { + // make sure it's a two array + if(day_data[i].size() != 2) + { + continue; + } + + // check each param name exists in param manager + bool success; + LLWLParamSet pset; + success = LLWLParamManager::instance()->getParamSet(day_data[i][1].asString(), pset); + if(!success) + { + // alert the user + LLString::format_map_t args; + args["[SKY]"] = day_data[i][1].asString(); + gViewerWindow->alertXml("WLMissingSky", args); + continue; + } + + // then add the key + addKey((F32)day_data[i][0].asReal(), day_data[i][1].asString()); + } + + day_cycle_xml.close(); + } +} + +void LLWLDayCycle::saveDayCycle(const LLString & fileName) +{ + LLSD day_data(LLSD::emptyArray()); + + LLString pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", fileName)); + //llinfos << "Saving WindLight settings to " << pathName << llendl; + + for(std::map::const_iterator mIt = mTimeMap.begin(); + mIt != mTimeMap.end(); + ++mIt) + { + LLSD key(LLSD::emptyArray()); + key.append(mIt->first); + key.append(mIt->second); + day_data.append(key); + } + + std::ofstream day_cycle_xml(pathName.c_str()); + LLPointer formatter = new LLSDXMLFormatter(); + formatter->format(day_data, day_cycle_xml, LLSDFormatter::OPTIONS_PRETTY); + + //day_cycle_xml.close(); +} + + +void LLWLDayCycle::clearKeys() +{ + mTimeMap.clear(); +} + + +bool LLWLDayCycle::addKey(F32 newTime, const LLString & paramName) +{ + // no adding negative time + if(newTime < 0) + { + newTime = 0; + } + + // if time not being used, add it and return true + if(mTimeMap.find(newTime) == mTimeMap.end()) + { + mTimeMap.insert(std::pair(newTime, paramName)); + return true; + } + + // otherwise, don't add, and return error + return false; +} + +bool LLWLDayCycle::changeKeyTime(F32 oldTime, F32 newTime) +{ + // just remove and add back + std::string name = mTimeMap[oldTime]; + + bool stat = removeKey(oldTime); + if(stat == false) + { + return stat; + } + + return addKey(newTime, name); +} + +bool LLWLDayCycle::changeKeyParam(F32 time, const LLString & name) +{ + // just remove and add back + // make sure param exists + LLWLParamSet tmp; + bool stat = LLWLParamManager::instance()->getParamSet(name, tmp); + if(stat == false) + { + return stat; + } + + mTimeMap[time] = name; + return true; +} + + +bool LLWLDayCycle::removeKey(F32 time) +{ + // look for the time. If there, erase it + std::map::iterator mIt = mTimeMap.find(time); + if(mIt != mTimeMap.end()) + { + mTimeMap.erase(mIt); + return true; + } + + return false; +} + +bool LLWLDayCycle::getKey(const LLString & name, F32& key) +{ + // scroll through till we find the + std::map::iterator mIt = mTimeMap.begin(); + for(; mIt != mTimeMap.end(); ++mIt) + { + if(name == mIt->second) + { + key = mIt->first; + return true; + } + } + + return false; +} + +bool LLWLDayCycle::getKeyedParam(F32 time, LLWLParamSet& param) +{ + // just scroll on through till you find it + std::map::iterator mIt = mTimeMap.find(time); + if(mIt != mTimeMap.end()) + { + return LLWLParamManager::instance()->getParamSet(mIt->second, param); + } + + // return error if not found + return false; +} + +bool LLWLDayCycle::getKeyedParamName(F32 time, LLString & name) +{ + // just scroll on through till you find it + std::map::iterator mIt = mTimeMap.find(time); + if(mIt != mTimeMap.end()) + { + name = mTimeMap[time]; + return true; + } + + // return error if not found + return false; +} diff --git a/linden/indra/newview/llwldaycycle.h b/linden/indra/newview/llwldaycycle.h new file mode 100644 index 0000000..85e75c2 --- /dev/null +++ b/linden/indra/newview/llwldaycycle.h @@ -0,0 +1,105 @@ +/** + * @file llwlparammanager.h + * @brief Implementation for the LLWLParamManager class. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_WL_DAY_CYCLE_H +#define LL_WL_DAY_CYCLE_H + +class LLWLDayCycle; + +#include "llfloater.h" + +#include +#include +#include +#include "llwlparamset.h" +#include "llwlanimator.h" + +class LLWLDayCycle +{ +public: + + // lists what param sets are used when during the day + std::map mTimeMap; + + // how long is my day + F32 mDayRate; + +public: + + /// simple constructor + LLWLDayCycle(); + + /// simple destructor + ~LLWLDayCycle(); + + /// load a day cycle + void loadDayCycle(const LLString & fileName); + + /// load a day cycle + void saveDayCycle(const LLString & fileName); + + /// clear keys + void clearKeys(); + + /// Getters and Setters + /// add a new key frame to the day cycle + /// returns true if successful + /// no negative time + bool addKey(F32 newTime, const LLString & paramName); + + /// adjust a key's placement in the day cycle + /// returns true if successful + bool changeKeyTime(F32 oldTime, F32 newTime); + + /// adjust a key's parameter used + /// returns true if successful + bool changeKeyParam(F32 time, const LLString & paramName); + + /// remove a key from the day cycle + /// returns true if successful + bool removeKey(F32 time); + + /// get the first key time for a parameter + /// returns false if not there + bool getKey(const LLString & name, F32& key); + + /// get the param set at a given time + /// returns true if found one + bool getKeyedParam(F32 time, LLWLParamSet& param); + + /// get the name + /// returns true if it found one + bool getKeyedParamName(F32 time, LLString & name); + +}; + + +#endif diff --git a/linden/indra/newview/llwlparammanager.cpp b/linden/indra/newview/llwlparammanager.cpp new file mode 100644 index 0000000..11ed43c --- /dev/null +++ b/linden/indra/newview/llwlparammanager.cpp @@ -0,0 +1,572 @@ +/** + * @file llwlparammanager.cpp + * @brief Implementation for the LLWLParamManager class. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llwlparammanager.h" + +#include "pipeline.h" +#include "llsky.h" + +#include "llsliderctrl.h" +#include "llspinctrl.h" +#include "llcheckboxctrl.h" +#include "llvieweruictrlfactory.h" +#include "llviewercamera.h" +#include "llcombobox.h" +#include "lllineeditor.h" +#include "llsdserialize.h" + +#include "v4math.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "lldrawpoolwater.h" +#include "llagent.h" +#include "llviewerregion.h" + +#include "llwlparamset.h" +#include "llpostprocess.h" +#include "llfloaterwindlight.h" +#include "llfloaterdaycycle.h" +#include "llfloaterenvsettings.h" + +#include "curl/curl.h" + +LLWLParamManager * LLWLParamManager::sInstance = NULL; + +LLWLParamManager::LLWLParamManager() : + + //set the defaults for the controls + // index is from sWLUniforms in pipeline.cpp line 979 + + /// Sun Delta Terrain tweak variables. + mSunDeltaYaw(180.0f), + mSceneLightStrength(2.0f), + mWLGamma(1.0f, "gamma"), + + mBlueHorizon(0.25f, 0.25f, 1.0f, 1.0f, "blue_horizon", "WLBlueHorizon"), + mHazeDensity(1.0f, 1.0f, 1.0f, 0.5f, "haze_density"), + mBlueDensity(0.25f, 0.25f, 0.25f, 1.0f, "blue_density", "WLBlueDensity"), + mDensityMult(1.0f, "density_multiplier", 1000), + mHazeHorizon(1.0f, 1.0f, 1.0f, 0.5f, "haze_horizon"), + mMaxAlt(4000.0f, "max_y"), + + // Lighting + mLightnorm(0.f, 0.707f, -0.707f, 1.f, "lightnorm"), + mSunlight(0.5f, 0.5f, 0.5f, 1.0f, "sunlight_color", "WLSunlight"), + mAmbient(0.5f, 0.75f, 1.0f, 1.19f, "ambient", "WLAmbient"), + mGlow(18.0f, 0.0f, -0.01f, 1.0f, "glow"), + + // Clouds + mCloudColor(0.5f, 0.5f, 0.5f, 1.0f, "cloud_color", "WLCloudColor"), + mCloudMain(0.5f, 0.5f, 0.125f, 1.0f, "cloud_pos_density1"), + mCloudCoverage(0.0f, "cloud_shadow"), + mCloudDetail(0.0f, 0.0f, 0.0f, 1.0f, "cloud_pos_density2"), + mDistanceMult(1.0f, "distance_multiplier"), + mCloudScale(0.42f, "cloud_scale"), + + // sky dome + mDomeOffset(0.96f), + mDomeRadius(15000.f) +{ +} + +LLWLParamManager::~LLWLParamManager() +{ +} + +void LLWLParamManager::loadPresets(const LLString& file_name) +{ + // if fileName exists, use legacy loading form the big file, otherwise, search the sky + // directory, and add the list + if(file_name != "") + { + LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", file_name)); + llinfos << "Loading WindLight settings from " << path_name << llendl; + + llifstream presetsXML(path_name.c_str()); + + if (presetsXML) + { + LLSD paramsData(LLSD::emptyMap()); + + LLPointer parser = new LLSDXMLParser(); + + parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED); + + LLSD::map_const_iterator endParams = paramsData.endMap(); + for(LLSD::map_const_iterator curParams = paramsData.beginMap(); + curParams != endParams; + ++curParams) + { + addParamSet(curParams->first, curParams->second); + } + } + } + + // otherwise, search the sky directory and find things there + else + { + LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", "")); + llinfos << "Loading WindLight settings from " << path_name << llendl; + + //mParamList.clear(); + + bool found = true; + while(found) + { + std::string name; + found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name, false); + + llinfos << "name: " << name << llendl; + + // if we have one + if(found) + { + // bugfix for SL-46920: preventing filenames that break stuff. + char * curl_str = curl_unescape(name.c_str(), name.size()); + std::string unescaped_name(curl_str); + curl_free(curl_str); + curl_str = NULL; + + // not much error checking here since we're getting rid of this + std::string sky_name = unescaped_name.substr(0, unescaped_name.size() - 4); + + LLString cur_path(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", name)); + llinfos << "Loading sky from " << cur_path << llendl; + + std::ifstream sky_xml(cur_path.c_str()); + if (sky_xml) + { + LLSD sky_data(LLSD::emptyMap()); + LLPointer parser = new LLSDXMLParser(); + parser->parse(sky_xml, sky_data, LLSDSerialize::SIZE_UNLIMITED); + + addParamSet(sky_name, sky_data); + } + } + } + } +} + +void LLWLParamManager::savePresets(const LLString & fileName) +{ + LLSD paramsData(LLSD::emptyMap()); + + LLString pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", fileName)); + + for(std::map::iterator mIt = mParamList.begin(); + mIt != mParamList.end(); + ++mIt) + { + paramsData[mIt->first] = mIt->second.getAll(); + } + + std::ofstream presetsXML(pathName.c_str()); + + LLPointer formatter = new LLSDXMLFormatter(); + + formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY); + + presetsXML.close(); +} + +void LLWLParamManager::loadPreset(const LLString & name) +{ + // bugfix for SL-46920: preventing filenames that break stuff. + char * curl_str = curl_escape(name.c_str(), name.size()); + std::string escaped_filename(curl_str); + curl_free(curl_str); + curl_str = NULL; + + escaped_filename += ".xml"; + + std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename)); + llinfos << "Loading WindLight sky setting from " << pathName << llendl; + + std::ifstream presetsXML(pathName.c_str()); + + if (presetsXML) + { + LLSD paramsData(LLSD::emptyMap()); + + LLPointer parser = new LLSDXMLParser(); + + parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED); + + std::map::iterator mIt = mParamList.find(name); + if(mIt == mParamList.end()) + { + addParamSet(name, paramsData); + } + else + { + setParamSet(name, paramsData); + } + } + else + { + llwarns << "Can't find " << name << llendl; + return; + } + + getParamSet(name, mCurParams); + + propagateParameters(); +} + +void LLWLParamManager::savePreset(const LLString & name) +{ + // bugfix for SL-46920: preventing filenames that break stuff. + char * curl_str = curl_escape(name.c_str(), name.size()); + std::string escaped_filename(curl_str); + curl_free(curl_str); + curl_str = NULL; + + escaped_filename += ".xml"; + + // make an empty llsd + LLSD paramsData(LLSD::emptyMap()); + std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename)); + + // fill it with LLSD windlight params + paramsData = mParamList[name].getAll(); + + // write to file + std::ofstream presetsXML(pathName.c_str()); + LLPointer formatter = new LLSDXMLFormatter(); + formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY); + presetsXML.close(); + + propagateParameters(); +} + +void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader) +{ + if (gPipeline.canUseWindLightShaders()) + { + mCurParams.update(shader); + } + + if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT) + { + shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, mRotatedLightDir.mV); + shader->uniform3fv("camPosLocal", 1, gCamera->getOrigin().mV); + } + + else if (shader->mShaderGroup == LLGLSLShader::SG_SKY) + { + shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, mClampedLightDir.mV); + } + + shader->uniform1f("scene_light_strength", mSceneLightStrength); + +} + +void LLWLParamManager::propagateParameters(void) +{ + LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM); + + LLVector4 sunDir; + LLVector4 moonDir; + + // set the sun direction from mSunAngle and mEastAngle + F32 sinTheta = sin(mCurParams.getEastAngle()); + F32 cosTheta = cos(mCurParams.getEastAngle()); + + F32 sinPhi = sin(mCurParams.getSunAngle()); + F32 cosPhi = cos(mCurParams.getSunAngle()); + + sunDir.mV[0] = -sinTheta * cosPhi; + sunDir.mV[1] = sinPhi; + sunDir.mV[2] = cosTheta * cosPhi; + sunDir.mV[3] = 0; + + moonDir = -sunDir; + + // is the normal from the sun or the moon + if(sunDir.mV[1] >= 0) + { + mLightDir = sunDir; + } + else if(sunDir.mV[1] < 0 && sunDir.mV[1] > NIGHTTIME_ELEVATION_COS) + { + // clamp v1 to 0 so sun never points up and causes weirdness on some machines + LLVector3 vec(sunDir.mV[0], sunDir.mV[1], sunDir.mV[2]); + vec.mV[1] = 0; + vec.normVec(); + mLightDir = LLVector4(vec, 0.f); + } + else + { + mLightDir = moonDir; + } + + // calculate the clamp lightnorm for sky (to prevent ugly banding in sky + // when haze goes below the horizon + mClampedLightDir = sunDir; + + if (mClampedLightDir.mV[1] < -0.1f) + { + mClampedLightDir.mV[1] = -0.1f; + } + + mCurParams.set("lightnorm", mLightDir); + + // bind the variables for all shaders only if we're using WindLight + LLShaderMgr::shader_iter shaders_iter, end_shaders; + end_shaders = LLShaderMgr::endShaders(); + for(shaders_iter = LLShaderMgr::beginShaders(); shaders_iter != end_shaders; ++shaders_iter) + { + if (shaders_iter->mProgramObject != 0 + && (gPipeline.canUseWindLightShaders() + || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)) + { + shaders_iter->mUniformsDirty = TRUE; + } + } + + // get the cfr version of the sun's direction + LLVector3 cfrSunDir(sunDir.mV[2], sunDir.mV[0], sunDir.mV[1]); + + // set direction and don't allow overriding + gSky.setSunDirection(cfrSunDir, LLVector3(0,0,0)); + gSky.setOverrideSun(TRUE); +} + +void LLWLParamManager::update(LLViewerCamera * cam) +{ + LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM); + + // update clouds, sun, and general + mCurParams.updateCloudScrolling(); + + // update only if running + if(mAnimator.mIsRunning) + { + mAnimator.update(mCurParams); + } + + // update the shaders and the menu + propagateParameters(); + + // sync menus if they exist + if(LLFloaterWindLight::isOpen()) + { + LLFloaterWindLight::instance()->syncMenu(); + } + if(LLFloaterDayCycle::isOpen()) + { + LLFloaterDayCycle::instance()->syncMenu(); + } + if(LLFloaterEnvSettings::isOpen()) + { + LLFloaterEnvSettings::instance()->syncMenu(); + } + + F32 camYaw = cam->getYaw(); + + stop_glerror(); + + // *TODO: potential optimization - this block may only need to be + // executed some of the time. For example for water shaders only. + { + F32 camYawDelta = mSunDeltaYaw * DEG_TO_RAD; + + LLVector3 lightNorm3(mLightDir); + lightNorm3 *= LLQuaternion(-(camYaw + camYawDelta), LLVector3(0.f, 1.f, 0.f)); + mRotatedLightDir = LLVector4(lightNorm3, 0.f); + + LLShaderMgr::shader_iter shaders_iter, end_shaders; + end_shaders = LLShaderMgr::endShaders(); + for(shaders_iter = LLShaderMgr::beginShaders(); shaders_iter != end_shaders; ++shaders_iter) + { + if (shaders_iter->mProgramObject != 0 + && (gPipeline.canUseWindLightShaders() + || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)) + { + shaders_iter->mUniformsDirty = TRUE; + } + } + } +} + +// static +void LLWLParamManager::initClass(void) +{ + instance(); +} + +// static +void LLWLParamManager::cleanupClass() +{ + delete sInstance; + sInstance = NULL; +} + +void LLWLParamManager::resetAnimator(F32 curTime, bool run) +{ + mAnimator.setTrack(mDay.mTimeMap, mDay.mDayRate, + curTime, run); + + return; +} +bool LLWLParamManager::addParamSet(const std::string& name, LLWLParamSet& param) +{ + // add a new one if not one there already + std::map::iterator mIt = mParamList.find(name); + if(mIt == mParamList.end()) + { + mParamList[name] = param; + return true; + } + + return false; +} + +BOOL LLWLParamManager::addParamSet(const std::string& name, LLSD const & param) +{ + // add a new one if not one there already + std::map::const_iterator finder = mParamList.find(name); + if(finder == mParamList.end()) + { + mParamList[name].setAll(param); + return TRUE; + } + else + { + return FALSE; + } +} + +bool LLWLParamManager::getParamSet(const std::string& name, LLWLParamSet& param) +{ + // find it and set it + std::map::iterator mIt = mParamList.find(name); + if(mIt != mParamList.end()) + { + param = mParamList[name]; + param.mName = name; + return true; + } + + return false; +} + +bool LLWLParamManager::setParamSet(const std::string& name, LLWLParamSet& param) +{ + mParamList[name] = param; + + return true; +} + +bool LLWLParamManager::setParamSet(const std::string& name, const LLSD & param) +{ + // quick, non robust (we won't be working with files, but assets) check + if(!param.isMap()) + { + return false; + } + + mParamList[name].setAll(param); + + return true; +} + +bool LLWLParamManager::removeParamSet(const std::string& name, bool delete_from_disk) +{ + // remove from param list + std::map::iterator mIt = mParamList.find(name); + if(mIt != mParamList.end()) + { + mParamList.erase(mIt); + } + + F32 key; + + // remove all references + bool stat = true; + do + { + // get it + stat = mDay.getKey(name, key); + if(stat == false) + { + break; + } + + // and remove + stat = mDay.removeKey(key); + + } while(stat == true); + + if(delete_from_disk) + { + LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", "")); + + // use full curl escaped name + char * curl_str = curl_escape(name.c_str(), name.size()); + std::string escaped_name(curl_str); + curl_free(curl_str); + curl_str = NULL; + + gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml"); + } + + return true; +} + + +// static +LLWLParamManager * LLWLParamManager::instance() +{ + if(NULL == sInstance) + { + sInstance = new LLWLParamManager(); + + sInstance->loadPresets(""); + + // load the day + sInstance->mDay.loadDayCycle("Default.xml"); + + // *HACK - sets cloud scrolling to what we want... fix this better in the future + sInstance->getParamSet("Default", sInstance->mCurParams); + + // set it to noon + sInstance->resetAnimator(0.5, true); + + // but use linden time sets it to what the estate is + sInstance->mAnimator.mUseLindenTime = true; + } + + return sInstance; +} diff --git a/linden/indra/newview/llwlparammanager.h b/linden/indra/newview/llwlparammanager.h new file mode 100644 index 0000000..bfb84e9 --- /dev/null +++ b/linden/indra/newview/llwlparammanager.h @@ -0,0 +1,292 @@ +/** + * @file llwlparammanager.h + * @brief Implementation for the LLWLParamManager class. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_WLPARAMMANAGER_H +#define LL_WLPARAMMANAGER_H + +#include +#include +#include "llwlparamset.h" +#include "llwlanimator.h" +#include "llwldaycycle.h" +#include "llviewercamera.h" + +class LLGLSLShader; + +// color control +struct WLColorControl { + + F32 r, g, b, i; /// the values + char const * name; /// name to use to dereference params + std::string mSliderName; /// name of the slider in menu + bool hasSliderName; /// only set slider name for true color types + bool isSunOrAmbientColor; /// flag for if it's the sun or ambient color controller + bool isBlueHorizonOrDensity; /// flag for if it's the Blue Horizon or Density color controller + + inline WLColorControl(F32 red, F32 green, F32 blue, F32 intensity, char const * n, + char const * sliderName = "") + : r(red), g(green), b(blue), i(intensity), name(n), mSliderName(sliderName) + { + // if there's a slider name, say we have one + hasSliderName = false; + if (mSliderName != "") { + hasSliderName = true; + } + + // if it's the sun controller + isSunOrAmbientColor = false; + if (mSliderName == "WLSunlight" || mSliderName == "WLAmbient") { + isSunOrAmbientColor = true; + } + + isBlueHorizonOrDensity = false; + if (mSliderName == "WLBlueHorizon" || mSliderName == "WLBlueDensity") { + isBlueHorizonOrDensity = true; + } + } + + inline WLColorControl & operator = (LLVector4 const & val) { + r = val.mV[0]; + g = val.mV[1]; + b = val.mV[2]; + i = val.mV[3]; + return *this; + } + + inline operator LLVector4 (void) const { + return LLVector4(r, g, b, i); + } + + inline operator LLVector3 (void) const { + return LLVector3(r, g, b); + } + + inline void update(LLWLParamSet & params) const { + params.set(name, r, g, b, i); + } +}; + +// float slider control +struct WLFloatControl { + F32 x; + char const * name; + F32 mult; + + inline WLFloatControl(F32 val, char const * n, F32 m=1.0f) + : x(val), name(n), mult(m) + { + } + + inline WLFloatControl & operator = (LLVector4 const & val) { + x = val.mV[0]; + + return *this; + } + + inline operator F32 (void) const { + return x; + } + + inline void update(LLWLParamSet & params) const { + params.set(name, x); + } +}; + +/// WindLight parameter manager class - what controls all the wind light shaders +class LLWLParamManager +{ +public: + + LLWLParamManager(); + ~LLWLParamManager(); + + /// load a preset file + void loadPresets(const LLString & fileName); + + /// save the preset file + void savePresets(const LLString & fileName); + + /// load an individual preset into the sky + void loadPreset(const LLString & name); + + /// save the parameter presets to file + void savePreset(const LLString & name); + + /// Set shader uniforms dirty, so they'll update automatically. + void propagateParameters(void); + + /// Update shader uniforms that have changed. + void updateShaderUniforms(LLGLSLShader * shader); + + /// setup the animator to run + void resetAnimator(F32 curTime, bool run); + + /// update information camera dependent parameters + void update(LLViewerCamera * cam); + + // get where the light is pointing + inline LLVector4 getLightDir(void) const; + + // get where the light is pointing + inline LLVector4 getClampedLightDir(void) const; + + // get where the light is pointing + inline LLVector4 getRotatedLightDir(void) const; + + /// get the dome's offset + inline F32 getDomeOffset(void) const; + + /// get the radius of the dome + inline F32 getDomeRadius(void) const; + + /// Perform global initialization for this class. + static void initClass(void); + + // Cleanup of global data that's only inited once per class. + static void cleanupClass(); + + /// add a param to the list + bool addParamSet(const std::string& name, LLWLParamSet& param); + + /// add a param to the list + BOOL addParamSet(const std::string& name, LLSD const & param); + + /// get a param from the list + bool getParamSet(const std::string& name, LLWLParamSet& param); + + /// set the param in the list with a new param + bool setParamSet(const std::string& name, LLWLParamSet& param); + + /// set the param in the list with a new param + bool setParamSet(const std::string& name, LLSD const & param); + + /// gets rid of a parameter and any references to it + /// returns true if successful + bool removeParamSet(const std::string& name, bool delete_from_disk); + + // singleton pattern implementation + static LLWLParamManager * instance(); + + +public: + + // helper variables + F32 mSunAngle; + F32 mEastAngle; + LLWLAnimator mAnimator; + + /// actual direction of the sun + LLVector4 mLightDir; + + /// light norm adjusted so haze works correctly + LLVector4 mRotatedLightDir; + + /// clamped light norm for shaders that + /// are adversely affected when the sun goes below the + /// horizon + LLVector4 mClampedLightDir; + + // list of params and how they're cycled for days + LLWLDayCycle mDay; + + // length of the day in seconds + F32 mLengthOfDay; + + LLWLParamSet mCurParams; + + /// Sun Delta Terrain tweak variables. + F32 mSunDeltaYaw; + WLFloatControl mWLGamma; + + F32 mSceneLightStrength; + + /// Atmospherics + WLColorControl mBlueHorizon; + WLColorControl mHazeDensity; + WLColorControl mBlueDensity; + WLFloatControl mDensityMult; + WLColorControl mHazeHorizon; + WLFloatControl mMaxAlt; + + /// Lighting + WLColorControl mLightnorm; + WLColorControl mSunlight; + WLColorControl mAmbient; + WLColorControl mGlow; + + /// Clouds + WLColorControl mCloudColor; + WLColorControl mCloudMain; + WLFloatControl mCloudCoverage; + WLColorControl mCloudDetail; + WLFloatControl mDistanceMult; + WLFloatControl mCloudScale; + + /// sky dome + F32 mDomeOffset; + F32 mDomeRadius; + + // list of all the parameters, listed by name + std::map mParamList; + + +private: + // our parameter manager singleton instance + static LLWLParamManager * sInstance; + +}; + +inline F32 LLWLParamManager::getDomeOffset(void) const +{ + return mDomeOffset; +} + +inline F32 LLWLParamManager::getDomeRadius(void) const +{ + return mDomeRadius; +} + +inline LLVector4 LLWLParamManager::getLightDir(void) const +{ + return mLightDir; +} + +inline LLVector4 LLWLParamManager::getClampedLightDir(void) const +{ + return mClampedLightDir; +} + +inline LLVector4 LLWLParamManager::getRotatedLightDir(void) const +{ + return mRotatedLightDir; +} + +#endif diff --git a/linden/indra/newview/llwlparamset.cpp b/linden/indra/newview/llwlparamset.cpp new file mode 100644 index 0000000..d6e1f03 --- /dev/null +++ b/linden/indra/newview/llwlparamset.cpp @@ -0,0 +1,403 @@ +/** + * @file llwlparamset.cpp + * @brief Implementation for the LLWLParamSet class. + * + * $LicenseInfo:firstyear=2005&license=viewergpl$ + * + * Copyright (c) 2005-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llwlparamset.h" +#include "llwlanimator.h" + +#include "llfloaterwindlight.h" +#include "llwlparammanager.h" +#include "lluictrlfactory.h" +#include "llsliderctrl.h" + +#include + +#include + +LLWLParamSet::LLWLParamSet(void) : + mName("Unnamed Preset"), + mCloudScrollXOffset(0.f), mCloudScrollYOffset(0.f) +{ +/* REMOVE or init the LLSD + const std::map::value_type hardcodedPreset[] = { + std::make_pair("lightnorm", LLVector4(0.f, 0.707f, -0.707f, 0.f)), + std::make_pair("sunlight_color", LLVector4(0.6f, 0.6f, 2.83f, 2.27f)), + std::make_pair("ambient", LLVector4(0.27f, 0.33f, 0.44f, 1.19f)), + std::make_pair("blue_horizon", LLVector4(0.3f, 0.4f, 0.9f, 1.f)), + std::make_pair("blue_density", LLVector4(0.3f, 0.4f, 0.8f, 1.f)), + std::make_pair("haze_horizon", LLVector4(0.6f, 0.6f, 0.6f, 1.f)), + std::make_pair("haze_density", LLVector4(0.3f, 0.3f, 0.3f, 1.f)), + std::make_pair("cloud_shadow", LLVector4(0.f, 0.f, 0.f, 0.f)), + std::make_pair("density_multiplier", LLVector4(0.001f, 0.001f, 0.001f, 0.001f)), + std::make_pair("distance_multiplier", LLVector4(1.f, 1.f, 1.f, 1.f)), + std::make_pair("max_y", LLVector4(600.f, 600.f, 600.f, 0.f)), + std::make_pair("glow", LLVector4(15.f, 0.001f, -0.03125f, 0.f)), + std::make_pair("cloud_color", LLVector4(0.0f, 0.0f, 0.0f, 0.0f)), + std::make_pair("cloud_pos_density1", LLVector4(0.f, 0.f, 0.f, 1.f)), + std::make_pair("cloud_pos_density2", LLVector4(0.f, 0.f, 0.f, 1.f)), + std::make_pair("cloud_scale", LLVector4(0.42f, 0.f, 0.f, 1.f)), + std::make_pair("gamma", LLVector4(2.0f, 2.0f, 2.0f, 0.0f)), + }; + std::map::value_type const * endHardcodedPreset = + hardcodedPreset + sizeof(hardcodedPreset)/sizeof(hardcodedPreset[0]); + + mParamValues.insert(hardcodedPreset, endHardcodedPreset); +*/ +} + +void LLWLParamSet::update(LLGLSLShader * shader) const +{ + for(LLSD::map_const_iterator i = mParamValues.beginMap(); + i != mParamValues.endMap(); + ++i) + { + const LLString& param = i->first; + + if( param == "star_brightness" || param == "preset_num" || param == "sun_angle" || + param == "east_angle" || param == "enable_cloud_scroll" || + param == "cloud_scroll_rate" || param == "lightnorm" ) + { + continue; + } + + if(param == "cloud_pos_density1") + { + LLVector4 val; + val.mV[0] = F32(i->second[0].asReal()) + mCloudScrollXOffset; + val.mV[1] = F32(i->second[1].asReal()) + mCloudScrollYOffset; + val.mV[2] = (F32) i->second[2].asReal(); + val.mV[3] = (F32) i->second[3].asReal(); + + shader->uniform4fv(param, 1, val.mV); + } + else + { + LLVector4 val; + + // handle all the different cases + if(i->second.isArray() && i->second.size() == 4) + { + val.mV[0] = (F32) i->second[0].asReal(); + val.mV[1] = (F32) i->second[1].asReal(); + val.mV[2] = (F32) i->second[2].asReal(); + val.mV[3] = (F32) i->second[3].asReal(); + } + else if(i->second.isReal()) + { + val.mV[0] = (F32) i->second.asReal(); + } + else if(i->second.isInteger()) + { + val.mV[0] = (F32) i->second.asReal(); + } + else if(i->second.isBoolean()) + { + val.mV[0] = i->second.asBoolean(); + } + + + shader->uniform4fv(param, 1, val.mV); + } + } +} + +void LLWLParamSet::set(const char * paramName, float x) +{ + // handle case where no array + if(mParamValues[paramName].isReal()) + { + mParamValues[paramName] = x; + } + + // handle array + else if(mParamValues[paramName].isArray() && + mParamValues[paramName][0].isReal()) + { + mParamValues[paramName][0] = x; + } +} + +void LLWLParamSet::set(const char * paramName, float x, float y) { + mParamValues[paramName][0] = x; + mParamValues[paramName][1] = y; +} + +void LLWLParamSet::set(const char * paramName, float x, float y, float z) +{ + mParamValues[paramName][0] = x; + mParamValues[paramName][1] = y; + mParamValues[paramName][2] = z; +} + +void LLWLParamSet::set(const char * paramName, float x, float y, float z, float w) +{ + mParamValues[paramName][0] = x; + mParamValues[paramName][1] = y; + mParamValues[paramName][2] = z; + mParamValues[paramName][3] = w; +} + +void LLWLParamSet::set(const char * paramName, const float * val) +{ + mParamValues[paramName][0] = val[0]; + mParamValues[paramName][1] = val[1]; + mParamValues[paramName][2] = val[2]; + mParamValues[paramName][3] = val[3]; +} + +void LLWLParamSet::set(const char * paramName, const LLVector4 & val) +{ + mParamValues[paramName][0] = val.mV[0]; + mParamValues[paramName][1] = val.mV[1]; + mParamValues[paramName][2] = val.mV[2]; + mParamValues[paramName][3] = val.mV[3]; +} + +void LLWLParamSet::set(const char * paramName, const LLColor4 & val) +{ + mParamValues[paramName][0] = val.mV[0]; + mParamValues[paramName][1] = val.mV[1]; + mParamValues[paramName][2] = val.mV[2]; + mParamValues[paramName][3] = val.mV[3]; +} + +LLVector4 LLWLParamSet::getVector(const char * paramName, bool& error) +{ + + // test to see if right type + LLSD cur_val = mParamValues.get(paramName); + if (!cur_val.isArray()) + { + error = true; + return LLVector4(0,0,0,0); + } + + LLVector4 val; + val.mV[0] = (F32) cur_val[0].asReal(); + val.mV[1] = (F32) cur_val[1].asReal(); + val.mV[2] = (F32) cur_val[2].asReal(); + val.mV[3] = (F32) cur_val[3].asReal(); + + error = false; + return val; +} + +F32 LLWLParamSet::getFloat(const char * paramName, bool& error) +{ + + // test to see if right type + LLSD cur_val = mParamValues.get(paramName); + if (cur_val.isArray() && cur_val.size() != 0) + { + error = false; + return (F32) cur_val[0].asReal(); + } + + if(cur_val.isReal()) + { + error = false; + return (F32) cur_val.asReal(); + } + + error = true; + return 0; +} + + + +void LLWLParamSet::setSunAngle(float val) +{ + // keep range 0 - 2pi + if(val > F_TWO_PI || val < 0) + { + F32 num = val / F_TWO_PI; + num -= floor(num); + val = F_TWO_PI * num; + } + + mParamValues["sun_angle"] = val; +} + + +void LLWLParamSet::setEastAngle(float val) +{ + // keep range 0 - 2pi + if(val > F_TWO_PI || val < 0) + { + F32 num = val / F_TWO_PI; + num -= floor(num); + val = F_TWO_PI * num; + } + + mParamValues["east_angle"] = val; +} + + +void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight) +{ + // set up the iterators + LLSD::map_iterator cIt = mParamValues.beginMap(); + + // keep cloud positions and coverage the same + /// TODO masking will do this later + F32 cloudPos1X = (F32) mParamValues["cloud_pos_density1"][0].asReal(); + F32 cloudPos1Y = (F32) mParamValues["cloud_pos_density1"][1].asReal(); + F32 cloudPos2X = (F32) mParamValues["cloud_pos_density2"][0].asReal(); + F32 cloudPos2Y = (F32) mParamValues["cloud_pos_density2"][1].asReal(); + F32 cloudCover = (F32) mParamValues["cloud_shadow"][0].asReal(); + + LLSD srcVal; + LLSD destVal; + + // do the interpolation for all the ones saved as vectors + // skip the weird ones + for(; cIt != mParamValues.endMap(); cIt++) { + + // check params to make sure they're actually there + if(src.mParamValues.has(cIt->first)) + { + srcVal = src.mParamValues[cIt->first]; + } + else + { + continue; + } + + if(dest.mParamValues.has(cIt->first)) + { + destVal = dest.mParamValues[cIt->first]; + } + else + { + continue; + } + + // skip if not a vector + if(!cIt->second.isArray()) + { + continue; + } + + // only Real vectors allowed + if(!cIt->second[0].isReal()) + { + continue; + } + + // make sure all the same size + if( cIt->second.size() != srcVal.size() || + cIt->second.size() != destVal.size()) + { + continue; + } + + // more error checking might be necessary; + + for(int i=0; i < cIt->second.size(); ++i) + { + cIt->second[i] = (1.0f - weight) * (F32) srcVal[i].asReal() + + weight * (F32) destVal[i].asReal(); + } + } + + // now mix the extra parameters + setStarBrightness((1 - weight) * (F32) src.getStarBrightness() + + weight * (F32) dest.getStarBrightness()); + + llassert(src.getSunAngle() >= - F_PI && + src.getSunAngle() <= 3 * F_PI); + llassert(dest.getSunAngle() >= - F_PI && + dest.getSunAngle() <= 3 * F_PI); + llassert(src.getEastAngle() >= 0 && + src.getEastAngle() <= 4 * F_PI); + llassert(dest.getEastAngle() >= 0 && + dest.getEastAngle() <= 4 * F_PI); + + // sun angle and east angle require some handling to make sure + // they go in circles. Yes quaternions would work better. + F32 srcSunAngle = src.getSunAngle(); + F32 destSunAngle = dest.getSunAngle(); + F32 srcEastAngle = src.getEastAngle(); + F32 destEastAngle = dest.getEastAngle(); + + if(fabsf(srcSunAngle - destSunAngle) > F_PI) + { + if(srcSunAngle > destSunAngle) + { + destSunAngle += 2 * F_PI; + } + else + { + srcSunAngle += 2 * F_PI; + } + } + + if(fabsf(srcEastAngle - destEastAngle) > F_PI) + { + if(srcEastAngle > destEastAngle) + { + destEastAngle += 2 * F_PI; + } + else + { + srcEastAngle += 2 * F_PI; + } + } + + setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle); + setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle); + + // now setup the sun properly + + // reset those cloud positions + mParamValues["cloud_pos_density1"][0] = cloudPos1X; + mParamValues["cloud_pos_density1"][1] = cloudPos1Y; + mParamValues["cloud_pos_density2"][0] = cloudPos2X; + mParamValues["cloud_pos_density2"][1] = cloudPos2Y; + mParamValues["cloud_shadow"][0] = cloudCover; +} + +void LLWLParamSet::updateCloudScrolling(void) +{ + static LLTimer s_cloud_timer; + + F64 delta_t = s_cloud_timer.getElapsedTimeAndResetF64(); + + if(getEnableCloudScrollX()) + { + mCloudScrollXOffset += F32(delta_t * (getCloudScrollX() - 10.f) / 100.f); + } + if(getEnableCloudScrollY()) + { + mCloudScrollYOffset += F32(delta_t * (getCloudScrollY() - 10.f) / 100.f); + } +} diff --git a/linden/indra/newview/llwlparamset.h b/linden/indra/newview/llwlparamset.h new file mode 100644 index 0000000..6fa0bff --- /dev/null +++ b/linden/indra/newview/llwlparamset.h @@ -0,0 +1,252 @@ +/** + * @file llwlparamset.h + * @brief Interface for the LLWLParamSet class. + * + * $LicenseInfo:firstyear=2005&license=viewergpl$ + * + * Copyright (c) 2005-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_WLPARAM_SET_H +#define LL_WLPARAM_SET_H + +#include +#include + +#include "v4math.h" +#include "v4color.h" +#include "llglslshader.h" + +class LLFloaterWindLight; +class LLWLParamSet; + +/// A class representing a set of parameter values for the WindLight shaders. +class LLWLParamSet { + + friend class LLWLParamManager; + +public: + LLString mName; + +private: + + LLSD mParamValues; + + float mCloudScrollXOffset, mCloudScrollYOffset; + +public: + + LLWLParamSet(); + + /// Update this set of shader uniforms from the parameter values. + void update(LLGLSLShader * shader) const; + + /// set the total llsd + void setAll(const LLSD& val); + + /// get the total llsd + const LLSD& getAll(); + + + /// Set a float parameter. + /// \param paramName The name of the parameter to set. + /// \param x The float value to set. + void set(const char * paramName, float x); + + /// Set a float2 parameter. + /// \param paramName The name of the parameter to set. + /// \param x The x component's value to set. + /// \param y The y component's value to set. + void set(const char * paramName, float x, float y); + + /// Set a float3 parameter. + /// \param paramName The name of the parameter to set. + /// \param x The x component's value to set. + /// \param y The y component's value to set. + /// \param z The z component's value to set. + void set(const char * paramName, float x, float y, float z); + + /// Set a float4 parameter. + /// \param paramName The name of the parameter to set. + /// \param x The x component's value to set. + /// \param y The y component's value to set. + /// \param z The z component's value to set. + /// \param w The w component's value to set. + void set(const char * paramName, float x, float y, float z, float w); + + /// Set a float4 parameter. + /// \param paramName The name of the parameter to set. + /// \param val An array of the 4 float values to set the parameter to. + void set(const char * paramName, const float * val); + + /// Set a float4 parameter. + /// \param paramName The name of the parameter to set. + /// \param val A struct of the 4 float values to set the parameter to. + void set(const char * paramName, const LLVector4 & val); + + /// Set a float4 parameter. + /// \param paramName The name of the parameter to set. + /// \param val A struct of the 4 float values to set the parameter to. + void set(const char * paramName, const LLColor4 & val); + + /// Get a float4 parameter. + /// \param paramName The name of the parameter to set. + /// \param error A flag to set if it's not the proper return type + LLVector4 getVector(const char * paramName, bool& error); + + /// Get an integer parameter + /// \param paramName The name of the parameter to set. + /// \param error A flag to set if it's not the proper return type + F32 getFloat(const char * paramName, bool& error); + + + // specific getters and setters + + + /// set the star's brightness + /// \param val brightness value + void setStarBrightness(F32 val); + + /// get the star brightness value; + F32 getStarBrightness(); + + /// set the star's brightness + /// \param val brightness value + void setSunAngle(F32 val); + + /// get the star brightness value; + F32 getSunAngle(); + + /// set the star's brightness + /// \param val brightness value + void setEastAngle(F32 val); + + /// get the star brightness value; + F32 getEastAngle(); + + + + /// set the cloud scroll x enable value + /// \param val scroll x value + void setEnableCloudScrollX(bool val); + + /// get the scroll x enable value; + bool getEnableCloudScrollX(); + + /// set the star's brightness + /// \param val scroll y bool value + void setEnableCloudScrollY(bool val); + + /// get the scroll enable y value; + bool getEnableCloudScrollY(); + + /// set the cloud scroll x enable value + /// \param val scroll x value + void setCloudScrollX(F32 val); + + /// get the scroll x enable value; + F32 getCloudScrollX(); + + /// set the star's brightness + /// \param val scroll y bool value + void setCloudScrollY(F32 val); + + /// get the scroll enable y value; + F32 getCloudScrollY(); + + /// interpolate two parameter sets + /// \param src The parameter set to start with + /// \param dest The parameter set to end with + /// \param weight The amount to interpolate + void mix(LLWLParamSet& src, LLWLParamSet& dest, + F32 weight); + + void updateCloudScrolling(void); +}; + +inline void LLWLParamSet::setAll(const LLSD& val) +{ + if(val.isMap()) { + mParamValues = val; + } +} + +inline const LLSD& LLWLParamSet::getAll() +{ + return mParamValues; +} + +inline void LLWLParamSet::setStarBrightness(float val) { + mParamValues["star_brightness"] = val; +} + +inline F32 LLWLParamSet::getStarBrightness() { + return (F32) mParamValues["star_brightness"].asReal(); +} + +inline F32 LLWLParamSet::getSunAngle() { + return (F32) mParamValues["sun_angle"].asReal(); +} + +inline F32 LLWLParamSet::getEastAngle() { + return (F32) mParamValues["east_angle"].asReal(); +} + + +inline void LLWLParamSet::setEnableCloudScrollX(bool val) { + mParamValues["enable_cloud_scroll"][0] = val; +} + +inline bool LLWLParamSet::getEnableCloudScrollX() { + return mParamValues["enable_cloud_scroll"][0].asBoolean(); +} + +inline void LLWLParamSet::setEnableCloudScrollY(bool val) { + mParamValues["enable_cloud_scroll"][1] = val; +} + +inline bool LLWLParamSet::getEnableCloudScrollY() { + return mParamValues["enable_cloud_scroll"][1].asBoolean(); +} + + +inline void LLWLParamSet::setCloudScrollX(F32 val) { + mParamValues["cloud_scroll_rate"][0] = val; +} + +inline F32 LLWLParamSet::getCloudScrollX() { + return (F32) mParamValues["cloud_scroll_rate"][0].asReal(); +} + +inline void LLWLParamSet::setCloudScrollY(F32 val) { + mParamValues["cloud_scroll_rate"][1] = val; +} + +inline F32 LLWLParamSet::getCloudScrollY() { + return (F32) mParamValues["cloud_scroll_rate"][1].asReal(); +} + + +#endif // LL_WLPARAM_SET_H diff --git a/linden/indra/newview/llworld.cpp b/linden/indra/newview/llworld.cpp index c03ef6e..60312db 100644 --- a/linden/indra/newview/llworld.cpp +++ b/linden/indra/newview/llworld.cpp @@ -636,7 +636,8 @@ void LLWorld::updateParticles() void LLWorld::updateClouds(const F32 dt) { - if (gSavedSettings.getBOOL("FreezeTime")) + if (gSavedSettings.getBOOL("FreezeTime") || + !gSavedSettings.getBOOL("SkyUseClassicClouds")) { // don't move clouds in snapshot mode return; @@ -791,7 +792,6 @@ void LLWorld::setLandFarClip(const F32 far_clip) void LLWorld::updateWaterObjects() { - //llinfos << "Start water update" << llendl; if (!gAgent.getRegion()) { return; @@ -803,35 +803,33 @@ void LLWorld::updateWaterObjects() } // First, determine the min and max "box" of water objects - bool first = true; S32 min_x = 0; S32 min_y = 0; S32 max_x = 0; S32 max_y = 0; U32 region_x, region_y; - S32 rwidth = llfloor(getRegionWidthInMeters()); + S32 rwidth = 256; + // We only want to fill in water for stuff that's near us, say, within 256 or 512m + S32 range = gCamera->getFar() > 256.f ? 512 : 256; + + LLViewerRegion* regionp = gAgent.getRegion(); + from_region_handle(regionp->getHandle(), ®ion_x, ®ion_y); + + min_x = (S32)region_x - range; + min_y = (S32)region_y - range; + max_x = (S32)region_x + range; + max_y = (S32)region_y + range; + + F32 height = 0.f; for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter) { LLViewerRegion* regionp = *iter; - from_region_handle(regionp->getHandle(), ®ion_x, ®ion_y); - if (first) - { - first = false; - min_x = max_x = region_x; - min_y = max_y = region_y; - } - else - { - min_x = llmin(min_x, (S32)region_x); - min_y = llmin(min_y, (S32)region_y); - max_x = llmax(max_x, (S32)region_x); - max_y = llmax(max_y, (S32)region_y); - } LLVOWater* waterp = regionp->getLand().getWaterObj(); + height += regionp->getWaterHeight(); if (waterp) { gObjectList.updateActive(waterp); @@ -846,15 +844,6 @@ void LLWorld::updateWaterObjects() } mHoleWaterObjects.clear(); - // We only want to fill in holes for stuff that's near us, say, within 512m - LLViewerRegion* regionp = gAgent.getRegion(); - from_region_handle(regionp->getHandle(), ®ion_x, ®ion_y); - - min_x = llmax((S32)region_x - 512, min_x); - min_y = llmax((S32)region_y - 512, min_y); - max_x = llmin((S32)region_x + 512, max_x); - max_y = llmin((S32)region_y + 512, max_y); - // Now, get a list of the holes S32 x, y; for (x = min_x; x <= max_x; x += rwidth) @@ -866,11 +855,11 @@ void LLWorld::updateWaterObjects() { LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion()); waterp->setUseTexture(FALSE); - gPipeline.addObject(waterp); waterp->setPositionGlobal(LLVector3d(x + rwidth/2, y + rwidth/2, - DEFAULT_WATER_HEIGHT)); - waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 0.f)); + 256.f+DEFAULT_WATER_HEIGHT)); + waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f)); + gPipeline.addObject(waterp); mHoleWaterObjects.push_back(waterp); } } @@ -884,15 +873,12 @@ void LLWorld::updateWaterObjects() center_x = min_x + (wx >> 1); center_y = min_y + (wy >> 1); - - S32 add_boundary[4] = { 512 - (max_x - region_x), 512 - (max_y - region_y), 512 - (region_x - min_x), 512 - (region_y - min_y) }; - S32 dir; for (dir = 0; dir < 8; dir++) { @@ -910,16 +896,10 @@ void LLWorld::updateWaterObjects() default: dim[1] = add_boundary[1]; break; } - if (dim[0] == 0 || dim[1] == 0) - { - continue; - } - // Resize and reshape the water objects const S32 water_center_x = center_x + llround((wx + dim[0]) * 0.5f * gDirAxes[dir][0]); const S32 water_center_y = center_y + llround((wy + dim[1]) * 0.5f * gDirAxes[dir][1]); - LLVOWater* waterp = mEdgeWaterObjects[dir]; if (!waterp || waterp->isDead()) { @@ -929,23 +909,38 @@ void LLWorld::updateWaterObjects() gAgent.getRegion()); waterp = mEdgeWaterObjects[dir]; waterp->setUseTexture(FALSE); + waterp->setIsEdgePatch(TRUE); gPipeline.addObject(waterp); } waterp->setRegion(gAgent.getRegion()); LLVector3d water_pos(water_center_x, water_center_y, - DEFAULT_WATER_HEIGHT); + DEFAULT_WATER_HEIGHT+256.f); + LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f); + + //stretch out to horizon + water_scale.mV[0] += fabsf(2048.f * gDirAxes[dir][0]); + water_scale.mV[1] += fabsf(2048.f * gDirAxes[dir][1]); + + water_pos.mdV[0] += 1024.f * gDirAxes[dir][0]; + water_pos.mdV[1] += 1024.f * gDirAxes[dir][1]; + waterp->setPositionGlobal(water_pos); - waterp->setScale(LLVector3((F32)dim[0], (F32)dim[1], 0.f)); + waterp->setScale(water_scale); + gObjectList.updateActive(waterp); - /*if (!gNoRender) - { - gPipeline.markMoved(waterp->mDrawable); - }*/ } +} +void LLWorld::shiftRegions(const LLVector3& offset) +{ + for (region_list_t::iterator i = getRegionList().begin(); i != getRegionList().end(); ++i) + { + LLViewerRegion* region = *i; + region->updateRenderMatrix(); + } - //llinfos << "End water update" << llendl; + mPartSim.shift(offset); } LLViewerImage* LLWorld::getDefaultWaterTexture() diff --git a/linden/indra/newview/llworld.h b/linden/indra/newview/llworld.h index cad24da..7b935e8 100644 --- a/linden/indra/newview/llworld.h +++ b/linden/indra/newview/llworld.h @@ -138,6 +138,7 @@ public: LLViewerImage *getDefaultWaterTexture(); void updateWaterObjects(); + void shiftRegions(const LLVector3& offset); void setSpaceTimeUSec(const U64 space_time_usec); U64 getSpaceTimeUSec() const; @@ -150,6 +151,8 @@ public: region_list_t mActiveRegionList; LLViewerPartSim mPartSim; + region_list_t& getRegionList() { return mActiveRegionList; } + private: region_list_t mRegionList; region_list_t mVisibleRegionList; diff --git a/linden/indra/newview/llworldmapview.cpp b/linden/indra/newview/llworldmapview.cpp index 266ffbc..2fac51a 100644 --- a/linden/indra/newview/llworldmapview.cpp +++ b/linden/indra/newview/llworldmapview.cpp @@ -35,10 +35,10 @@ #include "indra_constants.h" #include "llui.h" -#include "linked_lists.h" #include "llmath.h" // clampf() #include "llregionhandle.h" #include "lleventflags.h" +#include "llglimmediate.h" #include "llagent.h" #include "llcallingcard.h" @@ -210,9 +210,11 @@ LLWorldMapView::LLWorldMapView(const std::string& name, const LLRect& rect ) mTextBoxEast->setColor( minor_color ); addChild( mTextBoxEast ); + major_dir_rect.mRight += 1 ; mTextBoxWest = new LLTextBox( "W", major_dir_rect ); mTextBoxWest->setColor( minor_color ); addChild( mTextBoxWest ); + major_dir_rect.mRight -= 1 ; mTextBoxSouth = new LLTextBox( "S", major_dir_rect ); mTextBoxSouth->setColor( minor_color ); @@ -325,8 +327,8 @@ void LLWorldMapView::draw() sPanX = lerp(sPanX, sTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); sPanY = lerp(sPanY, sTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); - const S32 width = mRect.getWidth(); - const S32 height = mRect.getHeight(); + const S32 width = getRect().getWidth(); + const S32 height = getRect().getHeight(); const S32 half_width = width / 2; const S32 half_height = height / 2; LLVector3d camera_global = gAgent.getCameraPositionGlobal(); @@ -338,16 +340,18 @@ void LLWorldMapView::draw() glMatrixMode(GL_MODELVIEW); // Clear the background alpha to 0 + gGL.flush(); glColorMask(FALSE, FALSE, FALSE, TRUE); glAlphaFunc(GL_GEQUAL, 0.00f); - glBlendFunc(GL_ONE, GL_ZERO); - glColor4f(0.0f, 0.0f, 0.0f, 0.0f); + gGL.blendFunc(GL_ONE, GL_ZERO); + gGL.color4f(0.0f, 0.0f, 0.0f, 0.0f); gl_rect_2d(0, height, width, 0); } + gGL.flush(); glAlphaFunc(GL_GEQUAL, 0.01f); glColorMask(TRUE, TRUE, TRUE, TRUE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); F32 layer_alpha = 1.f; @@ -410,37 +414,40 @@ void LLWorldMapView::draw() LLViewerImage::bindTexture(current_image); // Draw map image into RGB - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.flush(); glColorMask(TRUE, TRUE, TRUE, FALSE); - glColor4f(1.f, 1.f, 1.f, layer_alpha); - - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 1.0f); - glVertex3f(left, top, -1.0f); - glTexCoord2f(0.0f, 0.0f); - glVertex3f(left, bottom, -1.0f); - glTexCoord2f(1.0f, 0.0f); - glVertex3f(right, bottom, -1.0f); - glTexCoord2f(1.0f, 1.0f); - glVertex3f(right, top, -1.0f); - glEnd(); + gGL.color4f(1.f, 1.f, 1.f, layer_alpha); + + gGL.begin(GL_QUADS); + gGL.texCoord2f(0.0f, 1.0f); + gGL.vertex3f(left, top, -1.0f); + gGL.texCoord2f(0.0f, 0.0f); + gGL.vertex3f(left, bottom, -1.0f); + gGL.texCoord2f(1.0f, 0.0f); + gGL.vertex3f(right, bottom, -1.0f); + gGL.texCoord2f(1.0f, 1.0f); + gGL.vertex3f(right, top, -1.0f); + gGL.end(); // draw an alpha of 1 where the sims are visible + gGL.flush(); glColorMask(FALSE, FALSE, FALSE, TRUE); - glColor4f(1.f, 1.f, 1.f, 1.f); - - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 1.0f); - glVertex2f(left, top); - glTexCoord2f(0.0f, 0.0f); - glVertex2f(left, bottom); - glTexCoord2f(1.0f, 0.0f); - glVertex2f(right, bottom); - glTexCoord2f(1.0f, 1.0f); - glVertex2f(right, top); - glEnd(); + gGL.color4f(1.f, 1.f, 1.f, 1.f); + + gGL.begin(GL_QUADS); + gGL.texCoord2f(0.0f, 1.0f); + gGL.vertex2f(left, top); + gGL.texCoord2f(0.0f, 0.0f); + gGL.vertex2f(left, bottom); + gGL.texCoord2f(1.0f, 0.0f); + gGL.vertex2f(right, bottom); + gGL.texCoord2f(1.0f, 1.0f); + gGL.vertex2f(right, top); + gGL.end(); } + gGL.flush(); glAlphaFunc(GL_GEQUAL, 0.01f); glColorMask(TRUE, TRUE, TRUE, TRUE); @@ -565,52 +572,54 @@ void LLWorldMapView::draw() LLGLSUIDefault gls_ui; LLViewerImage::bindTexture(simimage); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); F32 alpha = sim_alpha * info->mAlpha; - glColor4f(1.f, 1.0f, 1.0f, alpha); - - glBegin(GL_QUADS); - glTexCoord2f(0.f, 1.f); - glVertex3f(left, top, 0.f); - glTexCoord2f(0.f, 0.f); - glVertex3f(left, bottom, 0.f); - glTexCoord2f(1.f, 0.f); - glVertex3f(right, bottom, 0.f); - glTexCoord2f(1.f, 1.f); - glVertex3f(right, top, 0.f); - glEnd(); + gGL.color4f(1.f, 1.0f, 1.0f, alpha); + + gGL.begin(GL_QUADS); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3f(left, top, 0.f); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex3f(left, bottom, 0.f); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3f(right, bottom, 0.f); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex3f(right, top, 0.f); + gGL.end(); if (gSavedSettings.getBOOL("MapShowLandForSale") && overlayimage && overlayimage->getHasGLTexture()) { LLViewerImage::bindTexture(overlayimage); - glColor4f(1.f, 1.f, 1.f, alpha); - glBegin(GL_QUADS); - glTexCoord2f(0.f, 1.f); - glVertex3f(left, top, -0.5f); - glTexCoord2f(0.f, 0.f); - glVertex3f(left, bottom, -0.5f); - glTexCoord2f(1.f, 0.f); - glVertex3f(right, bottom, -0.5f); - glTexCoord2f(1.f, 1.f); - glVertex3f(right, top, -0.5f); - glEnd(); + gGL.color4f(1.f, 1.f, 1.f, alpha); + gGL.begin(GL_QUADS); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3f(left, top, -0.5f); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex3f(left, bottom, -0.5f); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3f(right, bottom, -0.5f); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex3f(right, top, -0.5f); + gGL.end(); } if ((info->mRegionFlags & REGION_FLAGS_NULL_LAYER) == 0) { // draw an alpha of 1 where the sims are visible (except NULL sims) - glBlendFunc(GL_ONE, GL_ZERO); + gGL.flush(); + gGL.blendFunc(GL_ONE, GL_ZERO); glColorMask(FALSE, FALSE, FALSE, TRUE); - glColor4f(1.f, 1.f, 1.f, 1.f); + gGL.color4f(1.f, 1.f, 1.f, 1.f); LLGLSNoTexture gls_no_texture; - glBegin(GL_QUADS); - glVertex2f(left, top); - glVertex2f(left, bottom); - glVertex2f(right, bottom); - glVertex2f(right, top); - glEnd(); - + gGL.begin(GL_QUADS); + gGL.vertex2f(left, top); + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, bottom); + gGL.vertex2f(right, top); + gGL.end(); + + gGL.flush(); glColorMask(TRUE, TRUE, TRUE, TRUE); } } @@ -618,16 +627,16 @@ void LLWorldMapView::draw() if (info->mAccess == SIM_ACCESS_DOWN) { // Draw a transparent red square over down sims - glBlendFunc(GL_DST_ALPHA, GL_SRC_ALPHA); - glColor4f(0.2f, 0.0f, 0.0f, 0.4f); + gGL.blendFunc(GL_DST_ALPHA, GL_SRC_ALPHA); + gGL.color4f(0.2f, 0.0f, 0.0f, 0.4f); LLGLSNoTexture gls_no_texture; - glBegin(GL_QUADS); - glVertex2f(left, top); - glVertex2f(left, bottom); - glVertex2f(right, bottom); - glVertex2f(right, top); - glEnd(); + gGL.begin(GL_QUADS); + gGL.vertex2f(left, top); + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, bottom); + gGL.vertex2f(right, top); + gGL.end(); } // If this is mature, and you are not, draw a line across it @@ -635,16 +644,16 @@ void LLWorldMapView::draw() && info->mAccess > SIM_ACCESS_PG && gAgent.isTeen()) { - glBlendFunc(GL_DST_ALPHA, GL_ZERO); + gGL.blendFunc(GL_DST_ALPHA, GL_ZERO); LLGLSNoTexture gls_no_texture; - glColor3f(1.f, 0.f, 0.f); - glBegin(GL_LINES); - glVertex2f(left, top); - glVertex2f(right, bottom); - glVertex2f(left, bottom); - glVertex2f(right, top); - glEnd(); + gGL.color3f(1.f, 0.f, 0.f); + gGL.begin(GL_LINES); + gGL.vertex2f(left, top); + gGL.vertex2f(right, bottom); + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, top); + gGL.end(); } // Draw the region name in the lower left corner @@ -697,13 +706,13 @@ void LLWorldMapView::draw() { LLGLSNoTexture gls_no_texture; glAlphaFunc(GL_GEQUAL, 0.0f); - glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA); - glColor4fv( mBackgroundColor.mV ); + gGL.blendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA); + gGL.color4fv( mBackgroundColor.mV ); gl_rect_2d(0, height, width, 0); } glAlphaFunc(GL_GEQUAL, 0.01f); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Infohubs if (gSavedSettings.getBOOL("MapShowInfohubs")) //(gMapScale >= sThresholdB) @@ -990,29 +999,29 @@ void LLWorldMapView::drawFrustum() F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); F32 half_width_pixels = half_width_meters * meters_to_pixels; - F32 ctr_x = mRect.getWidth() * 0.5f + sPanX; - F32 ctr_y = mRect.getHeight() * 0.5f + sPanY; + F32 ctr_x = getRect().getWidth() * 0.5f + sPanX; + F32 ctr_y = getRect().getHeight() * 0.5f + sPanY; LLGLSNoTexture gls_no_texture; // Since we don't rotate the map, we have to rotate the frustum. - glPushMatrix(); - glTranslatef( ctr_x, ctr_y, 0 ); + gGL.pushMatrix(); + gGL.translatef( ctr_x, ctr_y, 0 ); glRotatef( atan2( gCamera->getAtAxis().mV[VX], gCamera->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); // Draw triangle with more alpha in far pixels to make it // fade out in distance. - glBegin( GL_TRIANGLES ); - glColor4f(1.f, 1.f, 1.f, 0.25f); - glVertex2f( 0, 0 ); + gGL.begin( GL_TRIANGLES ); + gGL.color4f(1.f, 1.f, 1.f, 0.25f); + gGL.vertex2f( 0, 0 ); - glColor4f(1.f, 1.f, 1.f, 0.02f); - glVertex2f( -half_width_pixels, far_clip_pixels ); + gGL.color4f(1.f, 1.f, 1.f, 0.02f); + gGL.vertex2f( -half_width_pixels, far_clip_pixels ); - glColor4f(1.f, 1.f, 1.f, 0.02f); - glVertex2f( half_width_pixels, far_clip_pixels ); - glEnd(); - glPopMatrix(); + gGL.color4f(1.f, 1.f, 1.f, 0.02f); + gGL.vertex2f( half_width_pixels, far_clip_pixels ); + gGL.end(); + gGL.popMatrix(); } @@ -1027,8 +1036,8 @@ LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos ) // leave Z component in meters - pos_local.mV[VX] += mRect.getWidth() / 2 + sPanX; - pos_local.mV[VY] += mRect.getHeight() / 2 + sPanY; + pos_local.mV[VX] += getRect().getWidth() / 2 + sPanX; + pos_local.mV[VY] += getRect().getHeight() / 2 + sPanY; return pos_local; } @@ -1048,13 +1057,13 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& if( x < 0 || y < 0 - || x >= mRect.getWidth() - || y >= mRect.getHeight() ) + || x >= getRect().getWidth() + || y >= getRect().getHeight() ) { if (draw_arrow) { - drawTrackingCircle( mRect, x, y, color, 3, 15 ); - drawTrackingArrow( mRect, x, y, color ); + drawTrackingCircle( getRect(), x, y, color, 3, 15 ); + drawTrackingArrow( getRect(), x, y, color ); text_x = sTrackingArrowX; text_y = sTrackingArrowY; } @@ -1063,7 +1072,7 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& else if (LLTracker::getTrackingStatus() == LLTracker::TRACKING_LOCATION && LLTracker::getTrackedLocationType() != LLTracker::LOCATION_NOTHING) { - drawTrackingCircle( mRect, x, y, color, 3, 15 ); + drawTrackingCircle( getRect(), x, y, color, 3, 15 ); } else { @@ -1073,8 +1082,8 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& // clamp text position to on-screen const S32 TEXT_PADDING = DEFAULT_TRACKING_ARROW_SIZE + 2; S32 half_text_width = llfloor(font->getWidthF32(label) * 0.5f); - text_x = llclamp(text_x, half_text_width + TEXT_PADDING, mRect.getWidth() - half_text_width - TEXT_PADDING); - text_y = llclamp(text_y + vert_offset, TEXT_PADDING + vert_offset, mRect.getHeight() - llround(font->getLineHeight()) - TEXT_PADDING - vert_offset); + text_x = llclamp(text_x, half_text_width + TEXT_PADDING, getRect().getWidth() - half_text_width - TEXT_PADDING); + text_y = llclamp(text_y + vert_offset, TEXT_PADDING + vert_offset, getRect().getHeight() - llround(font->getLineHeight()) - TEXT_PADDING - vert_offset); if (label != "") { @@ -1102,8 +1111,8 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& // If you change this, then you need to change LLTracker::getTrackedPositionGlobal() as well LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y ) { - x -= llfloor((mRect.getWidth() / 2 + sPanX)); - y -= llfloor((mRect.getHeight() / 2 + sPanY)); + x -= llfloor((getRect().getWidth() / 2 + sPanX)); + y -= llfloor((getRect().getHeight() / 2 + sPanY)); LLVector3 pos_local( (F32)x, (F32)y, 0.f ); @@ -1210,15 +1219,15 @@ static void drawDot(F32 x_pixels, F32 y_pixels, F32 bottom = y_pixels - dot_radius; LLGLSNoTexture gls_no_texture; - glColor4fv( color.mV ); + gGL.color4fv( color.mV ); LLUI::setLineWidth(1.5f); F32 h_bar = relative_z > HEIGHT_THRESHOLD ? top : bottom; // horizontal bar Y - glBegin( GL_LINES ); - glVertex2f(left, h_bar); - glVertex2f(right, h_bar); - glVertex2f(center, top); - glVertex2f(center, bottom); - glEnd(); + gGL.begin( GL_LINES ); + gGL.vertex2f(center, top); + gGL.vertex2f(left, h_bar); + gGL.vertex2f(right, h_bar); + gGL.vertex2f(right, bottom); + gGL.end(); LLUI::setLineWidth(1.0f); } } @@ -1386,10 +1395,10 @@ void LLWorldMapView::drawTrackingCircle( const LLRect& rect, S32 x, S32 y, const } glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glTranslatef((F32)x, (F32)y, 0.f); + gGL.pushMatrix(); + gGL.translatef((F32)x, (F32)y, 0.f); gl_washer_segment_2d(inner_radius, outer_radius, start_theta, end_theta, 40, color, color); - glPopMatrix(); + gGL.popMatrix(); } @@ -1448,8 +1457,8 @@ void LLWorldMapView::setDirectionPos( LLTextBox* text_box, F32 rotation ) // Rotation of 0 means x = 1, y = 0 on the unit circle. - F32 map_half_height = mRect.getHeight() * 0.5f; - F32 map_half_width = mRect.getWidth() * 0.5f; + F32 map_half_height = getRect().getHeight() * 0.5f; + F32 map_half_width = getRect().getWidth() * 0.5f; F32 text_half_height = text_box->getRect().getHeight() * 0.5f; F32 text_half_width = text_box->getRect().getWidth() * 0.5f; F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width ); @@ -1462,8 +1471,8 @@ void LLWorldMapView::setDirectionPos( LLTextBox* text_box, F32 rotation ) void LLWorldMapView::updateDirections() { - S32 width = mRect.getWidth(); - S32 height = mRect.getHeight(); + S32 width = getRect().getWidth(); + S32 height = getRect().getHeight(); S32 text_height = mTextBoxNorth->getRect().getHeight(); S32 text_width = mTextBoxNorth->getRect().getWidth(); @@ -1695,7 +1704,7 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask ) S32 local_x, local_y; local_x = mMouseDownX + llfloor(sPanX - mMouseDownPanX); local_y = mMouseDownY + llfloor(sPanY - mMouseDownPanY); - LLRect clip_rect = mRect; + LLRect clip_rect = getRect(); clip_rect.stretch(-8); clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y); LLUI::setCursorPositionLocal(this, local_x, local_y); diff --git a/linden/indra/newview/llxmlrpctransaction.cpp b/linden/indra/newview/llxmlrpctransaction.cpp index 96f3326..bc10c1b 100644 --- a/linden/indra/newview/llxmlrpctransaction.cpp +++ b/linden/indra/newview/llxmlrpctransaction.cpp @@ -33,10 +33,10 @@ #include "llxmlrpctransaction.h" +#include "llcurl.h" #include "llviewercontrol.h" // Have to include these last to avoid queue redefinition! -#include #include #include "llappviewer.h" @@ -150,51 +150,48 @@ class LLXMLRPCTransaction::Impl { public: typedef LLXMLRPCTransaction::Status Status; - - CURL* mCurl; - CURLM* mCurlMulti; + + LLCurlEasyRequest* mCurlRequest; Status mStatus; CURLcode mCurlCode; std::string mStatusMessage; std::string mStatusURI; + LLCurl::TransferInfo mTransferInfo; - char mCurlErrorBuffer[CURL_ERROR_SIZE]; /* Flawfinder: ignore */ - std::string mURI; char* mRequestText; int mRequestTextSize; std::string mProxyAddress; - struct curl_slist* mHeaders; std::string mResponseText; XMLRPC_REQUEST mResponse; Impl(const std::string& uri, XMLRPC_REQUEST request, bool useGzip); Impl(const std::string& uri, - const std::string& method, LLXMLRPCValue params, bool useGzip); + const std::string& method, LLXMLRPCValue params, bool useGzip); ~Impl(); bool process(); void setStatus(Status code, - const std::string& message = "", const std::string& uri = ""); + const std::string& message = "", const std::string& uri = ""); void setCurlStatus(CURLcode); private: void init(XMLRPC_REQUEST request, bool useGzip); static size_t curlDownloadCallback( - void* data, size_t size, size_t nmemb, void* user_data); + char* data, size_t size, size_t nmemb, void* user_data); }; LLXMLRPCTransaction::Impl::Impl(const std::string& uri, XMLRPC_REQUEST request, bool useGzip) - : mCurl(0), mCurlMulti(0), + : mCurlRequest(0), mStatus(LLXMLRPCTransaction::StatusNotStarted), mURI(uri), - mRequestText(0), mHeaders(0), + mRequestText(0), mResponse(0) { init(request, useGzip); @@ -203,10 +200,10 @@ LLXMLRPCTransaction::Impl::Impl(const std::string& uri, LLXMLRPCTransaction::Impl::Impl(const std::string& uri, const std::string& method, LLXMLRPCValue params, bool useGzip) - : mCurl(0), mCurlMulti(0), + : mCurlRequest(0), mStatus(LLXMLRPCTransaction::StatusNotStarted), mURI(uri), - mRequestText(0), mHeaders(0), + mRequestText(0), mResponse(0) { XMLRPC_REQUEST request = XMLRPC_RequestNew(); @@ -222,55 +219,53 @@ LLXMLRPCTransaction::Impl::Impl(const std::string& uri, void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip) { - mCurl = curl_easy_init(); - + if (!mCurlRequest) + { + mCurlRequest = new LLCurlEasyRequest(); + } + if (gSavedSettings.getBOOL("BrowserProxyEnabled")) { mProxyAddress = gSavedSettings.getString("BrowserProxyAddress"); S32 port = gSavedSettings.getS32 ( "BrowserProxyPort" ); // tell curl about the settings - curl_easy_setopt(mCurl, CURLOPT_PROXY, mProxyAddress.c_str()); - curl_easy_setopt(mCurl, CURLOPT_PROXYPORT, (long) port); - curl_easy_setopt(mCurl, CURLOPT_PROXYTYPE, (long) CURLPROXY_HTTP); - }; - -// curl_easy_setopt(mCurl, CURLOPT_VERBOSE, 1L); // usefull for debugging - curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &curlDownloadCallback); - curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this); - curl_easy_setopt(mCurl, CURLOPT_ERRORBUFFER, &mCurlErrorBuffer); - curl_easy_setopt(mCurl, CURLOPT_CAINFO, gDirUtilp->getCAFile().c_str()); - curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, (long) gVerifySSLCert); - curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYHOST, gVerifySSLCert? 2L : 0L); + mCurlRequest->setoptString(CURLOPT_PROXY, mProxyAddress); + mCurlRequest->setopt(CURLOPT_PROXYPORT, port); + mCurlRequest->setopt(CURLOPT_PROXYTYPE, CURLPROXY_HTTP); + } + +// mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // usefull for debugging + mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1); + mCurlRequest->setWriteCallback(&curlDownloadCallback, (void*)this); + mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, gVerifySSLCert); + mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, gVerifySSLCert? 2 : 0); // Be a little impatient about establishing connections. - curl_easy_setopt(mCurl, CURLOPT_CONNECTTIMEOUT, 40L); + mCurlRequest->setopt(CURLOPT_CONNECTTIMEOUT, 40L); /* Setting the DNS cache timeout to -1 disables it completely. This might help with bug #503 */ - curl_easy_setopt(mCurl, CURLOPT_DNS_CACHE_TIMEOUT, -1L); + mCurlRequest->setopt(CURLOPT_DNS_CACHE_TIMEOUT, -1); + + mCurlRequest->slist_append("Content-Type: text/xml"); - mHeaders = curl_slist_append(mHeaders, "Content-Type: text/xml"); - curl_easy_setopt(mCurl, CURLOPT_URL, mURI.c_str()); - curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, mHeaders); if (useGzip) { - curl_easy_setopt(mCurl, CURLOPT_ENCODING, ""); + mCurlRequest->setoptString(CURLOPT_ENCODING, ""); } mRequestText = XMLRPC_REQUEST_ToXML(request, &mRequestTextSize); if (mRequestText) { - curl_easy_setopt(mCurl, CURLOPT_POSTFIELDS, mRequestText); - curl_easy_setopt(mCurl, CURLOPT_POSTFIELDSIZE, (long) mRequestTextSize); + mCurlRequest->setoptString(CURLOPT_POSTFIELDS, mRequestText); + mCurlRequest->setopt(CURLOPT_POSTFIELDSIZE, mRequestTextSize); } else { setStatus(StatusOtherError); } - - mCurlMulti = curl_multi_init(); - curl_multi_add_handle(mCurlMulti, mCurl); + + mCurlRequest->sendRequest(mURI); } @@ -281,30 +276,12 @@ LLXMLRPCTransaction::Impl::~Impl() XMLRPC_RequestFree(mResponse, 1); } - if (mHeaders) - { - curl_slist_free_all(mHeaders); - } - if (mRequestText) { XMLRPC_Free(mRequestText); } - if (mCurl) - { - if (mCurlMulti) - { - curl_multi_remove_handle(mCurlMulti, mCurl); - } - curl_easy_cleanup(mCurl); - } - - if (mCurlMulti) - { - curl_multi_cleanup(mCurlMulti); - } - + delete mCurlRequest; } bool LLXMLRPCTransaction::Impl::process() @@ -333,27 +310,28 @@ bool LLXMLRPCTransaction::Impl::process() const F32 MAX_PROCESSING_TIME = 0.05f; LLTimer timer; - int count; - - while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(mCurlMulti, &count)) + + while (mCurlRequest->perform() > 0) { if (timer.getElapsedTimeF32() >= MAX_PROCESSING_TIME) { return false; } } - - while(CURLMsg* curl_msg = curl_multi_info_read(mCurlMulti, &count)) + + while(1) { - if (CURLMSG_DONE == curl_msg->msg) + CURLcode result; + bool newmsg = mCurlRequest->getResult(&result, &mTransferInfo); + if (newmsg) { - if (curl_msg->data.result != CURLE_OK) + if (result != CURLE_OK) { - setCurlStatus(curl_msg->data.result); + setCurlStatus(result); llwarns << "LLXMLRPCTransaction CURL error " - << mCurlCode << ": " << mCurlErrorBuffer << llendl; + << mCurlCode << ": " << mCurlRequest->getErrorString() << llendl; llwarns << "LLXMLRPCTransaction request URI: " - << mURI << llendl; + << mURI << llendl; return true; } @@ -361,7 +339,7 @@ bool LLXMLRPCTransaction::Impl::process() setStatus(LLXMLRPCTransaction::StatusComplete); mResponse = XMLRPC_REQUEST_FromXML( - mResponseText.data(), mResponseText.size(), NULL); + mResponseText.data(), mResponseText.size(), NULL); bool hasError = false; bool hasFault = false; @@ -387,15 +365,19 @@ bool LLXMLRPCTransaction::Impl::process() setStatus(LLXMLRPCTransaction::StatusXMLRPCError); llwarns << "LLXMLRPCTransaction XMLRPC " - << (hasError ? "error " : "fault ") - << faultCode << ": " - << faultString << llendl; + << (hasError ? "error " : "fault ") + << faultCode << ": " + << faultString << llendl; llwarns << "LLXMLRPCTransaction request URI: " - << mURI << llendl; + << mURI << llendl; } return true; } + else + { + break; // done + } } return false; @@ -504,13 +486,13 @@ void LLXMLRPCTransaction::Impl::setCurlStatus(CURLcode code) } size_t LLXMLRPCTransaction::Impl::curlDownloadCallback( - void* data, size_t size, size_t nmemb, void* user_data) + char* data, size_t size, size_t nmemb, void* user_data) { Impl& impl(*(Impl*)user_data); size_t n = size * nmemb; - impl.mResponseText.append((const char*)data, n); + impl.mResponseText.append(data, n); if (impl.mStatus == LLXMLRPCTransaction::StatusStarted) { @@ -579,25 +561,17 @@ LLXMLRPCValue LLXMLRPCTransaction::responseValue() F64 LLXMLRPCTransaction::transferRate() { - if (!impl.mCurl || impl.mStatus != StatusComplete) + if (impl.mStatus != StatusComplete) { return 0.0L; } - double size_bytes = 0.0; - double time_seconds = 0.0; - double rate_bytes_per_sec = 0.0; - - curl_easy_getinfo(impl.mCurl, CURLINFO_SIZE_DOWNLOAD, &size_bytes); - curl_easy_getinfo(impl.mCurl, CURLINFO_TOTAL_TIME, &time_seconds); - curl_easy_getinfo(impl.mCurl, CURLINFO_SPEED_DOWNLOAD, &rate_bytes_per_sec); - - double rate_bits_per_sec = rate_bytes_per_sec * 8.0; + double rate_bits_per_sec = impl.mTransferInfo.mSpeedDownload * 8.0; llinfos << "Buffer size: " << impl.mResponseText.size() << " B" << llendl; - llinfos << "Transfer size: " << size_bytes << " B" << llendl; - llinfos << "Transfer time: " << time_seconds << " s" << llendl; - llinfos << "Transfer rate: " << rate_bits_per_sec/1000.0 << " Kb/s" << llendl; + llinfos << "Transfer size: " << impl.mTransferInfo.mSizeDownload << " B" << llendl; + llinfos << "Transfer time: " << impl.mTransferInfo.mTotalTime << " s" << llendl; + llinfos << "Transfer rate: " << rate_bits_per_sec / 1000.0 << " Kb/s" << llendl; return rate_bits_per_sec; } diff --git a/linden/indra/newview/lsl_guide.html b/linden/indra/newview/lsl_guide.html index 98b2c4c..03a0a58 100644 --- a/linden/indra/newview/lsl_guide.html +++ b/linden/indra/newview/lsl_guide.html @@ -1322,943 +1322,953 @@ HREF="#AEN3031" >
A.174. llParcelMediaQuery
A.175. llParseString2List
A.176. llParseStringKeepNulls
A.177. llParticleSystem
A.178. llPassCollisions
A.179. llPassTouches
A.180. llPlaySound
A.181. llPlaySoundSlave
A.182. llPointAt
A.183. llPow
A.184. llPreloadSound
A.185. llPushObject
A.186. llReleaseControls
A.187. llRemoteDataReply
A.188. llRemoteDataSetRegion
A.189. llRemoteLoadScript
A.190. llRemoteLoadScriptPin
A.191. llRemoveInventory
A.192. llRemoveVehicleFlags
A.193. llRequestAgentData
A.194. llRequestInventoryData
A.195. llRequestPermissions
A.196. llRequestSimulatorData
A.197. llResetScript
A.198. llResetOtherScript
A.199. llResetTime
A.200. llRezAtRoot
A.201. llRezObject
A.202. llRot2Angle
A.203. llRot2Axis
A.204. llRot2Euler
A.205. llRot2Fwd
A.206. llRot2Left
A.207. llRot2Up
A.208. llRotBetween
A.209. llRotLookAt
A.210. llRotTarget
A.211. llRotTargetRemove
A.212. llRotateTexture
A.213. llRound
A.214. llSameGroup
A.215. llSay
A.216. llScaleTexture
A.217. llScriptDanger
A.218. llSendRemoteData
A.219. llSensor
A.220. llSensorRemove
A.221. llSensorRepeat
A.222. llSetAlpha
A.223. llSetBuoyancy
A.224. llSetCameraAtOffset
A.225. llForceMouselookllSetClickAction
A.226. llSetCameraEyeOffsetllForceMouselook
A.227. llSetColorllSetCameraEyeOffset
A.228. llSetDamagellSetColor
A.229. llSetForcellSetDamage
A.230. llSetForceAndTorquellSetForce
A.231. llSetHoverHeightllSetForceAndTorque
A.232. llSetLinkAlphallSetHoverHeight
A.233. llSetLinkColorllSetLinkAlpha
A.234. llSetLinkPrimitiveParamsllSetLinkColor
A.235. llSetLinkTexturellSetLinkPrimitiveParams
A.236. llSetLocalRotllSetLinkTexture
A.237. llSetObjectDescllSetLocalRot
A.238. llSetObjectNamellSetObjectDesc
A.239. llSetParcelMusicURLllSetObjectName
A.240. llSetPayPricellSetParcelMusicURL
A.241. llSetPosllSetPayPrice
A.242. llSetPrimitiveParamsllSetPos
A.243. llSetRemoteScriptAccessPinllSetPrimitiveParams
A.244. llSetRotllSetRemoteScriptAccessPin
A.245. llSetScalellSetRot
A.246. llSetScriptStatellSetScale
A.247. llSetSitTextllSetScriptState
A.248. llSetSoundQueueingllSetSitText
A.249. llSetStatusllSetSoundQueueing
A.250. llSetTextllSetStatus
A.251. llSetTexturellSetText
A.252. llSetTextureAnimllSetTexture
A.253. llSetTimerEventllSetTextureAnim
A.254. llSetTorquellSetTimerEvent
A.255. llSetTouchTextllSetTorque
A.256. llSetVehicleFlagsllSetTouchText
A.257. llSetVehicleFloatParamllSetVehicleFlags
A.258. llSetVehicleTypellSetVehicleFloatParam
A.259. llSetVehicleRotationParamllSetVehicleType
A.260. llSetVehicleVectorParamllSetVehicleRotationParam
A.261. llShoutllSetVehicleVectorParam
A.262. llSinllShout
A.263. llSitTargetllSin
A.264. llSleepllSitTarget
A.265. llSqrtllSleep
A.266. llStartAnimationllSqrt
A.267. llStopAnimationllStartAnimation
A.268. llStopHoverllStopAnimation
A.269. llStopLookAtllStopHover
A.270. llStopMoveToTargetllStopLookAt
A.271. llStopPointAtllStopMoveToTarget
A.272. llStopSoundllStopPointAt
A.273. llStringLengthllStopSound
A.274. llSubStringIndexllStringLength
A.275. llStringToBase64llSubStringIndex
A.276. llTakeControlsllStringToBase64
A.277. llTanllTakeControls
A.278. llTargetllTan
A.279. llTargetOmegallTarget
A.280. llTargetRemovellTargetOmega
A.281. llTeleportAgentHomellTargetRemove
A.282. llToLowerllTeleportAgentHome
A.283. llToUpperllToLower
A.284. llTriggerSoundllToUpper
A.285. llTriggerSoundLimitedllTriggerSound
A.286. llUnescapeURLllTriggerSoundLimited
A.287. llUnSitllUnescapeURL
A.288. llVecDistllUnSit
A.289. llVecMagllVecDist
A.290. llVecNormllVecMag
A.291. llVolumeDetectllVecNorm
A.292. llWaterllVolumeDetect
A.293. llWhisperllWater
A.294. llWindllWhisper
A.295. llWind
A.296. llXorBase64Strings
B. Events
B.1. at_rot_target
B.2. at_target
B.3. attach
B.4. changed
B.5. collision
B.6. collision_end
B.7. collision_start
B.8. control
B.9. dataserver
B.10. email
B.11. land_collision
B.12. land_collision_end
B.13. land_collision_start
B.14. link_message
B.15. listen
B.16. money
B.17. moving_end
B.18. moving_start
B.19. no_sensor
B.20. not_at_rot_target
B.21. not_at_target
B.22. object_rez
B.23. on_rez
B.24. run_time_permissions
B.25. sensor
B.26. state_entry
B.27. state_exit
B.28. timer
B.29. touch
B.30. touch_end
B.31. touch_start
B.32. remote_data
C. Constants
C.1. Boolean Constants
C.2. Status Constants
C.3. Object Type Constants
C.4. Permission Constants
C.5. Inventory Constants
C.6. Pay Price Constants
C.7. Attachment Constants
C.8. Land Constants
C.9. Link Constants
C.10. Control Constants
C.11. Change Constants
C.12. Type Constants
C.13. Agent Info Constants
C.14. Texture Animation Constants
C.15. Particle System Constants
C.16. Agent Data Constants
C.17. Float Constants
C.18. Key Constant
C.19. Miscellaneous Integer Constants
C.20. Miscellaneous String Constants
C.21. Vector Constant
C.22. Rotation Constant
C.23. Simulator Data Constants
C.24. Vehicle Parameters
C.25. Vehicle Flags
C.26. Vehicle Types
C.27. Primitive Constants
C.28. XML-RPC Constants
C.29. Permission Mask Constants
C.30. Parcel Media Constants (Movies)Parcel Media Constants
C.31. Click Action Constants
llSay() function in state_entry() and do not bother to define a @@ -2537,7 +2547,7 @@ HREF="#AEN999" functions start with 'll'.

The example calls the llSay() function twice, which is used to emit text on the specified channel. @@ -2601,12 +2611,12 @@ CLASS="programlisting" >

There are many events that can be detected in your scripts by declaring a handler. The touch_start() event is raised when a @@ -3691,7 +3701,7 @@ CLASS="programlisting" non-zero integer. Once a conditional is determined to be true (non-zero), no further processing of 'else' conditionals will be considered. The NULL_KEY constant is counted as FALSE by conditional expressions.

The state_entry event occurs whenever a new state is @@ -4118,7 +4128,7 @@ NAME="AEN440" >

You will want to provide a state_exit() if you need to clean up any events that you have requested in the current state, but do @@ -4191,7 +4201,7 @@ state ListenState >

The state_exit() handler is not called when an object is @@ -4315,35 +4325,35 @@ HREF="#AEN1579" >llPowllRoundllSinllSqrtllTanllVecDistllVecMagllVecNormllRot2AnglellRot2AxisllRot2EulerllRot2FwdllRot2LeftllRot2UpllRotBetweenllStringLengthllSubStringIndexllStringToBase64llToLowerllToUpperllXorBase64StringsllParseString2ListllSayllShoutllWhisperllRemoveInventoryllRequestInventoryDatallRezObjectllRezAtRoot

Each scripted object can have one vehicle behavior that is configurable through the llSetVehicleType, llSetVehicleFloatParam, llSetVehicleVectorParam, llSetVehicleRotationParam, llSetVehicleFlags, and llRemoveVehicleFlags library calls.

It is not recommended that you mix vehicle behavior with some of the other script calls that provide impulse and forces to the object, especially llSetBuoyancy, llSetForce, llSetTorque, and llSetHoverHeight.

llLookAt, llRotLookAt, llMoveToTarget, and llTargetOmega at your own risk.

Before any vehicle parameters can be set the vehicle behavior must first be enabled. It is enabled by calling llSetVehicleType with any VEHICLE_TYPE_*, except VEHICLE_TYPE_NONE which will disable the vehicle. See the vehicle type constants section for currently available types. More types @@ -5447,7 +5457,7 @@ HREF="#AEN990" of linear and/or angular deflection or not. The speed of the deflections are controlled by setting the relevant parameters using the llSetVehicleFloatParam script call. Each variety of deflection has a @@ -5506,7 +5516,7 @@ HREF="#AEN1070" to make motion smoother and easier to control. Their directions can be set using the llSetVehicleVectorParam call. For example, to make the vehicle try to move at 5 @@ -6102,7 +6112,7 @@ NAME="AEN972" >

The vehicle has a built-in buoyancy feature that is independent of the llSetBuoyancy call. It is recommended that the two buoyancies do not mix! To make @@ -6117,7 +6127,7 @@ HREF="#AEN3770" >

It is not recommended that you mix vehicle buoyancy with the llSetBuoyancy script call. It would probably cause the object to fly up into space.

Adjusts the volume of the currently playing attached sound started with llPlaySound or llLoopSound. This function Has no effect on sounds started with llTriggerSound.

avatar at point attachment

If an avatar is sitting on the sit target, return the avatar's key, NULL_KEY otherwise. This only will detect avatars sitting on sit targets defined with llSitTarget.

id. Specify an empty string or NULL_KEY to not filter on the corresponding parameter.

number. Returns NULL_KEY if number is not valid sensed object.

id. Returns a bitfield of agent info constants.

face is ALL_SIDES the value returned is the mean average of all faces.

llResetTime. Use llSetTimerEvent if you want a reliable timing mechanism.

face is ALL_SIDES the color returned is the mean average of each channel.

type. Use the inventory constants to specify the type in the object inventory. Use the inventory constants to specify the mask for the specified inventory item. See Permission Mask Constants for more information. Example usage: @@ -8866,7 +8876,7 @@ CLASS="parameter" CLASS="parameter" >name is found. Use the inventory constants to compare against the return value.

pos or NULL_KEY if public.

Returns the type of the variable at name and returns the data through the dataserver event. The line count starts at zero. If the requested line is past the end of the notecard the dataserver event will return the constant EOF string. The key returned by this function is a unique identifier which will be supplied to the dataserver event in the name and returns this information through the dataserver event. The key returned by this function is a unique identifier which will be supplied to the dataserver event in the mask for the root object the task is attached to. See Permission Mask Constants for more information. Example usage: @@ -9688,7 +9698,7 @@ CLASS="FUNCDEF" >

Returns avatar that has enabled permissions. Returns NULL_KEY if not enabled.

parameters are identical to the rules of llSetPrimitiveParams, and the returned list is ordered as such. Most requested parameters do not require a value to be associated, except for texture-related requests (PRIM_TEXTURE, PRIM_COLOR, and PRIM_BUMP_SHINY) which require a side number to be specified as well. Valid parameters can be found in the Primitive Constants. Here is a simple example: @@ -10083,10 +10093,10 @@ CLASS="FUNCDEF" >

Returns the start parameter passed to llRezObject or llRezAtRoot. If the object was created from agent inventory, this function returns 0.

status. The value will be one of the status constants.

llGetAndResetTime or llResetTime. Use llSetTimerEvent if you want a reliable timing mechanism.

destination. This call will fail if PERMISSION_DEBIT has not been set.

ascending is TRUE. Note that sort only works in the head of each sort block is the same type.

number parameter to specify which event you are controlling. Use boolean values to specify

Similar to llPlaySound, this function plays a sound attached to an object, but will continuously loop that sound until llStopSound or llPlaySound is called. Only one sound may be attached to an object at a time. A second call to @@ -11879,12 +11889,12 @@ CLASS="parameter" >volume to 0 is not the same as calling llStopSound; a sound with 0 volume will continue to loop. To restart the sound from the beginning, call llStopSound before calling llLoopSound again.

llGetLinkNumber or a link constant.

size area. The parameters can be chosen from the land constants.

face is ALL_SIDES this function sets the texture offsets for all faces.

Returns TRUE if id is over land owned by the object owner, FALSE otherwise.

command can be one of PARCEL_MEDIA_COMMAND_STOP, PARCEL_MEDIA_COMMAND_PAUSE, PARCEL_MEDIA_COMMAND_PLAY, PARCEL_MEDIA_COMMAND_LOOP, PARCEL_MEDIA_COMMAND_TEXTURE, PARCEL_MEDIA_COMMAND_URL, PARCEL_MEDIA_COMMAND_TYPE, + PARCEL_MEDIA_COMMAND_DESC, + PARCEL_MEDIA_COMMAND_SIZE, + PARCEL_MEDIA_COMMAND_TIME, PARCEL_MEDIA_COMMAND_AGENT, PARCEL_MEDIA_COMMAND_UNLOAD, or PARCEL_MEDIA_COMMAND_AUTO_ALIGN.


A.174. llParcelMediaQuery

command can be one of PARCEL_MEDIA_COMMAND_TEXTURE or PARCEL_MEDIA_COMMAND_URL.


A.175. llParseString2List


A.176. llParseStringKeepNulls


A.177. llParticleSystem

are specified as an ordered list of parameter and value. Valid parameters and their expected values can be found in the particle system constants. Here is a simple example: @@ -12927,7 +12949,7 @@ CLASS="informalexample" >


A.178. llPassCollisions

pass is TRUE, land and object collisions are passed from children on to parents.


A.179. llPassTouches

pass is TRUE, touches are passed from children on to parents.


A.180. llPlaySound

Plays a sound once. The sound will be attached to an object and follow object movement. Only one sound may be attached to an object at a time, and attaching a new sound or calling llStopSound will stop the previously attached sound. A second call to llPlaySound with the @@ -13050,7 +13072,7 @@ CLASS="parameter" the new volume will be used, which allows control over the volume of already playing sounds. To restart the sound from the beginning, call llStopSound before calling llPlaySound again.


A.181. llPlaySoundSlave


A.182. llPointAt


A.183. llPow


A.184. llPreloadSound


A.185. llPushObject


A.186. llReleaseControls


A.187. llRemoteDataReply


A.188. llRemoteDataSetRegion


A.189. llRemoteLoadScript


A.190. llRemoteLoadScriptPin


A.191. llRemoveInventory


A.192. llRemoveVehicleFlags

flags to FALSE. Valid parameters can be found in the vehicle flags constants section.


A.193. llRequestAgentData

id. If and when the information is collected, the dataserver event is called with the returned key returned from this function @@ -13511,7 +13533,7 @@ CLASS="parameter" >requested parameter. See the agent data constants for details about valid values of data and what each will return in the dataserver event.


A.194. llRequestInventoryData

name. When data is available the dataserver event will be raised with the key returned from this function in the @@ -13575,7 +13597,7 @@ CLASS="section" >


A.195. llRequestPermissions

perm parameter should be a permission constant. Multiple permissions can be requested @@ -13616,7 +13638,7 @@ HREF="#AEN5348" permissions requests can only go to object owner. This call will not stop script execution - if the specified avatar grants the requested permissions, the run_time_permissions event will be called.


A.196. llRequestSimulatorData

sim_name. When the information is collected, the dataserver event is called with the returned key returned from this function @@ -13662,7 +13684,7 @@ CLASS="parameter" >requested parameter. See the simulator data constants for details about valid values of data and what each will return in the dataserver event.


A.197. llResetScript


A.198. llResetOtherScript


A.199. llResetTime


A.200. llRezAtRoot

param value will be available to the newly created object in the on_rez event or through the


A.201. llRezObject

param value will be available to the newly created object in the on_rez event or through the


A.202. llRot2Angle


A.203. llRot2Axis


A.204. llRot2Euler


A.205. llRot2Fwd


A.206. llRot2Left


A.207. llRot2Up


A.208. llRotBetween


A.209. llRotLookAt


A.210. llRotTarget

rotation as a rotational target and return an integer number for the target. The number can be used in llRotTargetRemove.


A.211. llRotTargetRemove


A.212. llRotateTexture

face ALL_SIDES, rotate the texture of all faces.


A.213. llRound


A.214. llSameGroup

Returns TRUE if the object or agent is in the same simulator and has the same active group as this object. Otherwise, returns FALSE.


A.215. llSay


A.216. llScaleTexture

scale_t respectively. If face is ALL_SIDES, scale the texture to all faces.


A.217. llScriptDanger


A.218. llSendRemoteData


A.219. llSensor

arc radians of forward vector. Specifying a blank name or NULL_KEY id will not filter results for any particular name or id. A range of 0.0 does not perform a @@ -14551,16 +14573,16 @@ HREF="#AEN6058" CLASS="parameter" >type parameter should be an object type constant value. If anything is found during the scan, a sensor event is triggered. A maximum of 16 items are passed to this event. If nothing is found during the scan, a no sensor event is triggered instead.


A.220. llSensorRemove


A.221. llSensorRepeat

rate seconds. Specifying a blank name or NULL_KEY id will not filter results for any particular name or id. A range of 0.0 cancels the @@ -14650,16 +14672,16 @@ HREF="#AEN6058" CLASS="parameter" >type parameter should be an object type constant value. If anything is found during the scan, a sensor event is triggered. A maximum of 16 items are passed to this event. If nothing is found during the scan, a no sensor event is triggered instead.


A.222. llSetAlpha

face. If face is ALL_SIDES, set the alpha to all faces. The


A.223. llSetBuoyancy


A.224. llSetCameraAtOffset


A.225. llForceMouselookA.225. llSetClickAction

llSetClickAction(integer action);

Sets which action is invoked when a resident clicks a prim.


A.226. llForceMouselook


A.226. llSetCameraEyeOffsetA.227. llSetCameraEyeOffset


A.227. llSetColorA.228. llSetColor

face. If face is ALL_SIDES, set the alpha to all faces.


A.228. llSetDamageA.229. llSetDamage


A.229. llSetForceA.230. llSetForce

force. The vector is in local coordinates if local is TRUE, global if FALSE.


A.230. llSetForceAndTorqueA.231. llSetForceAndTorque

torque. The vectors are in local coordinates if local is TRUE, global if FALSE.


A.231. llSetHoverHeightA.232. llSetHoverHeight

water is TRUE.


A.232. llSetLinkAlphaA.233. llSetLinkAlpha

llGetLinkNumber or a link constant. If face is ALL_SIDES, set the alpha of all faces.


A.233. llSetLinkColorA.234. llSetLinkColor

llGetLinkNumber or a link constant. If face is ALL_SIDES, set the color of all faces.


A.234. llSetLinkPrimitiveParamsA.235. llSetLinkPrimitiveParams

llGetLinkNumber or a link constant. The list is identical to that of llSetPrimitiveParams.


A.235. llSetLinkTextureA.236. llSetLinkTexture

llGetLinkNumber or a link constant. If face is ALL_SIDES, set the texture of all faces.


A.236. llSetLocalRotA.237. llSetLocalRot


A.237. llSetObjectDescA.238. llSetObjectDesc


A.238. llSetObjectNameA.239. llSetObjectName


A.239. llSetParcelMusicURLA.240. llSetParcelMusicURL


A.240. llSetPayPriceA.241. llSetPayPrice

Sets the default pay price and optionally the quick pay buttons for the 'Pay' window when someone pays this object. See also Pay Button Constants.


A.241. llSetPosA.242. llSetPos


A.242. llSetPrimitiveParamsA.243. llSetPrimitiveParams

are specified as an ordered list of parameter and value(s). Valid parameters and their expected values can be found in the Primitive Constants. Here is a simple example: @@ -15448,7 +15498,7 @@ CLASS="informalexample" >


A.243. llSetRemoteScriptAccessPinA.244. llSetRemoteScriptAccessPin


A.244. llSetRotA.245. llSetRot


A.245. llSetScaleA.246. llSetScale


A.246. llSetScriptStateA.247. llSetScriptState


A.247. llSetSitTextA.248. llSetSitText


A.248. llSetSoundQueueingA.249. llSetSoundQueueing

Sets whether successive calls to llPlaySound, , etc., (attached sounds) interrupt the playing sound. The default for objects is FALSE. Setting this value to TRUE will make the sound wait until the current playing sound reaches its end. The queue is one @@ -15658,15 +15708,15 @@ CLASS="section" >


A.249. llSetStatusA.250. llSetStatus

value. Use status constants for the values of


A.250. llSetTextA.251. llSetText


A.251. llSetTextureA.252. llSetTexture

face. If face is ALL_SIDES, set the texture to all faces.


A.252. llSetTextureAnimA.253. llSetTextureAnim

Animates a texture by setting the texture scale and offset. The mode is a mask of texture animation constants. You can only have one texture animation on an @@ -15810,17 +15860,17 @@ HREF="#AEN5805" reset it.

You can only do one traditional animation, ROTATE or SCALE at a time, you cannot combine masks. In the case of ROTATE or SCALE, face is ALL_SIDES, all textures on the object are animated.


A.253. llSetTimerEventA.254. llSetTimerEvent

Sets the timer event to be triggered every sec seconds. Passing in 0.0 stops further timer events.


A.254. llSetTorqueA.255. llSetTorque

torque. The vector is in local coordinates if local is TRUE, global if FALSE.


A.255. llSetTouchTextA.256. llSetTouchText


A.256. llSetVehicleFlagsA.257. llSetVehicleFlags

flags to TRUE. Valid parameters can be found in the vehicle flags constants section.


A.257. llSetVehicleFloatParamA.258. llSetVehicleFloatParam

param_value. Valid parameters and their expected values can be found in the vehicle parameter constants section.


A.258. llSetVehicleTypeA.259. llSetVehicleType

type. Valid types and an explanation of their characteristics can be found in the vehicle type constants section.


A.259. llSetVehicleRotationParamA.260. llSetVehicleRotationParam

param_value. Valid parameters can be found in the vehicle parameter constants section.


A.260. llSetVehicleVectorParamA.261. llSetVehicleVectorParam

param_value. Valid parameters can be found in the vehicle parameter constants section.


A.261. llShoutA.262. llShout


A.262. llSinA.263. llSin


A.263. llSitTargetA.264. llSitTarget

offset == ZERO_VECTOR clear the sit target.


A.264. llSleepA.265. llSleep


A.265. llSqrtA.266. llSqrt


A.266. llStartAnimationA.267. llStartAnimation


A.267. llStopAnimationA.268. llStopAnimation


A.268. llStopHoverA.269. llStopHover


A.269. llStopLookAtA.270. llStopLookAt


A.270. llStopMoveToTargetA.271. llStopMoveToTarget


A.271. llStopPointAtA.272. llStopPointAt


A.272. llStopSoundA.273. llStopSound

Stops a currently playing attached sound started with llPlaySound or llLoopSound. Has no effect on sounds started with llTriggerSound.


A.273. llStringLengthA.274. llStringLength


A.274. llSubStringIndexA.275. llSubStringIndex


A.275. llStringToBase64A.276. llStringToBase64


A.276. llTakeControlsA.277. llTakeControls

pass_on is TRUE, also send input to avatar.


A.277. llTanA.278. llTan


A.278. llTargetA.279. llTarget


A.279. llTargetOmegaA.280. llTargetOmega


A.280. llTargetRemoveA.281. llTargetRemove


A.281. llTeleportAgentHomeA.282. llTeleportAgentHome


A.282. llToLowerA.283. llToLower


A.283. llToUpperA.284. llToUpper


A.284. llTriggerSoundA.285. llTriggerSound

llTriggerSound does not affect the attached sounds created by llPlaySound and


A.285. llTriggerSoundLimitedA.286. llTriggerSoundLimited

llTriggerSound does not affect the attached sounds created by llPlaySound and


A.286. llUnescapeURLA.287. llUnescapeURL


A.287. llUnSitA.288. llUnSit


A.288. llVecDistA.289. llVecDist


A.289. llVecMagA.290. llVecMag


A.290. llVecNormA.291. llVecNorm


A.291. llVolumeDetectA.292. llVolumeDetect


A.292. llWaterA.293. llWater


A.293. llWhisperA.294. llWhisper


A.294. llWindA.295. llWind


A.295. llXorBase64StringsA.296. llXorBase64Strings


Appendix B. Events


B.1. at_rot_target

This event is triggered when a script comes within a defined angle of a target rotation. The range is set by a call to llRotTarget.


B.2. at_target

This event is triggered when a script comes within a defined range from a target position. The range and position are set by a call to llTarget.


B.3. attach

NULL_KEY.


B.4. changed

changed will be a bitfield of change constants.


B.5. collision


B.6. collision_end


B.7. collision_start


B.8. control

edges are bitfields of control constants.


B.9. dataserver

This event is triggered when the requested data is returned to the script. Data may be requested by the llRequestAgentData, the llRequestSimulatorData, the llRequestInventoryData, and the


B.10. email


B.11. land_collision


B.12. land_collision_end


B.13. land_collision_start


B.14. link_message


B.15. listen


B.16. money


B.17. moving_end


B.18. moving_start


B.19. no_sensor

This event is raised when sensors are active (via the llSensor library call) but are not sensing anything.


B.20. not_at_rot_target

When a target is set via the llRotTarget library call, but the script is outside the specified angle this event is raised.


B.21. not_at_target

When a target is set via the llTarget library call, but the script is outside the specified range this event is raised.


B.22. object_rez

Triggered when object rezzes another object from its inventory via the llRezObject api. The


B.23. on_rez

start_param is the parameter passed in from the call to llRezObject or llRezAtRoot.


B.24. run_time_permissions

llRequestPermissions library function is used to request these permissions and the various permissions integer constants can be supplied. The integer returned to this @@ -18594,7 +18644,7 @@ CLASS="section" >


B.25. sensor

This event is raised whenever objects matching the constraints of the llSensor command are detected. The number of detected objects is passed to @@ -18638,7 +18688,7 @@ CLASS="section" >


B.26. state_entry


B.27. state_exit


B.28. timer

This event is raised at regular intervals set by the llSetTimerEvent library function.


B.29. touch


B.30. touch_end


B.31. touch_start


B.32. remote_data

llOpenRemoteDataChannel, a remote XML-RPC server replies to a llSendRemoteData, or a remote XML-RPC client sends in an XML-RPC request. In the open case, @@ -18948,7 +18998,7 @@ CLASS="parameter" CLASS="appendix" >


Appendix C. Constants


C.1. Boolean Constants


C.2. Status Constants

The status constants are used in the llSetStatus and


C.3. Object Type Constants

These constants can be combined using the binary '|' operator and are used in the llSensor and related calls.


C.4. Permission Constants

The permission constants are used for passing values to llRequestPermissions, determining the value of llGetPermissions, and explicitly passed to the run_time_permissions event. For many of the basic library functions to work, a @@ -19176,7 +19226,7 @@ HREF="#AEN2342" >

If this permission enabled, the object can successfully call the llTakeControls library call.

If this permission is enabled, the object can successfully call llStartAnimation for the avatar that owns this object.


C.5. Inventory Constants


C.6. Pay Price Constants


C.7. Attachment Constants


C.8. Land Constants


C.9. Link Constants

These constants are used in calls to llSetLinkColor and


C.10. Control Constants

These constants are used in llTakeControls as well as the control event handler.


C.11. Change Constants

These constants are used in the changed event handler.


C.12. Type Constants


C.13. Agent Info Constants


C.14. Texture Animation Constants

These constants are used in the llSetTextureAnim api to control the animation mode.


C.15. Particle System Constants

These constants are used in calls to the llParticleSystem api to specify parameters.


C.16. Agent Data Constants

These constants are used in calls to the llRequestAgentData api to collect information about an agent which will be provided in the dataserver event.


C.17. Float Constants


C.18. Key Constant


C.19. Miscellaneous Integer Constants


C.20. Miscellaneous String Constants

There is one uncategorized string constant which is used in the dataserver event: EOF


C.21. Vector Constant


C.22. Rotation Constant


C.23. Simulator Data Constants

These constants are used in calls to the llRequestSimulatorData api to collect information about a simulator which will be provided in the dataserver event.


C.24. Vehicle Parameters


C.25. Vehicle Flags


C.26. Vehicle Types

Another vehicle that bounces along the ground but needs the motors to be driven from external controls or timer events.


C.31. Click Action Constants

These constants are passed to llSetClickAction to define default behavior when a resident clicks upon a prim.

Click Action Constants

CLICK_ACTION_NONE

Disables the click action for this prim.

CLICK_ACTION_TOUCH

Sets the click-action behavior of this prim to touch.

CLICK_ACTION_SIT

Sets the click-action behavior of this prim to sit.

CLICK_ACTION_BUY

Sets the click-action behavior of this prim to buy.

CLICK_ACTION_PAY

Sets the click-action behavior of this prim to pay.

CLICK_ACTION_OPEN

Sets the click-action behavior of this prim to open.

CLICK_ACTION_PLAY

Sets the click-action behavior of this prim to play.

CLICK_ACTION_OPEN_MEDIA

Sets the click-action behavior of this prim to open-media.

CLICK_ACTION_SIT

Sets the click-action behavior of this prim to sit.

CLICK_ACTION_SIT

Sets the click-action behavior of this prim to sit.

+ CommandLine="prebuild.bat releasenoopt" + ExcludedFromBuild="TRUE"/> - - - - - - + + + + + + + + + RelativePath=".\llfloaterhtmlhelp.cpp"> + RelativePath=".\llfloaterimagepreview.cpp"> @@ -596,6 +604,9 @@ RelativePath=".\llfloaterpostcard.cpp"> + + - - + + + + + + + + - - - - + + + + + + + + - - + + - - + + + + + + - - + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + RelativePath=".\llfloaterhtmlhelp.h"> + RelativePath=".\llfloaterimagepreview.h"> @@ -1737,6 +1796,9 @@ RelativePath=".\llfloaterpostcard.h"> + + - - + + + + - - - - + + + + + + + + - - + + - - + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/newview/newview_vc9.vcproj b/linden/indra/newview/newview_vc9.vcproj index 39b7c10..f4fdeb9 100644 --- a/linden/indra/newview/newview_vc9.vcproj +++ b/linden/indra/newview/newview_vc9.vcproj @@ -1,4400 +1,4540 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index a5b7d34..e0c2de7 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp @@ -50,6 +50,7 @@ #include "v3color.h" #include "llui.h" #include "llglheaders.h" +#include "llglimmediate.h" // newview includes #include "llagent.h" @@ -57,7 +58,6 @@ #include "lldrawpoolalpha.h" #include "lldrawpoolavatar.h" #include "lldrawpoolground.h" -#include "lldrawpoolsimple.h" #include "lldrawpoolbump.h" #include "lldrawpooltree.h" #include "lldrawpoolwater.h" @@ -96,6 +96,10 @@ #include "llglslshader.h" #include "llviewerjoystick.h" #include "llviewerdisplay.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h" +#include "llspatialpartition.h" + #ifdef _DEBUG // Debug indices is disabled for now for debug performance - djs 4/24/02 @@ -104,7 +108,7 @@ //#define DEBUG_INDICES #endif -#define AGGRESSIVE_OCCLUSION 0 +void render_ui_and_swap_if_needed(); const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f; const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f; @@ -112,15 +116,7 @@ const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f; const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f; const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40; const S32 MAX_OFFSCREEN_GEOMETRY_CHANGES_PER_FRAME = 10; - -// Guess on the number of visible objects in the scene, used to -// pre-size std::vector and other arrays. JC -const S32 ESTIMATED_VISIBLE_OBJECT_COUNT = 8192; - -// If the sum of the X + Y + Z scale of an object exceeds this number, -// it will be considered a potential occluder. For instance, -// a box of size 6 x 6 x 1 has sum 13, which might be an occluder. JC -const F32 OCCLUDE_SCALE_SUM_THRESHOLD = 8.f; +const U32 REFLECTION_MAP_RES = 128; // Max number of occluders to search for. JC const S32 MAX_OCCLUDER_COUNT = 2; @@ -128,31 +124,21 @@ const S32 MAX_OCCLUDER_COUNT = 2; extern S32 gBoxFrame; extern BOOL gRenderLightGlows; extern BOOL gHideSelectedObjects; +extern BOOL gDisplaySwapBuffers; -BOOL gAvatarBacklight = FALSE; +// hack counter for rendering a fixed number of frames after toggling +// fullscreen to work around DEV-5361 +static S32 sDelayedVBOEnable = 0; -S32 gTrivialAccepts = 0; +BOOL gAvatarBacklight = FALSE; BOOL gRenderForSelect = FALSE; LLPipeline gPipeline; +const LLMatrix4* gGLLastMatrix = NULL; //---------------------------------------- -void stamp(F32 x, F32 y, F32 xs, F32 ys) -{ - glBegin(GL_QUADS); - glTexCoord2f(0,0); - glVertex3f(x, y, 0.0f); - glTexCoord2f(1,0); - glVertex3f(x+xs,y, 0.0f); - glTexCoord2f(1,1); - glVertex3f(x+xs,y+ys,0.0f); - glTexCoord2f(0,1); - glVertex3f(x, y+ys,0.0f); - glEnd(); -} - U32 nhpo2(U32 v) { U32 r = 1; @@ -162,11 +148,60 @@ U32 nhpo2(U32 v) return r; } +glh::matrix4f glh_copy_matrix(GLdouble* src) +{ + glh::matrix4f ret; + for (U32 i = 0; i < 16; i++) + { + ret.m[i] = (F32) src[i]; + } + return ret; +} + +glh::matrix4f glh_get_current_modelview() +{ + return glh_copy_matrix(gGLModelView); +} + +glh::matrix4f glh_get_current_projection() +{ + return glh_copy_matrix(gGLProjection); +} + +void glh_copy_matrix(glh::matrix4f& src, GLdouble* dst) +{ + for (U32 i = 0; i < 16; i++) + { + dst[i] = src.m[i]; + } +} + +void glh_set_current_modelview(glh::matrix4f& mat) +{ + glh_copy_matrix(mat, gGLModelView); +} + +void glh_set_current_projection(glh::matrix4f& mat) +{ + glh_copy_matrix(mat, gGLProjection); +} + +glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar) +{ + glh::matrix4f ret( + 2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left), + 0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom), + 0.f, 0.f, -2.f/(zfar-znear), -(zfar+znear)/(zfar-znear), + 0.f, 0.f, 0.f, 1.f); + + return ret; +} //---------------------------------------- S32 LLPipeline::sCompiles = 0; +BOOL LLPipeline::sDynamicLOD = TRUE; BOOL LLPipeline::sShowHUDAttachments = TRUE; BOOL LLPipeline::sRenderPhysicalBeacons = TRUE; BOOL LLPipeline::sRenderScriptedBeacons = FALSE; @@ -176,32 +211,59 @@ BOOL LLPipeline::sRenderSoundBeacons = FALSE; BOOL LLPipeline::sRenderBeacons = FALSE; BOOL LLPipeline::sRenderHighlight = TRUE; BOOL LLPipeline::sRenderProcessBeacons = FALSE; -BOOL LLPipeline::sUseOcclusion = FALSE; +S32 LLPipeline::sUseOcclusion = 0; +BOOL LLPipeline::sFastAlpha = TRUE; +BOOL LLPipeline::sDisableShaders = FALSE; +BOOL LLPipeline::sRenderBump = TRUE; +BOOL LLPipeline::sUseFarClip = TRUE; BOOL LLPipeline::sSkipUpdate = FALSE; BOOL LLPipeline::sDynamicReflections = FALSE; +BOOL LLPipeline::sWaterReflections = FALSE; BOOL LLPipeline::sRenderGlow = FALSE; +BOOL LLPipeline::sReflectionRender = FALSE; +BOOL LLPipeline::sImpostorRender = FALSE; +BOOL LLPipeline::sUnderWaterRender = FALSE; +BOOL LLPipeline::sTextureBindTest = FALSE; +BOOL LLPipeline::sRenderFrameTest = FALSE; + +static LLCullResult* sCull = NULL; + +static const U32 gl_cube_face[] = +{ + GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, +}; + +void validate_framebuffer_object(); LLPipeline::LLPipeline() : - mScreenTex(0), - mGlowMap(0), - mGlowBuffer(0), + mCubeBuffer(NULL), + mInitialized(FALSE), mVertexShadersEnabled(FALSE), mVertexShadersLoaded(0), mLastRebuildPool(NULL), mAlphaPool(NULL), - mAlphaPoolPostWater(NULL), mSkyPool(NULL), - mStarsPool(NULL), mTerrainPool(NULL), mWaterPool(NULL), mGroundPool(NULL), mSimplePool(NULL), + mInvisiblePool(NULL), mGlowPool(NULL), mBumpPool(NULL), + mWLSkyPool(NULL), mLightMask(0), mLightMovingMask(0) { - mFramebuffer[0] = mFramebuffer[1] = 0; + //mFramebuffer[0] = mFramebuffer[1] = mFramebuffer[2] = mFramebuffer[3] = 0; + mBlurCubeBuffer[0] = mBlurCubeBuffer[1] = mBlurCubeBuffer[2] = 0; + mBlurCubeTexture[0] = mBlurCubeTexture[1] = mBlurCubeTexture[2] = 0; + + //mDepthbuffer[0] = mDepthbuffer[1] = 0; mCubeFrameBuffer = 0; mCubeDepth = 0; } @@ -210,27 +272,17 @@ void LLPipeline::init() { LLMemType mt(LLMemType::MTYPE_PIPELINE); + sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); + sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); + mInitialized = TRUE; stop_glerror(); - //create object partitions - //MUST MATCH declaration of eObjectPartitions - mObjectPartition.push_back(new LLVolumePartition()); //PARTITION_VOLUME - mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE - mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD - mObjectPartition.push_back(new LLTerrainPartition()); //PARTITION_TERRAIN - mObjectPartition.push_back(new LLWaterPartition()); //PARTITION_WATER - mObjectPartition.push_back(new LLTreePartition()); //PARTITION_TREE - mObjectPartition.push_back(new LLParticlePartition()); //PARTITION_PARTICLE - mObjectPartition.push_back(new LLCloudPartition()); //PARTITION_CLOUD - mObjectPartition.push_back(new LLGrassPartition()); //PARTITION_GRASS - mObjectPartition.push_back(NULL); //PARTITION_NONE - //create render pass pools getPool(LLDrawPool::POOL_ALPHA); - getPool(LLDrawPool::POOL_ALPHA_POST_WATER); getPool(LLDrawPool::POOL_SIMPLE); + getPool(LLDrawPool::POOL_INVISIBLE); getPool(LLDrawPool::POOL_BUMP); getPool(LLDrawPool::POOL_GLOW); @@ -239,7 +291,6 @@ void LLPipeline::init() mRenderTypeMask = 0xffffffff; // All render types start on mRenderDebugFeatureMask = 0xffffffff; // All debugging features on - mRenderFeatureMask = 0; // All features start off mRenderDebugMask = 0; // All debug starts off mOldRenderDebugMask = mRenderDebugMask; @@ -249,9 +300,10 @@ void LLPipeline::init() stop_glerror(); // Enable features - stop_glerror(); LLShaderMgr::setShaders(); + + stop_glerror(); } LLPipeline::~LLPipeline() @@ -261,6 +313,8 @@ LLPipeline::~LLPipeline() void LLPipeline::cleanup() { + assertInitialized(); + for(pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ) { @@ -295,12 +349,8 @@ void LLPipeline::cleanup() delete mAlphaPool; mAlphaPool = NULL; - delete mAlphaPoolPostWater; - mAlphaPoolPostWater = NULL; delete mSkyPool; mSkyPool = NULL; - delete mStarsPool; - mStarsPool = NULL; delete mTerrainPool; mTerrainPool = NULL; delete mWaterPool; @@ -309,10 +359,15 @@ void LLPipeline::cleanup() mGroundPool = NULL; delete mSimplePool; mSimplePool = NULL; + delete mInvisiblePool; + mInvisiblePool = NULL; delete mGlowPool; mGlowPool = NULL; delete mBumpPool; mBumpPool = NULL; + // don't delete wl sky pool it was handled above in the for loop + //delete mWLSkyPool; + mWLSkyPool = NULL; releaseGLBuffers(); @@ -321,21 +376,9 @@ void LLPipeline::cleanup() mFaceSelectImagep = NULL; mAlphaSizzleImagep = NULL; - for (S32 i = 0; i < NUM_PARTITIONS-1; i++) - { - delete mObjectPartition[i]; - } - mObjectPartition.clear(); - - mVisibleList.clear(); - mVisibleGroups.clear(); - mDrawableGroups.clear(); - mActiveGroups.clear(); - mVisibleBridge.clear(); mMovedBridge.clear(); - mOccludedBridge.clear(); - mAlphaGroups.clear(); - clearRenderMap(); + + mInitialized = FALSE; } //============================================================================ @@ -345,39 +388,47 @@ void LLPipeline::destroyGL() stop_glerror(); unloadShaders(); mHighlightFaces.clear(); - mVisibleList.clear(); - mVisibleGroups.clear(); - mDrawableGroups.clear(); - mActiveGroups.clear(); - mVisibleBridge.clear(); - mOccludedBridge.clear(); - mAlphaGroups.clear(); - clearRenderMap(); + + resetDrawOrders(); + resetVertexBuffers(); releaseGLBuffers(); -} -void LLPipeline::releaseGLBuffers() -{ - if (mGlowMap) + if (LLVertexBuffer::sEnableVBOs) { - glDeleteTextures(1, &mGlowMap); - mGlowMap = 0; + // render 30 frames after switching to work around DEV-5361 + sDelayedVBOEnable = 30; + LLVertexBuffer::sEnableVBOs = FALSE; } +} - if (mGlowBuffer) +void LLPipeline::resizeScreenTexture() +{ + if (gPipeline.canUseVertexShaders() && assertInitialized()) { - glDeleteTextures(1, &mGlowBuffer); - mGlowBuffer = 0; - } + GLuint resX = gViewerWindow->getWindowDisplayWidth(); + GLuint resY = gViewerWindow->getWindowDisplayHeight(); + + U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); + if (res_mod > 1) + { + resX /= res_mod; + resY /= res_mod; + } + + mScreen.release(); + mScreen.allocate(resX, resY, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB); - if (mScreenTex) - { - glDeleteTextures(1, &mScreenTex); - mScreenTex = 0; + llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl; } +} + +void LLPipeline::releaseGLBuffers() +{ + assertInitialized(); + if (mCubeBuffer) { mCubeBuffer = NULL; @@ -390,27 +441,152 @@ void LLPipeline::releaseGLBuffers() mCubeDepth = mCubeFrameBuffer = 0; } - if (mFramebuffer[0]) + /*if (mFramebuffer[0]) + { + glDeleteFramebuffersEXT(4, mFramebuffer); + mFramebuffer[0] = mFramebuffer[1] = mFramebuffer[2] = mFramebuffer[3] = 0; + }*/ + + if (mBlurCubeBuffer[0]) + { + glDeleteFramebuffersEXT(3, mBlurCubeBuffer); + mBlurCubeBuffer[0] = mBlurCubeBuffer[1] = mBlurCubeBuffer[2] = 0; + } + + if (mBlurCubeTexture[0]) + { + glDeleteTextures(3, mBlurCubeTexture); + mBlurCubeTexture[0] = mBlurCubeTexture[1] = mBlurCubeTexture[2] = 0; + } + + mWaterRef.release(); + mWaterDis.release(); + mScreen.release(); + + for (U32 i = 0; i < 3; i++) { - glDeleteFramebuffersEXT(2, mFramebuffer); - mFramebuffer[0] = mFramebuffer[1] = 0; + mGlow[i].release(); + } + + LLVOAvatar::resetImpostors(); +} + +void LLPipeline::createGLBuffers() +{ + assertInitialized(); + + if (LLPipeline::sDynamicReflections || + LLPipeline::sWaterReflections) + { //water reflection texture + U32 res = (U32) gSavedSettings.getS32("RenderWaterRefResolution"); + + mWaterRef.allocate(res,res,GL_RGBA,TRUE); + mWaterDis.allocate(res,res,GL_RGBA,TRUE); + + if (LLPipeline::sDynamicReflections) + { + //reflection map generation buffers + if (mCubeFrameBuffer == 0) + { + glGenFramebuffersEXT(1, &mCubeFrameBuffer); + glGenRenderbuffersEXT(1, &mCubeDepth); + + U32 res = REFLECTION_MAP_RES; + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mCubeDepth); + + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT,res,res); + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + + if (mCubeBuffer.isNull()) + { + res = 128; + mCubeBuffer = new LLCubeMap(); + mCubeBuffer->initGL(); + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCubeBuffer->getGLName()); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + for (U32 i = 0; i < 6; i++) + { + glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); + } + } + + if (mBlurCubeBuffer[0] == 0) + { + glGenFramebuffersEXT(3, mBlurCubeBuffer); + } + + if (mBlurCubeTexture[0] == 0) + { + glGenTextures(3, mBlurCubeTexture); + } + + res = (U32) gSavedSettings.getS32("RenderReflectionRes"); + + for (U32 j = 0; j < 3; j++) + { + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mBlurCubeTexture[j]); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + for (U32 i = 0; i < 6; i++) + { + glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); + } + } + } + } + + stop_glerror(); + + if (LLPipeline::sRenderGlow) + { //screen space glow buffers + const U32 glow_res = llmax(1, + llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); + + for (U32 i = 0; i < 3; i++) + { + mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE); + } } + + GLuint resX = gViewerWindow->getWindowDisplayWidth(); + GLuint resY = gViewerWindow->getWindowDisplayHeight(); + + mScreen.allocate(resX, resY, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB); } void LLPipeline::restoreGL() { - resetVertexBuffers(); + assertInitialized(); if (mVertexShadersEnabled) { LLShaderMgr::setShaders(); } - - for (U32 i = 0; i < mObjectPartition.size()-1; i++) + + if (gWorldp) { - if (mObjectPartition[i]) + for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); + iter != gWorldp->getRegionList().end(); ++iter) { - mObjectPartition[i]->restoreGL(); + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->restoreGL(); + } + } } } } @@ -421,7 +597,7 @@ BOOL LLPipeline::canUseVertexShaders() if (!gGLManager.mHasVertexShader || !gGLManager.mHasFragmentShader || !gFeatureManagerp->isFeatureAvailable("VertexShaderEnable") || - mVertexShadersLoaded == -1) + (assertInitialized() && mVertexShadersLoaded != 1) ) { return FALSE; } @@ -431,12 +607,31 @@ BOOL LLPipeline::canUseVertexShaders() } } +BOOL LLPipeline::canUseWindLightShaders() const +{ + return (!LLPipeline::sDisableShaders && + gWLSkyProgram.mProgramObject != 0 && + LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_WINDLIGHT) > 1); +} + +BOOL LLPipeline::canUseWindLightShadersOnObjects() const +{ + return (canUseWindLightShaders() + && LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_OBJECT) > 0); +} + void LLPipeline::unloadShaders() { LLShaderMgr::unloadShaders(); + mVertexShadersLoaded = 0; } +void LLPipeline::assertInitializedDoError() +{ + llerrs << "LLPipeline used when uninitialized." << llendl; +} + //============================================================================ void LLPipeline::enableShadows(const BOOL enable_shadows) @@ -458,6 +653,8 @@ S32 LLPipeline::getMaxLightingDetail() const S32 LLPipeline::setLightingDetail(S32 level) { + assertInitialized(); + if (level < 0) { level = gSavedSettings.getS32("RenderLightingDetail"); @@ -466,10 +663,7 @@ S32 LLPipeline::setLightingDetail(S32 level) if (level != mLightingDetail) { gSavedSettings.setS32("RenderLightingDetail", level); - if (level >= 2) - { - gObjectList.relightAllObjects(); - } + mLightingDetail = level; if (mVertexShadersLoaded == 1) @@ -487,9 +681,9 @@ public: LLOctreeDirtyTexture(const std::set& textures) : mTextures(textures) { } - virtual void visit(const LLOctreeState* state) + virtual void visit(const LLOctreeNode* node) { - LLSpatialGroup* group = (LLSpatialGroup*) state->getNode()->getListener(0); + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->getData().empty()) { @@ -517,6 +711,8 @@ public: // Called when a texture changes # of channels (causes faces to move to alpha pool) void LLPipeline::dirtyPoolObjectTextures(const std::set& textures) { + assertInitialized(); + // *TODO: This is inefficient and causes frame spikes; need a better way to do this // Most of the time is spent in dirty.traverse. @@ -529,18 +725,29 @@ void LLPipeline::dirtyPoolObjectTextures(const std::set& texture } } - LLOctreeDirtyTexture dirty(textures); - for (U32 i = 0; i < mObjectPartition.size(); i++) + if (gWorldp) { - if (mObjectPartition[i]) + LLOctreeDirtyTexture dirty(textures); + for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); + iter != gWorldp->getRegionList().end(); ++iter) { - dirty.traverse(mObjectPartition[i]->mOctree); + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + dirty.traverse(part->mOctree); + } + } } } } LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) { + assertInitialized(); + LLDrawPool *poolp = NULL; switch( type ) { @@ -548,6 +755,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) poolp = mSimplePool; break; + case LLDrawPool::POOL_INVISIBLE: + poolp = mInvisiblePool; + break; + case LLDrawPool::POOL_GLOW: poolp = mGlowPool; break; @@ -568,10 +779,6 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) poolp = mAlphaPool; break; - case LLDrawPool::POOL_ALPHA_POST_WATER: - poolp = mAlphaPoolPostWater; - break; - case LLDrawPool::POOL_AVATAR: break; // Do nothing @@ -579,10 +786,6 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) poolp = mSkyPool; break; - case LLDrawPool::POOL_STARS: - poolp = mStarsPool; - break; - case LLDrawPool::POOL_WATER: poolp = mWaterPool; break; @@ -591,6 +794,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) poolp = mGroundPool; break; + case LLDrawPool::POOL_WL_SKY: + poolp = mWLSkyPool; + break; + default: llassert(0); llerrs << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl; @@ -638,7 +845,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* image bool alpha = te->getColor().mV[3] < 0.999f; if (imagep) { - alpha = alpha || (imagep->getComponents() == 4) || (imagep->getComponents() == 2); + alpha = alpha || (imagep->getComponents() == 4 && ! imagep->mIsMediaTexture) || (imagep->getComponents() == 2); } if (alpha) @@ -659,6 +866,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* image void LLPipeline::addPool(LLDrawPool *new_poolp) { LLMemType mt(LLMemType::MTYPE_PIPELINE); + assertInitialized(); mPools.insert(new_poolp); addToQuickLookup( new_poolp ); } @@ -686,6 +894,8 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) { LLFastTimer t(LLFastTimer::FTM_PIPELINE); + assertInitialized(); + LLPointer drawablep = drawable; // make sure this doesn't get deleted before we are done // Based on flags, remove the drawable from the queues that it's on. @@ -721,8 +931,13 @@ U32 LLPipeline::addObject(LLViewerObject *vobj) return 0; } - LLDrawable *drawablep = vobj->createDrawable(this); + LLDrawable* drawablep = vobj->mDrawable; + if (!drawablep) + { + drawablep = vobj->createDrawable(this); + } + llassert(drawablep); if (vobj->getParent()) @@ -742,8 +957,14 @@ U32 LLPipeline::addObject(LLViewerObject *vobj) void LLPipeline::resetFrameStats() { + assertInitialized(); + mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); + if (mBatchCount > 0) + { + mMeanBatchSize = gPipeline.mTrianglesDrawn/gPipeline.mBatchCount; + } mTrianglesDrawn = 0; sCompiles = 0; mVerticesRelit = 0; @@ -775,6 +996,9 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) { return; } + + assertInitialized(); + // update drawable now drawablep->clearState(LLDrawable::MOVE_UNDAMPED); // force to DAMPED drawablep->updateMove(); // returns done @@ -801,6 +1025,9 @@ void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep) { return; } + + assertInitialized(); + // update drawable now drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED drawablep->updateMove(); @@ -836,7 +1063,7 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) void LLPipeline::updateMove() { - //LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); + LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); LLMemType mt(LLMemType::MTYPE_PIPELINE); if (gSavedSettings.getBOOL("FreezeTime")) @@ -844,6 +1071,8 @@ void LLPipeline::updateMove() return; } + assertInitialized(); + for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin(); iter != mRetexturedList.end(); ++iter) { @@ -881,11 +1110,18 @@ void LLPipeline::updateMove() //balance octrees { LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE); - for (U32 i = 0; i < mObjectPartition.size()-1; i++) + + for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); + iter != gWorldp->getRegionList().end(); ++iter) { - if (mObjectPartition[i]) + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { - mObjectPartition[i]->mOctree->balance(); + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->mOctree->balance(); + } } } } @@ -915,35 +1151,80 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera return radius*radius * 3.14159f; } -void LLPipeline::updateCull(LLCamera& camera) +void LLPipeline::grabReferences(LLCullResult& result) +{ + sCull = &result; +} + +void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip) { LLFastTimer t(LLFastTimer::FTM_CULL); LLMemType mt(LLMemType::MTYPE_PIPELINE); - mVisibleList.clear(); - mVisibleGroups.clear(); - mDrawableGroups.clear(); - mActiveGroups.clear(); - gTrivialAccepts = 0; - mVisibleBridge.clear(); + grabReferences(result); + + sCull->clear(); + + BOOL to_texture = LLPipeline::sUseOcclusion > 1 && + !hasRenderType(LLPipeline::RENDER_TYPE_HUD) && + !sReflectionRender && + gPipeline.canUseVertexShaders() && + sRenderGlow && + gGLManager.mHasFramebufferObject; + + if (to_texture) + { + mScreen.bindTarget(); + } + + glPushMatrix(); + gGLLastMatrix = NULL; + glLoadMatrixd(gGLLastModelView); + + LLVertexBuffer::unbind(); + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); + + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); - processOcclusion(camera); + for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); + iter != gWorldp->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + if (water_clip != 0) + { + LLPlane plane(LLVector3(0,0, (F32) -water_clip), (F32) water_clip*region->getWaterHeight()); + camera.setUserClipPlane(plane); + } + else + { + camera.disableUserClipPlane(); + } - for (U32 i = 0; i < mObjectPartition.size(); i++) - { - if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { - mObjectPartition[i]->cull(camera); + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + if (hasRenderType(part->mDrawableType)) + { + part->cull(camera); + } + } } } + camera.disableUserClipPlane(); + if (gSky.mVOSkyp.notNull() && gSky.mVOSkyp->mDrawable.notNull()) { // Hack for sky - always visible. if (hasRenderType(LLPipeline::RENDER_TYPE_SKY)) { gSky.mVOSkyp->mDrawable->setVisible(camera); - mVisibleList.push_back(gSky.mVOSkyp->mDrawable); + sCull->pushDrawable(gSky.mVOSkyp->mDrawable); gSky.updateCull(); stop_glerror(); } @@ -953,20 +1234,35 @@ void LLPipeline::updateCull(LLCamera& camera) llinfos << "No sky drawable!" << llendl; } - if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) && gSky.mVOGroundp.notNull() && gSky.mVOGroundp->mDrawable.notNull()) + if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) && + !gPipeline.canUseWindLightShaders() && + gSky.mVOGroundp.notNull() && + gSky.mVOGroundp->mDrawable.notNull() && + !LLPipeline::sWaterReflections) { gSky.mVOGroundp->mDrawable->setVisible(camera); - mVisibleList.push_back(gSky.mVOGroundp->mDrawable); + sCull->pushDrawable(gSky.mVOGroundp->mDrawable); + } + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + glPopMatrix(); + + if (to_texture) + { + mScreen.flush(); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } } -void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera, BOOL active) +void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) { if (group->getData().empty()) { return; } + group->setVisible(); + if (!sSkipUpdate) { group->updateDistance(camera); @@ -978,29 +1274,39 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera, BOOL act { return; } + + assertInitialized(); - group->mLastRenderTime = gFrameTimeSeconds; if (!group->mSpatialPartition->mRenderByGroup) { //render by drawable - mDrawableGroups.push_back(group); - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) - { - markVisible(*i, camera); - } + sCull->pushDrawableGroup(group); } else - { //render by group - if (active) - { - mActiveGroups.push_back(group); - } - else - { - mVisibleGroups.push_back(group); - for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) + { //render by group + sCull->pushVisibleGroup(group); + } + + mNumVisibleNodes++; +} + +void LLPipeline::markOccluder(LLSpatialGroup* group) +{ + if (sUseOcclusion > 1 && group && !group->isState(LLSpatialGroup::ACTIVE_OCCLUSION)) + { + LLSpatialGroup* parent = group->getParent(); + + if (!parent || !parent->isState(LLSpatialGroup::OCCLUDED)) + { //only mark top most occluders as active occlusion + sCull->pushOcclusionGroup(group); + group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); + + if (parent && + !parent->isState(LLSpatialGroup::ACTIVE_OCCLUSION) && + parent->getElementCount() == 0 && + parent->needsUpdate()) { - LLSpatialBridge* bridge = *i; - markVisible(bridge, camera); + sCull->pushOcclusionGroup(group); + parent->setState(LLSpatialGroup::ACTIVE_OCCLUSION); } } } @@ -1008,38 +1314,37 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera, BOOL act void LLPipeline::doOcclusion(LLCamera& camera) { - if (sUseOcclusion) + LLVertexBuffer::unbind(); + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) { - for (U32 i = 0; i < mObjectPartition.size(); i++) - { - if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) - { - mObjectPartition[i]->doOcclusion(&camera); - } - } - -#if AGGRESSIVE_OCCLUSION - for (LLSpatialBridge::bridge_vector_t::iterator i = mVisibleBridge.begin(); i != mVisibleBridge.end(); ++i) + glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE); + } + else + { + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + } + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + + if (LLPipeline::sUseOcclusion > 1) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) { - LLSpatialBridge* bridge = *i; - if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) - { - glPushMatrix(); - glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); - LLCamera trans = bridge->transformCamera(camera); - bridge->doOcclusion(&trans); - glPopMatrix(); - mOccludedBridge.push_back(bridge); - } + LLSpatialGroup* group = *iter; + group->doOcclusion(&camera); + group->clearState(LLSpatialGroup::ACTIVE_OCCLUSION); } -#endif } + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); } BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) { BOOL update_complete = drawablep->updateGeometry(priority); - if (update_complete) + if (update_complete && assertInitialized()) { drawablep->setState(LLDrawable::BUILT); mGeometryChanges++; @@ -1055,6 +1360,17 @@ void LLPipeline::updateGeom(F32 max_dtime) LLFastTimer t(LLFastTimer::FTM_GEO_UPDATE); + assertInitialized(); + + if (sDelayedVBOEnable > 0) + { + if (--sDelayedVBOEnable <= 0) + { + resetVertexBuffers(); + LLVertexBuffer::sEnableVBOs = TRUE; + } + } + // notify various object types to reset internal cost metrics, etc. // for now, only LLVOVolume does this to throttle LOD changes LLVOVolume::preUpdateGeom(); @@ -1091,9 +1407,10 @@ void LLPipeline::updateGeom(F32 max_dtime) // Iterate through some drawables on the non-priority build queue S32 min_count = 16; - if (mBuildQ2.size() > 1000) + S32 size = (S32) mBuildQ2.size(); + if (size > 1024) { - min_count = mBuildQ2.size(); + min_count = llclamp((S32) (size * (F32) size/4096), 16, size); } S32 count = 0; @@ -1144,44 +1461,25 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) LLMemType mt(LLMemType::MTYPE_PIPELINE); if(!drawablep || drawablep->isDead()) { - llwarns << "LLPipeline::markVisible called with NULL drawablep" << llendl; return; } - -#if LL_DEBUG if (drawablep->isSpatialBridge()) { - if (std::find(mVisibleBridge.begin(), mVisibleBridge.end(), (LLSpatialBridge*) drawablep) != - mVisibleBridge.end()) - { - llerrs << "Spatial bridge marked visible redundantly." << llendl; - } + sCull->pushBridge((LLSpatialBridge*) drawablep); } else { - if (std::find(mVisibleList.begin(), mVisibleList.end(), drawablep) != - mVisibleList.end()) - { - llerrs << "Drawable marked visible redundantly." << llendl; - } + sCull->pushDrawable(drawablep); } -#endif - if (drawablep->isSpatialBridge()) - { - mVisibleBridge.push_back((LLSpatialBridge*) drawablep); - } - else - { - mVisibleList.push_back(drawablep); - } drawablep->setVisible(camera); } void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) { LLMemType mt(LLMemType::MTYPE_PIPELINE); + if (!drawablep) { llerrs << "Sending null drawable to moved list!" << llendl; @@ -1200,6 +1498,7 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) markMoved(drawablep->getParent(), damped_motion); } + assertInitialized(); if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) { @@ -1226,11 +1525,14 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) void LLPipeline::markShift(LLDrawable *drawablep) { LLMemType mt(LLMemType::MTYPE_PIPELINE); + if (!drawablep || drawablep->isDead()) { return; } + assertInitialized(); + if (!drawablep->isState(LLDrawable::ON_SHIFT_LIST)) { drawablep->getVObj()->setChanged(LLXform::SHIFTED | LLXform::SILHOUETTE); @@ -1246,6 +1548,14 @@ void LLPipeline::markShift(LLDrawable *drawablep) void LLPipeline::shiftObjects(const LLVector3 &offset) { LLMemType mt(LLMemType::MTYPE_PIPELINE); + + assertInitialized(); + + //do a swap to indicate an invalid previous frame camera + render_ui_and_swap_if_needed(); + glClear(GL_DEPTH_BUFFER_BIT); + gDisplaySwapBuffers = FALSE; + for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); iter != mShiftList.end(); iter++) { @@ -1259,11 +1569,17 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) } mShiftList.resize(0); - for (U32 i = 0; i < mObjectPartition.size()-1; i++) + for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); + iter != gWorldp->getRegionList().end(); ++iter) { - if (mObjectPartition[i]) + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { - mObjectPartition[i]->shift(offset); + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->shift(offset); + } } } } @@ -1271,7 +1587,8 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) void LLPipeline::markTextured(LLDrawable *drawablep) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - if (drawablep && !drawablep->isDead()) + + if (drawablep && !drawablep->isDead() && assertInitialized()) { mRetexturedList.insert(drawablep); } @@ -1281,7 +1598,7 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f { LLMemType mt(LLMemType::MTYPE_PIPELINE); - if (drawablep && !drawablep->isDead()) + if (drawablep && !drawablep->isDead() && assertInitialized()) { if (!drawablep->isState(LLDrawable::BUILT)) { @@ -1305,60 +1622,94 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f drawablep->getVObj()->setChanged(LLXform::SILHOUETTE); } drawablep->setState(flag); - if ((flag & LLDrawable::REBUILD_LIGHTING) && drawablep->getLit()) - { - if (drawablep->isLight()) - { - drawablep->clearState(LLDrawable::LIGHTING_BUILT); - } - else - { - drawablep->clearState(LLDrawable::LIGHTING_BUILT); - } - } } } -void LLPipeline::markRelight(LLDrawable *drawablep, const BOOL priority) +void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) { - if (getLightingDetail() >= 2) + const U32 face_mask = (1 << LLPipeline::RENDER_TYPE_AVATAR) | + (1 << LLPipeline::RENDER_TYPE_GROUND) | + (1 << LLPipeline::RENDER_TYPE_TERRAIN) | + (1 << LLPipeline::RENDER_TYPE_TREE) | + (1 << LLPipeline::RENDER_TYPE_SKY) | + (1 << LLPipeline::RENDER_TYPE_WATER); + + if (mRenderTypeMask & face_mask) { - markRebuild(drawablep, LLDrawable::REBUILD_LIGHTING, FALSE); + //clear faces from face pools + LLFastTimer t(LLFastTimer::FTM_RESET_DRAWORDER); + gPipeline.resetDrawOrders(); } -} -void LLPipeline::stateSort(LLCamera& camera) -{ LLFastTimer ftm(LLFastTimer::FTM_STATESORT); LLMemType mt(LLMemType::MTYPE_PIPELINE); - for (LLSpatialGroup::sg_vector_t::iterator iter = mVisibleGroups.begin(); iter != mVisibleGroups.end(); ++iter) + grabReferences(result); + { - stateSort(*iter, camera); + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + group->checkOcclusion(); + if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) + { + markOccluder(group); + } + else + { + group->setVisible(); + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + markVisible(*i, camera); + } + } + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + group->checkOcclusion(); + if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) + { + markOccluder(group); + } + else + { + group->setVisible(); + stateSort(group, camera); + } + } } - - for (LLSpatialBridge::bridge_vector_t::iterator i = mVisibleBridge.begin(); i != mVisibleBridge.end(); ++i) + { - LLSpatialBridge* bridge = *i; - if (!bridge->isDead()) + for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { - stateSort(bridge, camera); + LLCullResult::bridge_list_t::iterator cur_iter = i; + LLSpatialBridge* bridge = *cur_iter; + LLSpatialGroup* group = bridge->getSpatialGroup(); + if (!bridge->isDead() && group && !group->isState(LLSpatialGroup::OCCLUDED)) + { + stateSort(bridge, camera); + } } } - for (LLDrawable::drawable_vector_t::iterator iter = mVisibleList.begin(); - iter != mVisibleList.end(); iter++) { - LLDrawable *drawablep = *iter; - if (!drawablep->isDead()) + LLFastTimer ftm(LLFastTimer::FTM_STATESORT_DRAWABLE); + for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); + iter != sCull->endVisibleList(); ++iter) { - stateSort(drawablep, camera); + LLDrawable *drawablep = *iter; + if (!drawablep->isDead()) + { + stateSort(drawablep, camera); + } } } - for (LLSpatialGroup::sg_vector_t::iterator iter = mActiveGroups.begin(); iter != mActiveGroups.end(); ++iter) { - stateSort(*iter, camera); + LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY); + LLVertexBuffer::clientCopy(); } postSort(camera); @@ -1375,19 +1726,12 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) stateSort(drawablep, camera); } } - -#if !LL_DARWIN - if (gFrameTimeSeconds - group->mLastUpdateTime > 4.f) - { - group->makeStatic(); - } -#endif } void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - if (!sSkipUpdate) + if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) { bridge->updateDistance(camera); } @@ -1396,8 +1740,7 @@ void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - LLFastTimer ftm(LLFastTimer::FTM_STATESORT_DRAWABLE); - + if (!drawablep || drawablep->isDead() || !hasRenderType(drawablep->getRenderType())) @@ -1414,6 +1757,17 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } + if (drawablep->isAvatar()) + { //don't draw avatars beyond render distance or if we don't have a spatial group. + if ((drawablep->getSpatialGroup() == NULL) || + (drawablep->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance)) + { + return; + } + } + + assertInitialized(); + if (hasRenderType(drawablep->mRenderType)) { if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE)) @@ -1427,17 +1781,21 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } - if (!drawablep->isActive() && drawablep->isVisible()) + LLSpatialGroup* group = drawablep->getSpatialGroup(); + if (!group || group->changeLOD()) { - if (!sSkipUpdate) + if (!drawablep->isActive() && drawablep->isVisible()) { - drawablep->updateDistance(camera); + if (!sSkipUpdate) + { + drawablep->updateDistance(camera); + } + } + else if (drawablep->isAvatar() && drawablep->isVisible()) + { + LLVOAvatar* vobj = (LLVOAvatar*) drawablep->getVObj().get(); + vobj->updateVisibility(); } - } - else if (drawablep->isAvatar() && drawablep->isVisible()) - { - LLVOAvatar* vobj = (LLVOAvatar*) drawablep->getVObj().get(); - vobj->updateVisibility(FALSE); } for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); @@ -1457,15 +1815,16 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } } - - + mNumVisibleFaces += drawablep->getNumFaces(); } -void LLPipeline::forAllDrawables(LLSpatialGroup::sg_vector_t& groups, void (*func)(LLDrawable*)) +void forAllDrawables(LLCullResult::sg_list_t::iterator begin, + LLCullResult::sg_list_t::iterator end, + void (*func)(LLDrawable*)) { - for (LLSpatialGroup::sg_vector_t::iterator i = groups.begin(); i != groups.end(); ++i) + for (LLCullResult::sg_list_t::iterator i = begin; i != end; ++i) { for (LLSpatialGroup::element_iter j = (*i)->getData().begin(); j != (*i)->getData().end(); ++j) { @@ -1476,9 +1835,8 @@ void LLPipeline::forAllDrawables(LLSpatialGroup::sg_vector_t& groups, void (*fun void LLPipeline::forAllVisibleDrawables(void (*func)(LLDrawable*)) { - forAllDrawables(mDrawableGroups, func); - forAllDrawables(mVisibleGroups, func); - forAllDrawables(mActiveGroups, func); + forAllDrawables(sCull->beginDrawableGroups(), sCull->endDrawableGroups(), func); + forAllDrawables(sCull->beginVisibleGroups(), sCull->endVisibleGroups(), func); } //function for creating scripted beacons @@ -1498,7 +1856,8 @@ void renderScriptedBeacons(LLDrawable* drawablep) if (gPipeline.sRenderHighlight) { S32 face_id; - for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++) + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) { gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); } @@ -1523,7 +1882,8 @@ void renderScriptedTouchBeacons(LLDrawable* drawablep) if (gPipeline.sRenderHighlight) { S32 face_id; - for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++) + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) { gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); } @@ -1547,7 +1907,8 @@ void renderPhysicalBeacons(LLDrawable* drawablep) if (gPipeline.sRenderHighlight) { S32 face_id; - for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++) + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) { gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); } @@ -1571,7 +1932,8 @@ void renderParticleBeacons(LLDrawable* drawablep) if (gPipeline.sRenderHighlight) { S32 face_id; - for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++) + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) { gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); } @@ -1579,73 +1941,61 @@ void renderParticleBeacons(LLDrawable* drawablep) } } -void LLPipeline::postSort(LLCamera& camera) +void renderSoundHighlights(LLDrawable* drawablep) { - LLMemType mt(LLMemType::MTYPE_PIPELINE); - LLFastTimer ftm(LLFastTimer::FTM_STATESORT_POSTSORT); - //reset render data sets - clearRenderMap(); - mAlphaGroups.clear(); - mAlphaGroupsPostWater.clear(); - - if (!gSavedSettings.getBOOL("RenderRippleWater") && hasRenderType(LLDrawPool::POOL_ALPHA)) - { //turn off clip plane for non-ripple water - toggleRenderType(LLDrawPool::POOL_ALPHA); - } - - F32 water_height = gAgent.getRegion()->getWaterHeight(); - BOOL above_water = gCamera->getOrigin().mV[2] > water_height ? TRUE : FALSE; - - //prepare occlusion geometry - if (sUseOcclusion) + // Look for attachments, objects, etc. + LLViewerObject *vobj = drawablep->getVObj(); + if (vobj && vobj->isAudioSource()) { - for (U32 i = 0; i < mObjectPartition.size(); i++) + if (gPipeline.sRenderHighlight) { - if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) + S32 face_id; + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) { - mObjectPartition[i]->buildOcclusion(); - } - } - -#if AGGRESSIVE_OCCLUSION - for (LLSpatialBridge::bridge_vector_t::iterator i = mVisibleBridge.begin(); i != mVisibleBridge.end(); ++i) - { - LLSpatialBridge* bridge = *i; - if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) - { - bridge->buildOcclusion(); + gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); } } -#endif } +} +void LLPipeline::postSort(LLCamera& camera) +{ + LLMemType mt(LLMemType::MTYPE_PIPELINE); + LLFastTimer ftm(LLFastTimer::FTM_STATESORT_POSTSORT); - if (!sSkipUpdate) + assertInitialized(); + + //rebuild drawable geometry + for (LLCullResult::sg_list_t::iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) { - //rebuild drawable geometry - for (LLSpatialGroup::sg_vector_t::iterator i = mDrawableGroups.begin(); i != mDrawableGroups.end(); ++i) + LLSpatialGroup* group = *i; + if (!sUseOcclusion || + !group->isState(LLSpatialGroup::OCCLUDED)) { - LLSpatialGroup* group = *i; group->rebuildGeom(); } } //build render map - for (LLSpatialGroup::sg_vector_t::iterator i = mVisibleGroups.begin(); i != mVisibleGroups.end(); ++i) + for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { LLSpatialGroup* group = *i; - if (!sSkipUpdate) + if (sUseOcclusion && + group->isState(LLSpatialGroup::OCCLUDED)) { - group->rebuildGeom(); + continue; } + + group->rebuildGeom(); + for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) { LLSpatialGroup::drawmap_elem_t& src_vec = j->second; - LLSpatialGroup::drawmap_elem_t& dest_vec = mRenderMap[j->first]; - - for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) + + for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) { - dest_vec.push_back(*k); + sCull->pushDrawInfo(j->first, *k); } } @@ -1653,95 +2003,47 @@ void LLPipeline::postSort(LLCamera& camera) if (alpha != group->mDrawMap.end()) { //store alpha groups for sorting + LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); if (!sSkipUpdate) { - group->updateDistance(camera); - } - - if (hasRenderType(LLDrawPool::POOL_ALPHA)) - { - BOOL above = group->mObjectBounds[0].mV[2] + group->mObjectBounds[1].mV[2] > water_height ? TRUE : FALSE; - BOOL below = group->mObjectBounds[0].mV[2] - group->mObjectBounds[1].mV[2] < water_height ? TRUE : FALSE; - - if (below == above_water || above == below) + if (bridge) { - mAlphaGroups.push_back(group); + LLCamera trans_camera = bridge->transformCamera(camera); + group->updateDistance(trans_camera); } - - if (above == above_water || below == above) + else { - mAlphaGroupsPostWater.push_back(group); + group->updateDistance(camera); } } - else + + if (hasRenderType(LLDrawPool::POOL_ALPHA)) { - mAlphaGroupsPostWater.push_back(group); + sCull->pushAlphaGroup(group); } } } - - //store active alpha groups - for (LLSpatialGroup::sg_vector_t::iterator i = mActiveGroups.begin(); i != mActiveGroups.end(); ++i) - { - LLSpatialGroup* group = *i; - if (!sSkipUpdate) - { - group->rebuildGeom(); - } - LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); - if (alpha != group->mDrawMap.end()) + { + //sort by texture or bump map + for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; ++i) { - LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); - LLCamera trans_camera = bridge->transformCamera(camera); - if (!sSkipUpdate) - { - group->updateDistance(trans_camera); - } - - if (hasRenderType(LLDrawPool::POOL_ALPHA)) + //if (!mRenderMap[i].empty()) { - LLSpatialGroup* bridge_group = bridge->getSpatialGroup(); - BOOL above = bridge_group->mObjectBounds[0].mV[2] + bridge_group->mObjectBounds[1].mV[2] > water_height ? TRUE : FALSE; - BOOL below = bridge_group->mObjectBounds[0].mV[2] - bridge_group->mObjectBounds[1].mV[2] < water_height ? TRUE : FALSE; - - - if (below == above_water || above == below) + if (i == LLRenderPass::PASS_BUMP) { - mAlphaGroups.push_back(group); + std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareBump()); } - - if (above == above_water || below == above) + else { - mAlphaGroupsPostWater.push_back(group); + std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareTexturePtrMatrix()); } } - else - { - mAlphaGroupsPostWater.push_back(group); - } } - } - //sort by texture or bump map - for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; ++i) - { - if (!mRenderMap[i].empty()) - { - if (i == LLRenderPass::PASS_BUMP) - { - std::sort(mRenderMap[i].begin(), mRenderMap[i].end(), LLDrawInfo::CompareBump()); - } - else - { - std::sort(mRenderMap[i].begin(), mRenderMap[i].end(), LLDrawInfo::CompareTexturePtr()); - } - } + std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater()); } - std::sort(mAlphaGroups.begin(), mAlphaGroups.end(), LLSpatialGroup::CompareDepthGreater()); - std::sort(mAlphaGroupsPostWater.begin(), mAlphaGroupsPostWater.end(), LLSpatialGroup::CompareDepthGreater()); - // only render if the flag is set. The flag is only set if the right key is pressed, we are in edit mode or the toggle is set in the menus if (sRenderProcessBeacons) { @@ -1771,7 +2073,7 @@ void LLPipeline::postSort(LLCamera& camera) // If god mode, also show audio cues if (sRenderSoundBeacons && gAudiop) { - // Update all of our audio sources, clean up dead ones. + // Walk all sound sources and render out beacons for them. Note, this isn't done in the ForAllVisibleDrawables function, because some are not visible. LLAudioEngine::source_map::iterator iter; for (iter = gAudiop->mAllSources.begin(); iter != gAudiop->mAllSources.end(); ++iter) { @@ -1785,6 +2087,8 @@ void LLPipeline::postSort(LLCamera& camera) gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); } } + // now deal with highlights for all those seeable sound sources + forAllVisibleDrawables(renderSoundHighlights); } } @@ -1815,7 +2119,7 @@ void LLPipeline::postSort(LLCamera& camera) } -static void render_hud_elements() +void render_hud_elements() { LLFastTimer t(LLFastTimer::FTM_RENDER_UI); gPipeline.disableLights(); @@ -1824,8 +2128,14 @@ static void render_hud_elements() LLGLDisable fog(GL_FOG); LLGLSUIDefault gls_ui; + + LLGLEnable stencil(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF); + glStencilMask(0xFFFFFFFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + gGL.start(); + if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() @@ -1857,11 +2167,15 @@ static void render_hud_elements() { LLHUDText::renderAllHUD(); } + gGL.stop(); } void LLPipeline::renderHighlights() { LLMemType mt(LLMemType::MTYPE_PIPELINE); + + assertInitialized(); + // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) // Render highlighted faces. LLColor4 color(1.f, 1.f, 1.f, 0.5f); @@ -1871,7 +2185,7 @@ void LLPipeline::renderHighlights() if ((LLShaderMgr::sVertexShaderLevel[LLShaderMgr::SHADER_INTERFACE] > 0)) { gHighlightProgram.bind(); - gHighlightProgram.vertexAttrib4f(LLShaderMgr::MATERIAL_COLOR,1,0,0,0.5f); + gHighlightProgram.vertexAttrib4f(LLShaderMgr::MATERIAL_COLOR,1,1,1,0.5f); } if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) @@ -1883,7 +2197,8 @@ void LLPipeline::renderHighlights() } mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); - for (U32 i = 0; i < mSelectedFaces.size(); i++) + U32 count = mSelectedFaces.size(); + for (U32 i = 0; i < count; i++) { LLFace *facep = mSelectedFaces[i]; if (!facep || facep->getDrawable()->isDead()) @@ -1900,7 +2215,12 @@ void LLPipeline::renderHighlights() { // Paint 'em red! color.setVec(1.f, 0.f, 0.f, 0.5f); - for (U32 i = 0; i < mHighlightFaces.size(); i++) + if ((LLShaderMgr::sVertexShaderLevel[LLShaderMgr::SHADER_INTERFACE] > 0)) + { + gHighlightProgram.vertexAttrib4f(LLShaderMgr::MATERIAL_COLOR,1,0,0,0.5f); + } + int count = mHighlightFaces.size(); + for (S32 i = 0; i < count; i++) { LLFace* facep = mHighlightFaces[i]; facep->renderSelected(LLViewerImage::sNullImagep, color); @@ -1917,11 +2237,26 @@ void LLPipeline::renderHighlights() } } -void LLPipeline::renderGeom(LLCamera& camera) +void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) { LLMemType mt(LLMemType::MTYPE_PIPELINE); LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY); - + + assertInitialized(); + + F64 saved_modelview[16]; + F64 saved_projection[16]; + + //HACK: preserve/restore matrices around HUD render + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + for (U32 i = 0; i < 16; i++) + { + saved_modelview[i] = gGLModelView[i]; + saved_projection[i] = gGLProjection[i]; + } + } + if (!mAlphaSizzleImagep) { mAlphaSizzleImagep = gImageList.getImage(LLUUID(gViewerArt.getString("alpha_sizzle.tga")), MIPMAP_TRUE, TRUE); @@ -1952,11 +2287,8 @@ void LLPipeline::renderGeom(LLCamera& camera) } } - { - //LLFastTimer ftm(LLFastTimer::FTM_TEMP6); - LLVertexBuffer::startRender(); - } - + LLVertexBuffer::startRender(); + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) { LLDrawPool *poolp = *iter; @@ -1966,6 +2298,14 @@ void LLPipeline::renderGeom(LLCamera& camera) } } + //by bao + //fake vertex buffer updating + //to guaranttee at least updating one VBO buffer every frame + //to walk around the bug caused by ATI card --> DEV-3855 + // + if(forceVBOUpdate) + gSky.mVOSkyp->updateDummyVertexBuffer() ; + gFrameStats.start(LLFrameStats::RENDER_GEOM); // Initialize lots of GL state to "safe" values @@ -1976,13 +2316,18 @@ void LLPipeline::renderGeom(LLCamera& camera) LLGLSPipeline gls_pipeline; LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); - // LLGLState normalize(GL_NORMALIZE, TRUE); - + // Toggle backface culling for debugging LLGLEnable cull_face(mBackfaceCull ? GL_CULL_FACE : 0); // Set fog - LLGLEnable fog_enable(hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG) ? GL_FOG : 0); + BOOL use_fog = hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG); + LLGLEnable fog_enable(use_fog && + !gPipeline.canUseWindLightShadersOnObjects() ? GL_FOG : 0); gSky.updateFog(camera.getFar()); + if (!use_fog) + { + sUnderWaterRender = FALSE; + } LLViewerImage::sDefaultImagep->bind(0); LLViewerImage::sDefaultImagep->setClamp(FALSE, FALSE); @@ -1993,13 +2338,10 @@ void LLPipeline::renderGeom(LLCamera& camera) // // stop_glerror(); - BOOL did_hud_elements = LLDrawPoolWater::sSkipScreenCopy; - BOOL occlude = sUseOcclusion; - + BOOL occlude = sUseOcclusion > 1; + U32 cur_type = 0; - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING)) { gObjectList.renderObjectsForSelect(camera); @@ -2008,6 +2350,8 @@ void LLPipeline::renderGeom(LLCamera& camera) { LLFastTimer t(LLFastTimer::FTM_POOLS); calcNearbyLights(camera); + setupHWLights(NULL); + pool_set_t::iterator iter1 = mPools.begin(); while ( iter1 != mPools.end() ) { @@ -2018,23 +2362,18 @@ void LLPipeline::renderGeom(LLCamera& camera) if (occlude && cur_type > LLDrawPool::POOL_AVATAR) { occlude = FALSE; + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); doOcclusion(camera); } - if (cur_type > LLDrawPool::POOL_ALPHA_POST_WATER && !did_hud_elements) - { - renderHighlights(); - // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) - render_hud_elements(); - did_hud_elements = TRUE; - } - pool_set_t::iterator iter2 = iter1; if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0) { LLFastTimer t(LLFastTimer::FTM_POOLRENDER); - setupHWLights(poolp); + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); for( S32 i = 0; i < poolp->getNumPasses(); i++ ) { @@ -2049,11 +2388,10 @@ void LLPipeline::renderGeom(LLCamera& camera) p->resetTrianglesDrawn(); p->render(i); - mTrianglesDrawn += p->getTrianglesDrawn(); } poolp->endRenderPass(i); #ifndef LL_RELEASE_FOR_DOWNLOAD -#if LL_DEBUG_GL +# if LL_DEBUG_GL GLint depth; glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); if (depth > 3) @@ -2063,7 +2401,7 @@ void LLPipeline::renderGeom(LLCamera& camera) LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); -#endif +# endif #endif } } @@ -2090,94 +2428,69 @@ void LLPipeline::renderGeom(LLCamera& camera) LLGLState::checkClientArrays(); #endif + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + if (occlude) { - doOcclusion(camera); occlude = FALSE; - } - - if (!did_hud_elements) - { - renderHighlights(); - render_hud_elements(); + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + doOcclusion(camera); } stop_glerror(); - - { - LLVertexBuffer::stopRender(); - } - + #ifndef LL_RELEASE_FOR_DOWNLOAD LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); #endif + if (!sReflectionRender) + { + renderHighlights(); + } + // Contains a list of the faces of objects that are physical or // have touch-handlers. mHighlightFaces.clear(); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + render_hud_elements(); - if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD) && - !LLDrawPoolWater::sSkipScreenCopy && - sRenderGlow && - gGLManager.mHasFramebufferObject) - { - const U32 glow_res = nhpo2(gSavedSettings.getS32("RenderGlowResolution")); - if (mGlowMap == 0) - { - glGenTextures(1, &mGlowMap); - glBindTexture(GL_TEXTURE_2D, mGlowMap); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glow_res, glow_res, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - } + LLVertexBuffer::stopRender(); + LLVertexBuffer::unbind(); + - if (mGlowBuffer == 0) + //HACK: preserve/restore matrices around HUD render + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + for (U32 i = 0; i < 16; i++) { - glGenTextures(1, &mGlowBuffer); - glBindTexture(GL_TEXTURE_2D, mGlowBuffer); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glow_res, glow_res, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + gGLModelView[i] = saved_modelview[i]; + gGLProjection[i] = saved_projection[i]; } - - bindScreenToTexture(); - renderBloom(mScreenTex, mGlowMap, mGlowBuffer, glow_res, LLVector2(0,0), mScreenScale); } + +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); +#endif } -void LLPipeline::processOcclusion(LLCamera& camera) +void LLPipeline::addTrianglesDrawn(S32 count) { - //process occlusion (readback) - if (sUseOcclusion) + assertInitialized(); + mTrianglesDrawn += count; + mBatchCount++; + mMaxBatchSize = llmax(mMaxBatchSize, count); + mMinBatchSize = llmin(mMinBatchSize, count); + + if (LLPipeline::sRenderFrameTest) { - for (U32 i = 0; i < mObjectPartition.size(); i++) - { - if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) - { - mObjectPartition[i]->processOcclusion(&camera); - } - } - -#if AGGRESSIVE_OCCLUSION - for (LLSpatialBridge::bridge_vector_t::iterator i = mOccludedBridge.begin(); i != mOccludedBridge.end(); ++i) - { - LLSpatialBridge* bridge = *i; - if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) - { - LLCamera trans = bridge->transformCamera(camera); - bridge->processOcclusion(&trans); - } - } -#endif - mOccludedBridge.clear(); + gViewerWindow->getWindow()->swapBuffers(); + ms_sleep(16); } } @@ -2185,24 +2498,41 @@ void LLPipeline::renderDebug() { LLMemType mt(LLMemType::MTYPE_PIPELINE); + assertInitialized(); + + gGL.start(); + // Disable all client state - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); + //glDisableClientState(GL_TEXTURE_COORD_ARRAY); + //glDisableClientState(GL_NORMAL_ARRAY); + //glDisableClientState(GL_COLOR_ARRAY); + + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); // Debug stuff. - for (U32 i = 0; i < mObjectPartition.size(); i++) + for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); + iter != gWorldp->getRegionList().end(); ++iter) { - if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { - mObjectPartition[i]->renderDebug(); + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + if (hasRenderType(part->mDrawableType)) + { + part->renderDebug(); + } + } } } - for (LLSpatialBridge::bridge_vector_t::iterator i = mVisibleBridge.begin(); i != mVisibleBridge.end(); ++i) + for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { LLSpatialBridge* bridge = *i; - if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) + if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType)) { glPushMatrix(); glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); @@ -2211,51 +2541,6 @@ void LLPipeline::renderDebug() } } - if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_LIGHT_TRACE) - { - LLGLSNoTexture no_texture; - - LLVector3 pos, pos1; - - for (LLDrawable::drawable_vector_t::iterator iter = mVisibleList.begin(); - iter != mVisibleList.end(); iter++) - { - LLDrawable *drawablep = *iter; - if (drawablep->isDead()) - { - continue; - } - for (LLDrawable::drawable_set_t::iterator iter = drawablep->mLightSet.begin(); - iter != drawablep->mLightSet.end(); iter++) - { - LLDrawable *targetp = *iter; - if (targetp->isDead() || !targetp->getVObj()->getNumTEs()) - { - continue; - } - else - { - if (targetp->getTextureEntry(0)) - { - if (drawablep->getVObj()->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) - { - glColor4f(0.f, 1.f, 0.f, 1.f); - gObjectList.addDebugBeacon(drawablep->getPositionAgent(), "TC"); - } - else - { - glColor4fv (targetp->getTextureEntry(0)->getColor().mV); - } - glBegin(GL_LINES); - glVertex3fv(targetp->getPositionAgent().mV); - glVertex3fv(drawablep->getPositionAgent().mV); - glEnd(); - } - } - } - } - } - if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) { // Debug composition layers @@ -2263,9 +2548,9 @@ void LLPipeline::renderDebug() LLGLSNoTexture gls_no_texture; - glBegin(GL_POINTS); if (gAgent.getRegion()) { + gGL.begin(GL_POINTS); // Draw the composition layer for the region that I'm in. for (x = 0; x <= 260; x++) { @@ -2273,29 +2558,40 @@ void LLPipeline::renderDebug() { if ((x > 255) || (y > 255)) { - glColor4f(1.f, 0.f, 0.f, 1.f); + gGL.color4f(1.f, 0.f, 0.f, 1.f); } else { - glColor4f(0.f, 0.f, 1.f, 1.f); + gGL.color4f(0.f, 0.f, 1.f, 1.f); } F32 z = gAgent.getRegion()->getCompositionXY((S32)x, (S32)y); z *= 5.f; z += 50.f; - glVertex3f(x, y, z); + gGL.vertex3f(x, y, z); } } + gGL.end(); } - glEnd(); } + gGL.stop(); } void LLPipeline::renderForSelect(std::set& objects) { - LLMemType mt(LLMemType::MTYPE_PIPELINE); - - LLVertexBuffer::startRender(); - + assertInitialized(); + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + gPipeline.resetDrawOrders(); + + for (std::set::iterator iter = objects.begin(); iter != objects.end(); ++iter) + { + stateSort((*iter)->mDrawable, *gCamera); + } + + LLMemType mt(LLMemType::MTYPE_PIPELINE); + + LLVertexBuffer::startRender(); + glMatrixMode(GL_MODELVIEW); LLGLSDefault gls_default; @@ -2319,7 +2615,10 @@ void LLPipeline::renderForSelect(std::set& objects) { LLFacePool* face_pool = (LLFacePool*) poolp; face_pool->renderForSelect(); - + + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + #ifndef LL_RELEASE_FOR_DOWNLOAD if (poolp->getType() != last_type) { @@ -2330,9 +2629,8 @@ void LLPipeline::renderForSelect(std::set& objects) } #endif } - } + } - LLGLEnable tex(GL_TEXTURE_2D); glEnableClientState(GL_TEXTURE_COORD_ARRAY); LLGLEnable alpha_test(GL_ALPHA_TEST); if (gPickTransparent) @@ -2387,17 +2685,22 @@ void LLPipeline::renderForSelect(std::set& objects) LLVOAvatar* avatarp = gAgent.getAvatarObject(); if (avatarp && sShowHUDAttachments) { - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + glh::matrix4f save_proj(glh_get_current_projection()); + glh::matrix4f save_model(glh_get_current_modelview()); + U32 viewport[4]; + + for (U32 i = 0; i < 4; i++) + { + viewport[i] = gGLViewport[i]; + } + setup_hud_matrices(TRUE); - LLViewerJointAttachment* attachmentp; - for (attachmentp = avatarp->mAttachmentPoints.getFirstData(); - attachmentp; - attachmentp = avatarp->mAttachmentPoints.getNextData()) + for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); + iter != avatarp->mAttachmentPoints.end(); ) { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachmentp = curiter->second; if (attachmentp->getIsHUDAttachment()) { LLViewerObject* objectp = attachmentp->getObject(); @@ -2436,15 +2739,27 @@ void LLPipeline::renderForSelect(std::set& objects) } glMatrixMode(GL_PROJECTION); - glPopMatrix(); + glLoadMatrixf(save_proj.m); + glh_set_current_projection(save_proj); + glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + glLoadMatrixf(save_model.m); + glh_set_current_modelview(save_model); + + + for (U32 i = 0; i < 4; i++) + { + gGLViewport[i] = viewport[i]; + } + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); } glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisableClientState( GL_TEXTURE_COORD_ARRAY ); LLVertexBuffer::stopRender(); + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } void LLPipeline::renderFaceForUVSelect(LLFace* facep) @@ -2455,6 +2770,9 @@ void LLPipeline::renderFaceForUVSelect(LLFace* facep) void LLPipeline::rebuildPools() { LLMemType mt(LLMemType::MTYPE_PIPELINE); + + assertInitialized(); + S32 max_count = mPools.size(); pool_set_t::iterator iter1 = mPools.upper_bound(mLastRebuildPool); while(max_count > 0 && mPools.size() > 0) // && num_rebuilds < MAX_REBUILDS) @@ -2492,6 +2810,9 @@ void LLPipeline::rebuildPools() void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) { LLMemType mt(LLMemType::MTYPE_PIPELINE); + + assertInitialized(); + switch( new_poolp->getType() ) { case LLDrawPool::POOL_SIMPLE: @@ -2506,6 +2827,18 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) } break; + case LLDrawPool::POOL_INVISIBLE: + if (mInvisiblePool) + { + llassert(0); + llwarns << "Ignoring duplicate simple pool." << llendl; + } + else + { + mInvisiblePool = (LLRenderPass*) new_poolp; + } + break; + case LLDrawPool::POOL_GLOW: if (mGlowPool) { @@ -2550,18 +2883,6 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) } break; - case LLDrawPool::POOL_ALPHA_POST_WATER: - if( mAlphaPoolPostWater ) - { - llassert(0); - llwarns << "LLPipeline::addPool(): Ignoring duplicate Alpha pool" << llendl; - } - else - { - mAlphaPoolPostWater = new_poolp; - } - break; - case LLDrawPool::POOL_AVATAR: break; // Do nothing @@ -2576,18 +2897,6 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) mSkyPool = new_poolp; } break; - - case LLDrawPool::POOL_STARS: - if( mStarsPool ) - { - llassert(0); - llwarns << "LLPipeline::addPool(): Ignoring duplicate Stars pool" << llendl; - } - else - { - mStarsPool = new_poolp; - } - break; case LLDrawPool::POOL_WATER: if( mWaterPool ) @@ -2613,6 +2922,18 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) } break; + case LLDrawPool::POOL_WL_SKY: + if( mWLSkyPool ) + { + llassert(0); + llwarns << "LLPipeline::addPool(): Ignoring duplicate WLSky Pool" << llendl; + } + else + { + mWLSkyPool = new_poolp; + } + break; + default: llassert(0); llwarns << "Invalid Pool Type in LLPipeline::addPool()" << llendl; @@ -2622,6 +2943,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) void LLPipeline::removePool( LLDrawPool* poolp ) { + assertInitialized(); removeFromQuickLookup(poolp); mPools.erase(poolp); delete poolp; @@ -2629,6 +2951,7 @@ void LLPipeline::removePool( LLDrawPool* poolp ) void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) { + assertInitialized(); LLMemType mt(LLMemType::MTYPE_PIPELINE); switch( poolp->getType() ) { @@ -2637,6 +2960,16 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) mSimplePool = NULL; break; + case LLDrawPool::POOL_INVISIBLE: + llassert(mInvisiblePool == poolp); + mInvisiblePool = NULL; + break; + + case LLDrawPool::POOL_WL_SKY: + llassert(mWLSkyPool == poolp); + mWLSkyPool = NULL; + break; + case LLDrawPool::POOL_GLOW: llassert(mGlowPool == poolp); mGlowPool = NULL; @@ -2674,11 +3007,6 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) mAlphaPool = NULL; break; - case LLDrawPool::POOL_ALPHA_POST_WATER: - llassert( poolp == mAlphaPoolPostWater ); - mAlphaPoolPostWater = NULL; - break; - case LLDrawPool::POOL_AVATAR: break; // Do nothing @@ -2687,11 +3015,6 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) mSkyPool = NULL; break; - case LLDrawPool::POOL_STARS: - llassert( poolp == mStarsPool ); - mStarsPool = NULL; - break; - case LLDrawPool::POOL_WATER: llassert( poolp == mWaterPool ); mWaterPool = NULL; @@ -2711,6 +3034,7 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) void LLPipeline::resetDrawOrders() { + assertInitialized(); // Iterate through all of the draw pools and rebuild them. for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) { @@ -2725,7 +3049,7 @@ void LLPipeline::resetDrawOrders() void LLPipeline::setupAvatarLights(BOOL for_edit) { - const LLColor4 black(0,0,0,1); + assertInitialized(); if (for_edit) { @@ -2740,8 +3064,8 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) mHWLightColors[1] = diffuse; glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, black.mV); + glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); + glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); glLightfv(GL_LIGHT1, GL_POSITION, light_pos.mV); glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); @@ -2756,7 +3080,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f); backlight_pos.normVec(); - LLColor4 light_diffuse = mSunDiffuse * mSunShadowFactor; + LLColor4 light_diffuse = mSunDiffuse; LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f); F32 max_component = 0.001f; for (S32 i = 0; i < 3; i++) @@ -2780,8 +3104,8 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) mHWLightColors[1] = backlight_diffuse; glLightfv(GL_LIGHT1, GL_POSITION, backlight_pos.mV); // this is just sun/moon direction glLightfv(GL_LIGHT1, GL_DIFFUSE, backlight_diffuse.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, black.mV); + glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); + glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); @@ -2790,10 +3114,10 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) } else { - mHWLightColors[1] = black; - glLightfv(GL_LIGHT1, GL_DIFFUSE, black.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, black.mV); + mHWLightColors[1] = LLColor4::black; + glLightfv(GL_LIGHT1, GL_DIFFUSE, LLColor4::black.mV); + glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); + glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); } } @@ -2829,13 +3153,15 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_ void LLPipeline::calcNearbyLights(LLCamera& camera) { + assertInitialized(); + if (mLightingDetail >= 1) { // mNearbyLight (and all light_set_t's) are sorted such that // begin() == the closest light and rbegin() == the farthest light const S32 MAX_LOCAL_LIGHTS = 6; // LLVector3 cam_pos = gAgent.getCameraPositionAgent(); - LLVector3 cam_pos = LLPipeline::sSkipUpdate || LLViewerJoystick::sOverrideCamera ? + LLVector3 cam_pos = LLViewerJoystick::sOverrideCamera ? camera.getOrigin() : gAgent.getPositionAgent(); @@ -2933,7 +3259,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) void LLPipeline::setupHWLights(LLDrawPool* pool) { - const LLColor4 black(0,0,0,1); + assertInitialized(); // Ambient LLColor4 ambient = gSky.getTotalAmbientColor(); @@ -2941,7 +3267,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) // Light 0 = Sun or Moon (All objects) { - mSunShadowFactor = 1.f; // no shadowing by defailt if (gSky.getSunDirection().mV[2] >= NIGHTTIME_ELEVATION_COS) { mSunDir.setVec(gSky.getSunDirection()); @@ -2950,7 +3275,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) else { mSunDir.setVec(gSky.getMoonDirection()); - mSunDiffuse.setVec(gSky.getMoonDiffuseColor() * 1.5f); + mSunDiffuse.setVec(gSky.getMoonDiffuseColor()); } F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]); @@ -2961,12 +3286,12 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) mSunDiffuse.clamp(); LLVector4 light_pos(mSunDir, 0.0f); - LLColor4 light_diffuse = mSunDiffuse * mSunShadowFactor; + LLColor4 light_diffuse = mSunDiffuse; mHWLightColors[0] = light_diffuse; glLightfv(GL_LIGHT0, GL_POSITION, light_pos.mV); // this is just sun/moon direction glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse.mV); - glLightfv(GL_LIGHT0, GL_AMBIENT, black.mV); - glLightfv(GL_LIGHT0, GL_SPECULAR, black.mV); + glLightfv(GL_LIGHT0, GL_AMBIENT, LLColor4::black.mV); + glLightfv(GL_LIGHT0, GL_SPECULAR, LLColor4::black.mV); glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f); glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0f); glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f); @@ -3002,7 +3327,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) LLColor4 light_color = light->getLightColor(); light_color.mV[3] = 0.0f; - F32 fade = LLPipeline::sSkipUpdate ? 1.f : iter->fade; + F32 fade = iter->fade; if (fade < LIGHT_FADE_TIME) { // fade in/out light @@ -3043,8 +3368,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) S32 gllight = GL_LIGHT0+cur_light; glLightfv(gllight, GL_POSITION, light_pos_gl.mV); glLightfv(gllight, GL_DIFFUSE, light_color.mV); - glLightfv(gllight, GL_AMBIENT, black.mV); - glLightfv(gllight, GL_SPECULAR, black.mV); + glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); + glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); glLightf (gllight, GL_LINEAR_ATTENUATION, atten); glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad); @@ -3059,11 +3384,41 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) } for ( ; cur_light < 8 ; cur_light++) { - mHWLightColors[cur_light] = black; + mHWLightColors[cur_light] = LLColor4::black; S32 gllight = GL_LIGHT0+cur_light; - glLightfv(gllight, GL_DIFFUSE, black.mV); - glLightfv(gllight, GL_AMBIENT, black.mV); - glLightfv(gllight, GL_SPECULAR, black.mV); + glLightfv(gllight, GL_DIFFUSE, LLColor4::black.mV); + glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); + glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); + } + + if (gAgent.getAvatarObject() && + gAgent.getAvatarObject()->mSpecialRenderMode == 3) + { + LLColor4 light_color = LLColor4::white; + light_color.mV[3] = 0.0f; + + LLVector3 light_pos(gCamera->getOrigin()); + LLVector4 light_pos_gl(light_pos, 1.0f); + + F32 light_radius = 16.f; + F32 atten, quad; + + { + F32 x = 3.f; + atten = x / (light_radius); // % of brightness at radius + quad = 0.0f; + } + //mHWLightColors[cur_light] = light_color; + S32 gllight = GL_LIGHT2; + glLightfv(gllight, GL_POSITION, light_pos_gl.mV); + glLightfv(gllight, GL_DIFFUSE, light_color.mV); + glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); + glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); + glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); + glLightf (gllight, GL_LINEAR_ATTENUATION, atten); + glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad); + glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); + glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); } // Init GL state @@ -3075,8 +3430,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) mLightMask = 0; } -void LLPipeline::enableLights(U32 mask, F32 shadow_factor) +void LLPipeline::enableLights(U32 mask) { + assertInitialized(); if (mLightingDetail == 0) { mask &= 0xf003; // sun and backlight only (and fullbright bit) @@ -3113,8 +3469,9 @@ void LLPipeline::enableLights(U32 mask, F32 shadow_factor) } } -void LLPipeline::enableLightsStatic(F32 shadow_factor) +void LLPipeline::enableLightsStatic() { + assertInitialized(); U32 mask = 0x01; // Sun if (mLightingDetail >= 2) { @@ -3125,39 +3482,55 @@ void LLPipeline::enableLightsStatic(F32 shadow_factor) { mask |= 0xff & (~2); // Hardware local lights } - enableLights(mask, shadow_factor); + enableLights(mask); } -void LLPipeline::enableLightsDynamic(F32 shadow_factor) +void LLPipeline::enableLightsDynamic() { + assertInitialized(); U32 mask = 0xff & (~2); // Local lights - enableLights(mask, shadow_factor); + enableLights(mask); if (mLightingDetail >= 2) { glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default } + + LLVOAvatar* avatarp = gAgent.getAvatarObject(); + + if (avatarp && getLightingDetail() <= 0) + { + if (avatarp->mSpecialRenderMode == 0) // normal + { + gPipeline.enableLightsAvatar(); + } + else if (avatarp->mSpecialRenderMode >= 1) // anim preview + { + gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f)); + } + } } -void LLPipeline::enableLightsAvatar(F32 shadow_factor) +void LLPipeline::enableLightsAvatar() { U32 mask = 0xff; // All lights setupAvatarLights(FALSE); - enableLights(mask, shadow_factor); + enableLights(mask); } void LLPipeline::enableLightsAvatarEdit(const LLColor4& color) { U32 mask = 0x2002; // Avatar backlight only, set ambient setupAvatarLights(TRUE); - enableLights(mask, 1.0f); + enableLights(mask); glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); } void LLPipeline::enableLightsFullbright(const LLColor4& color) { + assertInitialized(); U32 mask = 0x1000; // Non-0 mask, set ambient - enableLights(mask, 1.f); + enableLights(mask); glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); if (mLightingDetail >= 2) @@ -3168,19 +3541,10 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color) void LLPipeline::disableLights() { - enableLights(0, 0.f); // no lighting (full bright) + enableLights(0); // no lighting (full bright) glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default } -// Call *after*s etting up lights -void LLPipeline::setAmbient(const LLColor4& ambient) -{ - mLightMask |= 0x4000; // tweak mask so that ambient will get reset - LLColor4 amb = ambient + gSky.getTotalAmbientColor(); - amb.clamp(); - glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb.mV); -} - //============================================================================ class LLMenuItemGL; @@ -3188,55 +3552,10 @@ class LLInvFVBridge; struct cat_folder_pair; class LLVOBranch; class LLVOLeaf; -class Foo; - -void scale_stamp(const F32 x, const F32 y, const F32 xs, const F32 ys) -{ - stamp(0.25f + 0.5f*x, - 0.5f + 0.45f*y, - 0.5f*xs, - 0.45f*ys); -} - -void drawBars(const F32 begin, const F32 end, const F32 height = 1.f) -{ - if (begin >= 0 && end <=1) - { - F32 lines = 40.0f; - S32 ibegin = (S32)(begin * lines); - S32 iend = (S32)(end * lines); - F32 fbegin = begin * lines - ibegin; - F32 fend = end * lines - iend; - - F32 line_height = height/lines; - - if (iend == ibegin) - { - scale_stamp(fbegin, (F32)ibegin/lines,fend-fbegin, line_height); - } - else - { - // Beginning row - scale_stamp(fbegin, (F32)ibegin/lines, 1.0f-fbegin, line_height); - - // End row - scale_stamp(0.0, (F32)iend/lines, fend, line_height); - - // Middle rows - for (S32 l = (ibegin+1); l < iend; l++) - { - scale_stamp(0.0f, (F32)l/lines, 1.0f, line_height); - } - } - } -} void LLPipeline::findReferences(LLDrawable *drawablep) { - if (std::find(mVisibleList.begin(), mVisibleList.end(), drawablep) != mVisibleList.end()) - { - llinfos << "In mVisibleList" << llendl; - } + assertInitialized(); if (mLights.find(drawablep) != mLights.end()) { llinfos << "In mLights" << llendl; @@ -3278,13 +3597,16 @@ void LLPipeline::findReferences(LLDrawable *drawablep) BOOL LLPipeline::verify() { - BOOL ok = TRUE; - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + BOOL ok = assertInitialized(); + if (ok) { - LLDrawPool *poolp = *iter; - if (!poolp->verify()) + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) { - ok = FALSE; + LLDrawPool *poolp = *iter; + if (!poolp->verify()) + { + ok = FALSE; + } } } @@ -3396,7 +3718,7 @@ bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light) { - if (drawablep) + if (drawablep && assertInitialized()) { if (is_light) { @@ -3408,12 +3730,12 @@ void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light) drawablep->clearState(LLDrawable::LIGHT); mLights.erase(drawablep); } - markRelight(drawablep); } } void LLPipeline::setActive(LLDrawable *drawablep, BOOL active) { + assertInitialized(); if (active) { mActiveQ.insert(drawablep); @@ -3634,7 +3956,22 @@ BOOL LLPipeline::getProcessBeacons(void* data) LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision) { - LLDrawable* drawable = mObjectPartition[PARTITION_VOLUME]->pickDrawable(start, end, collision); + LLDrawable* drawable = NULL; + + for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); + iter != gWorldp->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME); + if (part) + { + LLDrawable* hit = part->pickDrawable(start, end, collision); + if (hit) + { + drawable = hit; + } + } + } return drawable ? drawable->getVObj().get() : NULL; } @@ -3642,31 +3979,23 @@ LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj) { if (vobj) { - return getSpatialPartition(vobj->getPartitionType()); + LLViewerRegion* region = vobj->getRegion(); + if (region) + { + return region->getSpatialPartition(vobj->getPartitionType()); + } } return NULL; } -LLSpatialPartition* LLPipeline::getSpatialPartition(U32 type) -{ - if (type < mObjectPartition.size()) - { - return mObjectPartition[type]; - } - return NULL; -} -void LLPipeline::clearRenderMap() +void LLPipeline::resetVertexBuffers(LLDrawable* drawable) { - for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) + if (!drawable || drawable->isDead()) { - mRenderMap[i].clear(); + return; } -} - -void LLPipeline::resetVertexBuffers(LLDrawable* drawable) -{ if (!drawable) { return; @@ -3682,36 +4011,63 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable) void LLPipeline::resetVertexBuffers() { - for (U32 i = 0; i < mObjectPartition.size(); ++i) + sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); + + if (gWorldp) { - if (mObjectPartition[i]) + for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); + iter != gWorldp->getRegionList().end(); ++iter) { - mObjectPartition[i]->resetVertexBuffers(); + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + part->resetVertexBuffers(); + } + } } } resetDrawOrders(); - if (gSky.mVOSkyp.notNull()) + gSky.resetVertexBuffers(); + + if (LLVertexBuffer::sGLCount > 0) { - resetVertexBuffers(gSky.mVOSkyp->mDrawable); - resetVertexBuffers(gSky.mVOGroundp->mDrawable); - resetVertexBuffers(gSky.mVOStarsp->mDrawable); - markRebuild(gSky.mVOSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); - markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); - markRebuild(gSky.mVOStarsp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); + LLVertexBuffer::cleanupClass(); } + //delete all name pool caches + LLGLNamePool::cleanupPools(); + if (LLVertexBuffer::sGLCount > 0) { - LLVertexBuffer::cleanupClass(); + llwarns << "VBO wipe failed." << llendl; + } + + if (!LLVertexBuffer::sStreamIBOPool.mNameList.empty() || + !LLVertexBuffer::sStreamVBOPool.mNameList.empty() || + !LLVertexBuffer::sDynamicIBOPool.mNameList.empty() || + !LLVertexBuffer::sDynamicVBOPool.mNameList.empty()) + { + llwarns << "VBO name pool cleanup failed." << llendl; } + + LLVertexBuffer::unbind(); + + LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); } void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture) { - mSimplePool->renderStatic(type, mask, texture); - mSimplePool->renderActive(type, mask, texture); + assertInitialized(); + gGLLastMatrix = NULL; + glLoadMatrixd(gGLLastModelView); + mSimplePool->renderGroups(type, mask, texture); + gGLLastMatrix = NULL; + glLoadMatrixd(gGLLastModelView); } void LLPipeline::setUseVBO(BOOL use_vbo) @@ -3759,26 +4115,42 @@ void apply_cube_face_rotation(U32 face) break; } } -void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, GLsizei res) +void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam) { +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); +#endif + + assertInitialized(); + //render dynamic cube map U32 type_mask = gPipeline.getRenderTypeMask(); - BOOL use_occlusion = LLPipeline::sUseOcclusion; - LLPipeline::sUseOcclusion = FALSE; + S32 use_occlusion = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = 0; LLPipeline::sSkipUpdate = TRUE; - static GLuint blur_tex = 0; - if (!blur_tex) - { - glGenTextures(1, &blur_tex); - } + U32 res = REFLECTION_MAP_RES; - BOOL reattach = FALSE; - if (mCubeFrameBuffer == 0) - { - glGenFramebuffersEXT(1, &mCubeFrameBuffer); - glGenRenderbuffersEXT(1, &mCubeDepth); - reattach = TRUE; + LLPipeline::sReflectionRender = TRUE; + + cube_map->bind(); + GLint width; + glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_TEXTURE_WIDTH, &width); + if (width != res) + { + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + for (U32 i = 0; i < 6; i++) + { + glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); + } } + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0); + cube_map->disable(); BOOL toggle_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); if (toggle_ui) @@ -3788,10 +4160,9 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, U32 cube_mask = (1 << LLPipeline::RENDER_TYPE_SIMPLE) | (1 << LLPipeline::RENDER_TYPE_WATER) | - (1 << LLPipeline::RENDER_TYPE_BUMP) | + //(1 << LLPipeline::RENDER_TYPE_BUMP) | (1 << LLPipeline::RENDER_TYPE_ALPHA) | (1 << LLPipeline::RENDER_TYPE_TREE) | - (1 << LLDrawPool::POOL_ALPHA_POST_WATER) | //(1 << LLPipeline::RENDER_TYPE_PARTICLES) | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | //(1 << LLPipeline::RENDER_TYPE_STARS) | @@ -3801,9 +4172,11 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, (1 << LLPipeline::RENDER_TYPE_VOLUME) | (1 << LLPipeline::RENDER_TYPE_TERRAIN) | (1 << LLPipeline::RENDER_TYPE_SKY) | + (1 << LLPipeline::RENDER_TYPE_WL_SKY) | (1 << LLPipeline::RENDER_TYPE_GROUND); LLDrawPoolWater::sSkipScreenCopy = TRUE; + LLPipeline::sSkipUpdate = TRUE; cube_mask = cube_mask & type_mask; gPipeline.setRenderTypeMask(cube_mask); @@ -3816,57 +4189,23 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, glClearColor(0,0,0,0); - U32 cube_face[] = - { - GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, - GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, - GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, - GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, - }; - LLVector3 origin = cube_cam.getOrigin(); gPipeline.calcNearbyLights(cube_cam); - cube_map->bind(); - for (S32 i = 0; i < 6; i++) - { - GLint res_x, res_y; - glGetTexLevelParameteriv(cube_face[i], 0, GL_TEXTURE_WIDTH, &res_x); - glGetTexLevelParameteriv(cube_face[i], 0, GL_TEXTURE_HEIGHT, &res_y); - - if (res_x != res || res_y != res) - { - glTexImage2D(cube_face[i],0,GL_RGBA,res,res,0,GL_RGBA,GL_FLOAT,NULL); - reattach = TRUE; - } - } - cube_map->disable(); - - if (reattach) - { - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mCubeDepth); - GLint res_x, res_y; - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &res_x); - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_HEIGHT_EXT, &res_y); - - if (res_x != res || res_y != res) - { - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT24,res,res); - } - - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - } + stop_glerror(); + LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, mCubeDepth); + stop_glerror(); for (S32 i = 0; i < 6; i++) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - cube_face[i], cube_map->getGLName(), 0); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, mCubeDepth); + gl_cube_face[i], cube_map->getGLName(), 0); + validate_framebuffer_object(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90.f, 1.f, 0.1f, 1024.f); @@ -3879,23 +4218,29 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, cube_cam.setOrigin(origin); LLViewerCamera::updateFrustumPlanes(cube_cam); cube_cam.setOrigin(gCamera->getOrigin()); - gPipeline.updateCull(cube_cam); - gPipeline.stateSort(cube_cam); + static LLCullResult result; + gPipeline.updateCull(cube_cam, result); + gPipeline.stateSort(cube_cam, result); + glClearColor(0,0,0,0); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); + stop_glerror(); gPipeline.renderGeom(cube_cam); } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); cube_cam.setOrigin(origin); - gPipeline.resetDrawOrders(); gShinyOrigin.setVec(cube_cam.getOrigin(), cube_cam.getFar()*2.f); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); + gViewerWindow->setupViewport(); + gPipeline.setRenderTypeMask(type_mask); LLPipeline::sUseOcclusion = use_occlusion; LLPipeline::sSkipUpdate = FALSE; @@ -3905,12 +4250,21 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, gPipeline.toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); } LLDrawPoolWater::sSkipScreenCopy = FALSE; + LLPipeline::sSkipUpdate = FALSE; + LLPipeline::sReflectionRender = FALSE; + +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); +#endif + } //send cube map vertices and texture coordinates void render_cube_map() { - U32 idx[36]; + U16 idx[36]; idx[0] = 1; idx[1] = 0; idx[2] = 2; //front idx[3] = 3; idx[4] = 2; idx[5] = 0; @@ -3943,18 +4297,54 @@ void render_cube_map() vert[6] = r.scaledVec(LLVector3(-1,-1,-1)); // 6 - right bottom back vert[7] = r.scaledVec(LLVector3(1,-1,-1)); // 7 -left bottom back - glBegin(GL_TRIANGLES); - for (U32 i = 0; i < 36; i++) - { - glTexCoord3fv(vert[idx[i]].mV); - glVertex3fv(vert[idx[i]].mV); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(3, GL_FLOAT, 0, vert); + glVertexPointer(3, GL_FLOAT, 0, vert); + + glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, (GLushort*) idx); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +void validate_framebuffer_object() +{ + GLenum status; + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + switch(status) + { + case GL_FRAMEBUFFER_COMPLETE_EXT: + //framebuffer OK, no error. + break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + // frame buffer not OK: probably means unsupported depth buffer format + llerrs << "Framebuffer Incomplete Dimensions." << llendl; + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + // frame buffer not OK: probably means unsupported depth buffer format + llerrs << "Framebuffer Incomplete Attachment." << llendl; + break; + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + /* choose different formats */ + llerrs << "Framebuffer unsupported." << llendl; + break; + default: + llerrs << "Unknown framebuffer status." << llendl; + break; } - glEnd(); } -void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 res) +void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out) { - LLGLEnable cube(GL_TEXTURE_CUBE_MAP_ARB); +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); +#endif + + assertInitialized(); + + U32 res = (U32) gSavedSettings.getS32("RenderReflectionRes"); + enableLightsFullbright(LLColor4::white); LLGLDepthTest depth(GL_FALSE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glMatrixMode(GL_PROJECTION); @@ -3964,27 +4354,33 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 glMatrixMode(GL_MODELVIEW); glPushMatrix(); + cube_out->enableTexture(0); + cube_out->bind(); + GLint width; + glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_TEXTURE_WIDTH, &width); + if (width != res) + { + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + for (U32 i = 0; i < 6; i++) + { + glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); + } + } + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0); + glViewport(0, 0, res, res); LLGLEnable blend(GL_BLEND); S32 kernel = 2; F32 step = 90.f/res; - F32 alpha = 1.f/((kernel*2)+1); - - glColor4f(alpha,alpha,alpha,alpha*1.25f); - - S32 x = 0; - - U32 cube_face[] = - { - GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, - GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, - GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, - GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, - }; + F32 alpha = 1.f / ((kernel*2)+1); + gGL.color4f(alpha,alpha,alpha,alpha*1.25f); + LLVector3 axis[] = { LLVector3(1,0,0), @@ -3992,117 +4388,121 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 LLVector3(0,0,1) }; - - glBlendFunc(GL_ONE, GL_ONE); + stop_glerror(); + glViewport(0,0,res, res); + gGL.blendFunc(GL_ONE, GL_ONE); + cube_in->enableTexture(0); //3-axis blur for (U32 j = 0; j < 3; j++) { - glViewport(0,0,res, res*6); - glClear(GL_COLOR_BUFFER_BIT); + stop_glerror(); + if (j == 0) { cube_in->bind(); } + else + { + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mBlurCubeTexture[j-1]); + } + + stop_glerror(); + + LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mBlurCubeBuffer[j]); + stop_glerror(); for (U32 i = 0; i < 6; i++) { - glViewport(0,i*res, res, res); + stop_glerror(); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + gl_cube_face[i], + j < 2 ? mBlurCubeTexture[j] : cube_out->getGLName(), 0); + validate_framebuffer_object(); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); apply_cube_face_rotation(i); - for (x = -kernel; x <= kernel; ++x) + for (S32 x = -kernel; x <= kernel; ++x) { glPushMatrix(); glRotatef(x*step, axis[j].mV[0], axis[j].mV[1], axis[j].mV[2]); render_cube_map(); glPopMatrix(); } + stop_glerror(); } - - //readback - if (j == 0) - { - cube_out->bind(); - } - for (U32 i = 0; i < 6; i++) - { - glCopyTexImage2D(cube_face[i], 0, GL_RGBA, 0, i*res, res, res, 0); - } } - - glMatrixMode(GL_PROJECTION); + + stop_glerror(); + + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); + glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glClear(GL_COLOR_BUFFER_BIT); + cube_in->disableTexture(); + gViewerWindow->setupViewport(); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); +#endif } void LLPipeline::bindScreenToTexture() { - LLGLEnable gl_texture_2d(GL_TEXTURE_2D); - - GLint* viewport = (GLint*) gGLViewport; - GLuint resX = nhpo2(viewport[2]); - GLuint resY = nhpo2(viewport[3]); + +} - if (mScreenTex == 0) +void LLPipeline::renderBloom(BOOL for_snapshot) +{ + if (!(gPipeline.canUseVertexShaders() && + sRenderGlow && + gGLManager.mHasFramebufferObject)) { - glGenTextures(1, &mScreenTex); - glBindTexture(GL_TEXTURE_2D, mScreenTex); - - gImageList.updateMaxResidentTexMem(-1, resX*resY*3); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, resX, resY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + return; } - glBindTexture(GL_TEXTURE_2D, mScreenTex); - GLint cResX; - GLint cResY; - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &cResX); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &cResY); +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); +#endif + + assertInitialized(); - if (cResX != (GLint)resX || cResY != (GLint)resY) + if (gUseWireframe) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, resX, resY, 0, GL_RGB, GL_FLOAT, NULL); - gImageList.updateMaxResidentTexMem(-1, resX*resY*3); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, viewport[0], viewport[1], 0, 0, viewport[2], viewport[3]); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); - - mScreenScale.mV[0] = (float) viewport[2]/resX; - mScreenScale.mV[1] = (float) viewport[3]/resY; - - LLImageGL::sBoundTextureMemory += resX * resY * 3; -} + LLVector2 tc1(0,0); + LLVector2 tc2((F32) gViewerWindow->getWindowDisplayWidth(), + (F32) gViewerWindow->getWindowDisplayHeight()); -void LLPipeline::renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res, LLVector2 tc1, LLVector2 tc2) -{ - gGlowProgram.bind(); + if (res_mod > 1) + { + tc2 /= (F32) res_mod; + } - LLGLEnable tex(GL_TEXTURE_2D); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM); + gGL.start(); LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); LLGLDisable cull(GL_CULL_FACE); - - if (mFramebuffer[0] == 0) - { - glGenFramebuffersEXT(2, mFramebuffer); - } - - GLint viewport[4]; - glGetIntegerv(GL_VIEWPORT, viewport); - glViewport(0,0,res,res); + + enableLightsFullbright(LLColor4(1,1,1,1)); glMatrixMode(GL_PROJECTION); glPushMatrix(); @@ -4111,82 +4511,769 @@ void LLPipeline::renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res, glPushMatrix(); glLoadIdentity(); - glBindTexture(GL_TEXTURE_2D, source); - - S32 kernel = gSavedSettings.getS32("RenderGlowSize")*2; - LLGLDisable test(GL_ALPHA_TEST); - F32 delta = 1.f/(res*gSavedSettings.getF32("RenderGlowStrength")); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glClearColor(0,0,0,0); + + if (for_snapshot) + { + mGlow[1].bindTexture(); + { + //LLGLEnable stencil(GL_STENCIL_TEST); + //glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); + //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + //LLGLDisable blend(GL_BLEND); + LLGLEnable blend(GL_BLEND); + gGL.blendFunc(GL_ONE, GL_ONE); + tc2.setVec(1,1); + gGL.begin(GL_TRIANGLE_STRIP); + gGL.color4f(1,1,1,1); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,1); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(1,-1); + + gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); + gGL.vertex2f(1,1); + gGL.end(); - for (S32 i = 0; i < kernel; i++) + gGL.flush(); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + gGL.stop(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + return; + } + { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFramebuffer[i%2]); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, - i%2 == 0 ? buffer : dest, 0); + { + LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO); + mGlow[2].bindTarget(); + mGlow[2].clear(); + } + + gGlowExtractProgram.bind(); + F32 minLum = llclamp(gSavedSettings.getF32("RenderGlowMinLuminance"), 0.0f, 1.0f); + F32 maxAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha"); + F32 warmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount"); + LLVector3 lumWeights = gSavedSettings.getVector3("RenderGlowLumWeights"); + LLVector3 warmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights"); + gGlowExtractProgram.uniform1f("minLuminance", minLum); + gGlowExtractProgram.uniform1f("maxExtractAlpha", maxAlpha); + gGlowExtractProgram.uniform3f("lumWeights", lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]); + gGlowExtractProgram.uniform3f("warmthWeights", warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]); + gGlowExtractProgram.uniform1f("warmthAmount", warmthAmount); + LLGLEnable blend_on(GL_BLEND); + LLGLEnable test(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.f); + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE); + LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); + + glDisable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_RECTANGLE_ARB); + mScreen.bindTexture(); + + gGL.color4f(1,1,1,1); + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + gGL.begin(GL_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,1); - glBindTexture(GL_TEXTURE_2D, i == 0 ? source : - i%2==0 ? dest : - buffer); + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(1,-1); - glUniform1fARB(gGlowProgram.mUniform[LLShaderMgr::GLOW_DELTA],delta); + gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); + gGL.vertex2f(1,1); + gGL.end(); + + glEnable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_RECTANGLE_ARB); + + mGlow[2].flush(); + } + + tc1.setVec(0,0); + tc2.setVec(1,1); + - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(tc1.mV[0], tc1.mV[1]); - glVertex2f(-1,-1); + + // power of two between 1 and 1024 + U32 glowResPow = gSavedSettings.getS32("RenderGlowResolutionPow"); + const U32 glow_res = llmax(1, + llmin(1024, 1 << glowResPow)); + + S32 kernel = gSavedSettings.getS32("RenderGlowIterations")*2; + F32 delta = gSavedSettings.getF32("RenderGlowWidth") / glow_res; + // Use half the glow width if we have the res set to less than 9 so that it looks + // almost the same in either case. + if (glowResPow < 9) + { + delta *= 0.5f; + } + F32 strength = gSavedSettings.getF32("RenderGlowStrength"); + + gGlowProgram.bind(); + gGlowProgram.uniform1f("glowStrength", strength); + + for (S32 i = 0; i < kernel; i++) + { + LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); + { + LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO); + mGlow[i%2].bindTarget(); + mGlow[i%2].clear(); + } + + if (i == 0) + { + mGlow[2].bindTexture(); + } + else + { + mGlow[(i-1)%2].bindTexture(); + } + + if (i%2 == 0) + { + gGlowProgram.uniform2f("glowDelta", delta, 0); + } + else + { + gGlowProgram.uniform2f("glowDelta", 0, delta); + } + + gGL.begin(GL_TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); - glTexCoord2f(tc1.mV[0], tc2.mV[1]); - glVertex2f(-1,1); + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,1); - glTexCoord2f(tc2.mV[0], tc1.mV[1]); - glVertex2f(1,-1); + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(1,-1); - glTexCoord2f(tc2.mV[0], tc2.mV[1]); - glVertex2f(1,1); - glEnd(); - - tc1.setVec(0,0); - tc2.setVec(1,1); + gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); + gGL.vertex2f(1,1); + gGL.end(); + mGlow[i%2].flush(); } - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); gGlowProgram.unbind(); - glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + if (LLRenderTarget::sUseFBO) + { + LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } + + gViewerWindow->setupViewport(); - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_GLOW)) + /*mGlow[1].bindTexture(); { - glClear(GL_COLOR_BUFFER_BIT); + LLGLEnable stencil(GL_STENCIL_TEST); + glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + LLGLDisable blend(GL_BLEND); + + gGL.begin(GL_TRIANGLE_STRIP); + gGL.color4f(1,1,1,1); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,1); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(1,-1); + + gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); + gGL.vertex2f(1,1); + gGL.end(); + + gGL.flush(); } - glBindTexture(GL_TEXTURE_2D, dest); + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_GLOW)) { + tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(), + (F32) gViewerWindow->getWindowDisplayHeight()); + + if (res_mod > 1) + { + tc2 /= (F32) res_mod; + } + LLGLEnable blend(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + gGL.blendFunc(GL_ONE, GL_ONE); + + glDisable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_RECTANGLE_ARB); + mScreen.bindTexture(); + + gGL.begin(GL_TRIANGLE_STRIP); + gGL.color4f(1,1,1,1); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,1); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(1,-1); + + gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); + gGL.vertex2f(1,1); + gGL.end(); + + gGL.flush(); + + glEnable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_RECTANGLE_ARB); + + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + }*/ + gGL.stop(); + + { + LLVertexBuffer::unbind(); - glBegin(GL_TRIANGLE_STRIP); - glColor4f(1,1,1,1); - glTexCoord2f(tc1.mV[0], tc1.mV[1]); - glVertex2f(-1,-1); + F32 uv0[] = + { + tc1.mV[0], tc1.mV[1], + tc1.mV[0], tc2.mV[1], + tc2.mV[0], tc1.mV[1], + tc2.mV[0], tc2.mV[1] + }; + + tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(), + (F32) gViewerWindow->getWindowDisplayHeight()); + + if (res_mod > 1) + { + tc2 /= (F32) res_mod; + } + + F32 uv1[] = + { + tc1.mV[0], tc1.mV[1], + tc1.mV[0], tc2.mV[1], + tc2.mV[0], tc1.mV[1], + tc2.mV[0], tc2.mV[1] + }; + + F32 v[] = + { + -1,-1, + -1,1, + 1,-1, + 1,1 + }; + + LLGLDisable blend(GL_BLEND); + + + //tex unit 0 + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); - glTexCoord2f(tc1.mV[0], tc2.mV[1]); - glVertex2f(-1,1); + mGlow[1].bindTexture(); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, uv0); + glActiveTextureARB(GL_TEXTURE1_ARB); + glEnable(GL_TEXTURE_RECTANGLE_ARB); - glTexCoord2f(tc2.mV[0], tc1.mV[1]); - glVertex2f(1,-1); + //tex unit 1 + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); - glTexCoord2f(tc2.mV[0], tc2.mV[1]); - glVertex2f(1,1); - glEnd(); + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, uv1); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glVertexPointer(2, GL_FLOAT, 0, v); + + mScreen.bindTexture(); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisable(GL_TEXTURE_RECTANGLE_ARB); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + glActiveTextureARB(GL_TEXTURE0_ARB); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); +#endif + +} + +void LLPipeline::processImagery(LLCamera& camera) +{ + for (LLWorld::region_list_t::iterator iter = gWorldp->getRegionList().begin(); + iter != gWorldp->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME); + if (part) + { + part->processImagery(&camera); + } + } +} + + +inline float sgn(float a) +{ + if (a > 0.0F) return (1.0F); + if (a < 0.0F) return (-1.0F); + return (0.0F); +} + +void LLPipeline::generateWaterReflection(LLCamera& camera_in) +{ + if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) + { + LLCamera camera = camera_in; + camera.setFar(camera.getFar()*0.87654321f); + LLPipeline::sReflectionRender = TRUE; + S32 occlusion = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = llmin(occlusion, 1); + U32 type_mask = gPipeline.mRenderTypeMask; + + glh::matrix4f projection = glh_get_current_projection(); + glh::matrix4f mat; + + stop_glerror(); + LLPlane plane; + + F32 height = gAgent.getRegion()->getWaterHeight(); + F32 to_clip = fabsf(camera.getOrigin().mV[2]-height); + F32 pad = -to_clip*0.05f; //amount to "pad" clip plane by + + //plane params + LLVector3 pnorm; + F32 pd; + + S32 water_clip = 0; + if (!gCamera->cameraUnderWater()) + { //camera is above water, clip plane points up + pnorm.setVec(0,0,1); + pd = -height; + plane.setVec(pnorm, pd); + water_clip = -1; + } + else + { //camera is below water, clip plane points down + pnorm = LLVector3(0,0,-1); + pd = height; + plane.setVec(pnorm, pd); + water_clip = 1; + } + + + + if (!gCamera->cameraUnderWater()) + { //generate planar reflection map + LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); + glClearColor(0,0,0,0); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + mWaterRef.bindTarget(); + mWaterRef.getViewport(gGLViewport); + mWaterRef.clear(); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); + + stop_glerror(); + + LLVector3 origin = camera.getOrigin(); + + glPushMatrix(); + + mat.set_scale(glh::vec3f(1,1,-1)); + mat.set_translate(glh::vec3f(0,0,height*2.f)); + + glh::matrix4f current = glh_get_current_modelview(); + + mat = current * mat; + + glh_set_current_modelview(mat); + glLoadMatrixf(mat.m); + + LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE); + + glCullFace(GL_FRONT); + + //initial sky pass (no user clip plane) + { //mask out everything but the sky + U32 tmp = mRenderTypeMask; + mRenderTypeMask &= ((1 << LLPipeline::RENDER_TYPE_SKY) | + (1 << LLPipeline::RENDER_TYPE_CLOUDS) | + (1 << LLPipeline::RENDER_TYPE_WL_SKY)); + + static LLCullResult result; + updateCull(camera, result); + stateSort(camera, result); + renderGeom(camera, TRUE); + + mRenderTypeMask = tmp; + } + + if (LLDrawPoolWater::sNeedsReflectionUpdate) + { + mRenderTypeMask &= ~((1<cameraUnderWater() ? FALSE : TRUE; + + if (LLPipeline::sUnderWaterRender) + { + mRenderTypeMask &= ~((1<setupViewport(); + mRenderTypeMask = type_mask; + LLDrawPoolWater::sNeedsReflectionUpdate = FALSE; + gCamera->setUserClipPlane(LLPlane(-pnorm, -pd)); + LLPipeline::sUseOcclusion = occlusion; + } +} + +LLCubeMap* LLPipeline::findReflectionMap(const LLVector3& location) +{ + LLViewerRegion* region = gWorldp->getRegionFromPosAgent(location); + if (region) + { + LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME); + if (part) + { + LLSpatialGroup::OctreeNode* node = part->mOctree->getNodeAt(LLVector3d(location), 32.0); + if (node) + { + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + return group->mReflectionMap; + } + } + } + + return NULL; +} + +void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) +{ +#if !LL_RELEASE_FOR_DOWNLOAD + LLGLState::checkClientArrays(mask); +#endif + + for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) + { + LLSpatialGroup* group = *i; + if (!group->isDead() && + (!sUseOcclusion || !group->isState(LLSpatialGroup::OCCLUDED)) && + gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && + group->mDrawMap.find(type) != group->mDrawMap.end()) + { + pass->renderGroup(group,type,mask,texture); + } + } +} + +void LLPipeline::generateImpostor(LLVOAvatar* avatar) +{ + static LLCullResult result; + result.clear(); + grabReferences(result); + + if (!avatar || !avatar->mDrawable) + { + return; + } + + assertInitialized(); + + if (!avatar->mImpostor.isComplete()) + { + avatar->mImpostor.allocate(128,256,GL_RGBA,TRUE); + avatar->mImpostor.bindTexture(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + LLImageGL::unbindTexture(0, GL_TEXTURE_2D); + } + + U32 mask = (1<mDrawable, *gCamera); + LLVOAvatar::sUseImpostors = FALSE; + + LLVOAvatar::attachment_map_t::iterator iter; + for (iter = avatar->mAttachmentPoints.begin(); + iter != avatar->mAttachmentPoints.end(); + ++iter) + { + LLViewerObject* object = iter->second->getObject(); + if (object) + { + markVisible(object->mDrawable->getSpatialBridge(), *gCamera); + } + } + + stateSort(*gCamera, result); + + glClearColor(0.0f,0.0f,0.0f,0.0f); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glStencilMask(0xFFFFFFFF); + glClearStencil(0); + + { + LLGLEnable scissor(GL_SCISSOR_TEST); + glScissor(0, 0, 128, 256); + avatar->mImpostor.bindTarget(); + avatar->mImpostor.getViewport(gGLViewport); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + } + + LLGLEnable stencil(GL_STENCIL_TEST); + + glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + const LLVector3* ext = avatar->mDrawable->getSpatialExtents(); + LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); + + LLCamera camera = *gCamera; + + camera.lookAt(gCamera->getOrigin(), pos, gCamera->getUpAxis()); + + LLVector2 tdim; + + LLVector3 half_height = (ext[1]-ext[0])*0.5f; + + LLVector3 left = camera.getLeftAxis(); + left *= left; + left.normVec(); + + LLVector3 up = camera.getUpAxis(); + up *= up; + up.normVec(); + + tdim.mV[0] = fabsf(half_height * left); + tdim.mV[1] = fabsf(half_height * up); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glh::matrix4f ortho = gl_ortho(-tdim.mV[0], tdim.mV[0], -tdim.mV[1], tdim.mV[1], 1.0, 256.0); + glh_set_current_projection(ortho); + glLoadMatrixf(ortho.m); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glh::matrix4f mat; + camera.getOpenGLTransform(mat.m); + + mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; + + glLoadMatrixf(mat.m); + glh_set_current_modelview(mat); + + renderGeom(camera); + + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_EQUAL, 1, 0xFFFFFF); + + { + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f; + LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f; + + LLGLEnable blend(GL_BLEND); + gGL.blendFunc(GL_ONE, GL_ONE); + LLImageGL::unbindTexture(0, GL_TEXTURE_2D); + + LLGLDepthTest depth(GL_FALSE, GL_FALSE); + + gGL.start(); + gGL.color4ub(0,0,0,1); + gGL.begin(GL_QUADS); + gGL.vertex3fv((pos+left-up).mV); + gGL.vertex3fv((pos-left-up).mV); + gGL.vertex3fv((pos-left+up).mV); + gGL.vertex3fv((pos+left+up).mV); + gGL.end(); + gGL.stop(); + + gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + avatar->mImpostor.flush(); + + avatar->setImpostorDim(tdim); + + LLVOAvatar::sUseImpostors = TRUE; + sUseOcclusion = occlusion; + sReflectionRender = FALSE; + sImpostorRender = FALSE; + gPipeline.mRenderTypeMask = saved_mask; glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); + + avatar->mNeedsImpostorUpdate = FALSE; + avatar->cacheImpostorValues(); +} + +BOOL LLPipeline::hasRenderBatches(const U32 type) const +{ + return sCull->getRenderMapSize(type) > 0; } + +LLCullResult::drawinfo_list_t::iterator LLPipeline::beginRenderMap(U32 type) +{ + return sCull->beginRenderMap(type); +} + +LLCullResult::drawinfo_list_t::iterator LLPipeline::endRenderMap(U32 type) +{ + return sCull->endRenderMap(type); +} + +LLCullResult::sg_list_t::iterator LLPipeline::beginAlphaGroups() +{ + return sCull->beginAlphaGroups(); +} + +LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() +{ + return sCull->endAlphaGroups(); +} + diff --git a/linden/indra/newview/pipeline.h b/linden/indra/newview/pipeline.h index 9b0706f..0e3e1c0 100644 --- a/linden/indra/newview/pipeline.h +++ b/linden/indra/newview/pipeline.h @@ -32,20 +32,20 @@ #ifndef LL_PIPELINE_H #define LL_PIPELINE_H +#include "llerror.h" #include "lldarrayptr.h" #include "lldqueueptr.h" #include "llstat.h" -#include "lllinkedqueue.h" -#include "llskiplist.h" #include "lldrawpool.h" #include "llspatialpartition.h" #include "m4math.h" #include "llmemory.h" #include "lldrawpool.h" #include "llgl.h" +#include "lldrawable.h" +#include "llrendertarget.h" class LLViewerImage; -class LLDrawable; class LLEdge; class LLFace; class LLViewerObject; @@ -54,6 +54,8 @@ class LLDisplayPrimitive; class LLTextureEntry; class LLRenderFunc; class LLCubeMap; +class LLCullResult; +class LLVOAvatar; typedef enum e_avatar_skinning_method { @@ -65,6 +67,11 @@ BOOL compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max); // Shouldn bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon = 0); BOOL LLLineSegmentAABB(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size); BOOL setup_hud_matrices(BOOL for_select); +glh::matrix4f glh_get_current_modelview(); +void glh_set_current_modelview(glh::matrix4f& mat); +glh::matrix4f glh_get_current_projection(); +void glh_set_current_projection(glh::matrix4f& mat); +glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar); class LLPipeline { @@ -75,16 +82,23 @@ public: void destroyGL(); void restoreGL(); void resetVertexBuffers(); + void resizeScreenTexture(); void releaseGLBuffers(); + void createGLBuffers(); + void resetVertexBuffers(LLDrawable* drawable); void setUseVBO(BOOL use_vbo); - void generateReflectionMap(LLCubeMap* cube_map, LLCamera& camera, GLsizei res); - void blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 res); + void generateImpostor(LLVOAvatar* avatar); + void generateReflectionMap(LLCubeMap* cube_map, LLCamera& camera); + void blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out); void bindScreenToTexture(); - void renderBloom(GLuint source, GLuint dest, GLuint buffer, U32 res, LLVector2 tc1, LLVector2 tc2); + void renderBloom(BOOL for_snapshot); + + LLCubeMap* findReflectionMap(const LLVector3& location); void init(); void cleanup(); + BOOL isInit() { return mInitialized; }; /// @brief Get a draw pool from pool type (POOL_SIMPLE, POOL_MEDIA) and texture. /// @return Draw pool, or NULL if not found. @@ -107,14 +121,14 @@ public: // Object related methods void markVisible(LLDrawable *drawablep, LLCamera& camera); + void markOccluder(LLSpatialGroup* group); void doOcclusion(LLCamera& camera); - void markNotCulled(LLSpatialGroup* group, LLCamera &camera, BOOL active = FALSE); + void markNotCulled(LLSpatialGroup* group, LLCamera &camera); void markMoved(LLDrawable *drawablep, BOOL damped_motion = FALSE); void markShift(LLDrawable *drawablep); void markTextured(LLDrawable *drawablep); void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); - void markRelight(LLDrawable *drawablep, const BOOL now = FALSE); - + //get the object between start and end that's closest to start. Return the point of collision in collision. LLViewerObject* pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision); @@ -136,7 +150,9 @@ public: void setUseVertexShaders(BOOL use_shaders); BOOL getUseVertexShaders() const { return mVertexShadersEnabled; } BOOL canUseVertexShaders(); - + BOOL canUseWindLightShaders() const; + BOOL canUseWindLightShadersOnObjects() const; + // phases void resetFrameStats(); @@ -144,26 +160,29 @@ public: void updateMoveNormalAsync(LLDrawable* drawablep); void updateMovedList(LLDrawable::drawable_vector_t& move_list); void updateMove(); - void updateCull(LLCamera& camera); + void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane void updateGeom(F32 max_dtime); //calculate pixel area of given box from vantage point of given camera static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); - void stateSort(LLCamera& camera); + void stateSort(LLCamera& camera, LLCullResult& result); void stateSort(LLSpatialGroup* group, LLCamera& camera); void stateSort(LLSpatialBridge* bridge, LLCamera& camera); void stateSort(LLDrawable* drawablep, LLCamera& camera); void postSort(LLCamera& camera); - void forAllDrawables(LLSpatialGroup::sg_vector_t& groups, void (*func)(LLDrawable*)); void forAllVisibleDrawables(void (*func)(LLDrawable*)); void renderObjects(U32 type, U32 mask, BOOL texture = TRUE); + void renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture); - void renderGeom(LLCamera& camera); + void grabReferences(LLCullResult& result); + + void renderGeom(LLCamera& camera, BOOL forceVBOUpdate = FALSE); + void processImagery(LLCamera& camera); + void generateWaterReflection(LLCamera& camera); void renderHighlights(); void renderDebug(); - void processOcclusion(LLCamera& camera); void renderForSelect(std::set& objects); void renderFaceForUVSelect(LLFace* facep); @@ -172,29 +191,33 @@ public: void findReferences(LLDrawable *drawablep); // Find the lists which have references to this object BOOL verify(); // Verify that all data in the pipeline is "correct" - S32 getVisibleCount() const { return mVisibleList.size(); } S32 getLightCount() const { return mLights.size(); } void calcNearbyLights(LLCamera& camera); void setupHWLights(LLDrawPool* pool); void setupAvatarLights(BOOL for_edit = FALSE); - void enableLights(U32 mask, F32 shadow_factor); - void enableLightsStatic(F32 shadow_factor); - void enableLightsDynamic(F32 shadow_factor); - void enableLightsAvatar(F32 shadow_factor); + void enableLights(U32 mask); + void enableLightsStatic(); + void enableLightsDynamic(); + void enableLightsAvatar(); void enableLightsAvatarEdit(const LLColor4& color); void enableLightsFullbright(const LLColor4& color); void disableLights(); - void setAmbient(const LLColor4& ambient); void shiftObjects(const LLVector3 &offset); void setLight(LLDrawable *drawablep, BOOL is_light); void setActive(LLDrawable *drawablep, BOOL active); + BOOL hasRenderBatches(const U32 type) const; + LLCullResult::drawinfo_list_t::iterator beginRenderMap(U32 type); + LLCullResult::drawinfo_list_t::iterator endRenderMap(U32 type); + LLCullResult::sg_list_t::iterator beginAlphaGroups(); + LLCullResult::sg_list_t::iterator endAlphaGroups(); + + void addTrianglesDrawn(S32 count); BOOL hasRenderType(const U32 type) const { return (type && (mRenderTypeMask & (1< mAlphaSizzleImagep; - //MUST MATCH THE ORDER OF DECLARATION IN LLPipeline::init() - typedef enum - { - PARTITION_VOLUME = 0, - PARTITION_BRIDGE, - PARTITION_HUD, - PARTITION_TERRAIN, - PARTITION_WATER, - PARTITION_TREE, - PARTITION_PARTICLE, - PARTITION_CLOUD, - PARTITION_GRASS, - PARTITION_NONE, - NUM_PARTITIONS - } eObjectPartitions; - -private: - std::vector mObjectPartition; public: LLSpatialPartition* getSpatialPartition(LLViewerObject* vobj); - LLSpatialPartition* getSpatialPartition(U32 index); void updateCamera(BOOL reset = FALSE); @@ -347,7 +342,14 @@ public: LLQuaternion mFlyCamRotation; BOOL mBackfaceCull; + S32 mBatchCount; + S32 mMatrixOpCount; + S32 mTextureMatrixOps; + S32 mMaxBatchSize; + S32 mMinBatchSize; + S32 mMeanBatchSize; S32 mTrianglesDrawn; + S32 mNumVisibleNodes; LLStat mTrianglesDrawnStat; S32 mVerticesRelit; @@ -359,25 +361,48 @@ public: static S32 sCompiles; static BOOL sShowHUDAttachments; - static BOOL sUseOcclusion; + static S32 sUseOcclusion; // 0 = no occlusion, 1 = read only, 2 = read/write + static BOOL sFastAlpha; + static BOOL sDisableShaders; // if TRUE, rendering will be done without shaders + static BOOL sRenderBump; + static BOOL sUseFBO; + static BOOL sUseFarClip; static BOOL sSkipUpdate; //skip lod updates static BOOL sDynamicReflections; + static BOOL sWaterReflections; + static BOOL sDynamicLOD; + static BOOL sReflectionRender; + static BOOL sImpostorRender; + static BOOL sUnderWaterRender; static BOOL sRenderGlow; - + static BOOL sTextureBindTest; + static BOOL sRenderFrameTest; + //screen texture - GLuint mScreenTex; + LLRenderTarget mScreen; + LLVector2 mScreenScale; - //texture for making the glow - GLuint mGlowMap; - GLuint mGlowBuffer; + //water reflection texture + LLRenderTarget mWaterRef; + + //water distortion texture (refraction) + LLRenderTarget mWaterDis; + //texture for making the glow + LLRenderTarget mGlow[3]; + //framebuffer objects for off-screen scratch space - GLuint mFramebuffer[2]; + //GLuint mFramebuffer[4]; + //GLuint mDepthbuffer[2]; //dynamic cube map scratch space LLPointer mCubeBuffer; + //cube map anti-aliasing buffers + GLuint mBlurCubeBuffer[3]; + GLuint mBlurCubeTexture[3]; + //frambuffer object for rendering dynamic cube maps GLuint mCubeFrameBuffer; @@ -388,22 +413,12 @@ public: LLColor4 mSunDiffuse; LLVector3 mSunDir; - LLSpatialGroup::sg_vector_t mActiveGroups; - LLSpatialGroup::drawmap_elem_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; - std::vector mAlphaGroups; - std::vector mAlphaGroupsPostWater; - LLSpatialGroup::sg_vector_t mVisibleGroups; - LLSpatialGroup::sg_vector_t mDrawableGroups; - - void clearRenderMap(); - BOOL mInitialized; BOOL mVertexShadersEnabled; S32 mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed protected: U32 mRenderTypeMask; - U32 mRenderFeatureMask; U32 mRenderDebugFeatureMask; U32 mRenderDebugMask; @@ -412,9 +427,6 @@ protected: ///////////////////////////////////////////// // // - LLDrawable::drawable_vector_t mVisibleList; - LLSpatialBridge::bridge_vector_t mVisibleBridge; - LLSpatialBridge::bridge_vector_t mOccludedBridge; LLDrawable::drawable_vector_t mMovedList; LLDrawable::drawable_vector_t mMovedBridge; LLDrawable::drawable_vector_t mShiftList; @@ -457,7 +469,7 @@ protected: // LLDrawable::drawable_list_t mBuildQ1; // priority LLDrawable::drawable_list_t mBuildQ2; // non-priority - + LLDrawable::drawable_set_t mActiveQ; LLDrawable::drawable_set_t mRetexturedList; @@ -496,15 +508,15 @@ protected: std::map mTerrainPools; std::map mTreePools; LLDrawPool* mAlphaPool; - LLDrawPool* mAlphaPoolPostWater; LLDrawPool* mSkyPool; - LLDrawPool* mStarsPool; LLDrawPool* mTerrainPool; LLDrawPool* mWaterPool; LLDrawPool* mGroundPool; LLRenderPass* mSimplePool; + LLDrawPool* mInvisiblePool; LLDrawPool* mGlowPool; LLDrawPool* mBumpPool; + LLDrawPool* mWLSkyPool; // Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar public: @@ -519,8 +531,7 @@ protected: U32 mLightMask; U32 mLightMovingMask; S32 mLightingDetail; - F32 mSunShadowFactor; - + static BOOL sRenderPhysicalBeacons; static BOOL sRenderScriptedTouchBeacons; static BOOL sRenderScriptedBeacons; @@ -536,5 +547,6 @@ void render_bbox(const LLVector3 &min, const LLVector3 &max); extern LLPipeline gPipeline; extern BOOL gRenderForSelect; +extern const LLMatrix4* gGLLastMatrix; #endif diff --git a/linden/indra/newview/postbuild.bat b/linden/indra/newview/postbuild.bat index 106dde1..f8859ac 100644 --- a/linden/indra/newview/postbuild.bat +++ b/linden/indra/newview/postbuild.bat @@ -23,7 +23,7 @@ xcopy ..\..\libraries\i686-win32\lib_debug\softokn3.dll .\debug\ /y xcopy ..\..\libraries\i686-win32\lib_debug\ssl3.dll .\debug\ /y xcopy ..\..\libraries\i686-win32\lib_debug\xpcom.dll .\debug\ /y xcopy ..\..\libraries\i686-win32\lib_debug\xul.dll .\debug\ /y -xcopy ..\..\libraries\i686-win32\lib_debug\openjpeg.dll .\debug\ /y +xcopy ..\..\libraries\i686-win32\lib_debug\openjpegd.dll .\debug\ /y rem --- this is required for mozilla debug builds and displays the aborty/retry/ignore dialog on an assert - crashes without it --- xcopy ..\..\libraries\i686-win32\lib_debug\windbgdlg.exe .\debug\ /y diff --git a/linden/indra/newview/releasenotes.txt b/linden/indra/newview/releasenotes.txt index f745a7e..5c9dc87 100644 --- a/linden/indra/newview/releasenotes.txt +++ b/linden/indra/newview/releasenotes.txt @@ -1,3 +1,93 @@ +Release Notes for Second Life 1.19.1(0) March 5th, 2008 +===================================== +New features and changes: + +* WindLight - Physically accurate atmospheric rendering and lighting +** Animateable day cycles +** Vastly improved realistic water with reflections and glimmer +** "Glow" as new object attribute +** Avatar Impostoring, which can speed up crowded scenes tremendously +** A new cleaned-up, easy to use Graphics Preferences tab with simple and advanced options for performance/quality settings + +* Additional rendering optimizations: +** Faster, more reliable occlusion culling - occluded regions are discovered instantaneously, eliminating random bad frames due to the camera moving too quickly +** No geometry transform overhead on region crossing - results in region crossings being slightly smoother +** Faster frustum culling - less time is spent determining what's visible, thus giving better overall framerates +** No copy-to-texture for ripple water - objects under water are rendered to texture at half resolution, resulting in better overall framerates +** Faster sky updates - the non-WindLight (aka no-shader) skies update quicker - even faster than the pre-WindLight skies! +** Single pass shiny when using shaders - making an object shiny will no longer require it to be rendered twice, which results in virtually free shiny functionality from a performance standpoint +** Single pass terrain when using shaders - the terrain is no longer drawn in two passes, which, from a performance standpoint, results in virtually free high detail terrain for shader friendly cards (See the System Recommendations at http://secondlife.com/corporate/sysreqs.php) +** Improved object update code (less work for the CPU) - attachments are no longer added to the active list, which improves performance in crowded areas +** Better scheduling of Avatar LOD (Level of Detail) updates - Avatar LOD is now calculated every 16 frames as opposed to every single frame, which removes redundant work +** Better Avatar culling through more accurate bounding boxes - Avatar bounding boxes now match their current animation, resulting in more optimized culling of avatars that are not visible in the frame +** Better tree rendering (70% fewer matrix operations, no reliance on GL matrix stack) - results in improved performance for tree rendering +** Trimmed unused state in LLDrawable, LLSpatialGroup, LLOctree, and LLFace - results in memory savings +** 16-bit index buffers are now used instead of 32-bit buffers - improves memory bandwidth for rendering geometry +** For more information, see: https://wiki.secondlife.com/wiki/WindLight +** Known Issue: +*** VWR-1749: Second Life viewer client freezes on MacBook Pro + +* Parcel Media - adds the ability to display Web based media on a parcel +** New API for Media Rendering +** Enables Web content inworld +** Added two new click actions, one for playing movies, and one for opening media +** Embedded web browser +** Added support for Media resizing + +* Estate-Level Abuse Reporting +** Estate owners and managers now have the ability (under World > Region/Estate) to enter an email address where abuse reports will be sent. +** If this address is empty, abuse reports will go to Linden Lab as usual. If the address is present, the abuse reports will be sent there instead. In both cases, all abuse reports are logged by Linden Lab. + +* Voice changes +** Changed the default voice volume to be a bit higher, to better match the volume of in-world sounds +** Changed the voice volume slider to default to the middle of its range, so voice volume can be boosted above the default + +* Improved Linux Voice support +** Better support for USB headsets and other devices +** Better voice audio quality + +Fixes: +* VWR-434: HUD textures are attaching but not being seen +* bumpmapping flips on active objects +* Fixed various Teleport and Show on Map bugs +* VWR-2030: Avatar only turns half-way in Appearance Mode +* VWR-2920: Sculptie LOD causes object to be deformed into a flattened sphere close while correct far +* VWR-2164: Particle Alpha transition is done incorrectly +* VWR-1609: disabling "Show Selection Beam" makes beam render incorrectly for others +* VWR-2834: Builds fail on 1.18.4.0 with no mozlib +* More Help Buttons in Graphics Preferences +* VWR-983: Particles -> Offscreen/hidden particles get extended life -> as of 1.16.x at least. +* (Linux) Working device enumeration A.K.A. USB headset support +* Linux Voice quality issues in 1.19.0 +* VWR-4921: not recognising in Linux that client is already running +* Change the way local output volume is handled +* Checkboxes in About Land untick when selected +* Add missing header file to export list for public SVN repository +* Copy To Inventory fail to execute without any output feedback when Notecard has changes but not saved +* Resolve instant message crash report +* Textures/Snapshots in a notecard are opened again when you click copy to inventory. +* VWR-882: Group name showing as (???) in About Land, IM tabs, and object edit window +* Packet-loss while viewing inventory currently results in perceived inventory loss +* stop and pause Media and music buttons do not work +* Displayed page in the client browser disappears when crossing property boundaries. +* replace misspellings in alerts.xml parameters ( + @@ -432,10 +433,18 @@ - - - - + + + + + + + + + + + + diff --git a/linden/indra/newview/skins/xui/de/floater_html.xml b/linden/indra/newview/skins/xui/de/floater_html.xml index 22b8e60..1b37b52 100644 --- a/linden/indra/newview/skins/xui/de/floater_html.xml +++ b/linden/indra/newview/skins/xui/de/floater_html.xml @@ -8,16 +8,8 @@ http://www.secondlife.com - - In-Welt-Hilfe - - - http://www.secondlife.com/app/support/inworld.html - - - Weitere Hilfe - - - http://www.secondlife.com/app/support/support.html + + diff --git a/linden/indra/newview/skins/xui/en-us/LCD_text.xml b/linden/indra/newview/skins/xui/en-us/LCD_text.xml index d679d64..b9c1200 100644 --- a/linden/indra/newview/skins/xui/en-us/LCD_text.xml +++ b/linden/indra/newview/skins/xui/en-us/LCD_text.xml @@ -1,28 +1,76 @@ - \ No newline at end of file + + + Debug Info + + + FPS + + + SimFPS + + + P-In + + + P-Out + + + P-Loss + + + Ping + + + Account Details + + + L$ bal + + + Time + + + Location Details 1 + + + Location Details 2 + + + Region + + + Parcel + + + Pos + + + Sqm + + + Owner + + + Type + + + Yes + + + No + + + ForSale + + + Traffic + + + Last 3 Chat Lines + + + Last 3 IM Lines + + diff --git a/linden/indra/newview/skins/xui/en-us/alerts.xml b/linden/indra/newview/skins/xui/en-us/alerts.xml index 67f7df5..69491ef 100644 --- a/linden/indra/newview/skins/xui/en-us/alerts.xml +++ b/linden/indra/newview/skins/xui/en-us/alerts.xml @@ -1,8 +1,11 @@ - Don't show me this again - Always choose this option - + + Don't show me this again + + + Always choose this option + [ALERT_NAME] is missing from alerts.xml! @@ -340,13 +343,13 @@ according to the Community Standards. Selecting the "Publish in Search" Checking this box will show: - this parcel in search results -- this parcel's public objects +- this parcel's public objects - this parcel in web search -You can't make this parcel show in search because it is located in a + You can't make this parcel show in search because it is located in a region that forbids this. @@ -368,16 +371,16 @@ according to the Community Standards. -You can propose to another Resident or dissolve an existing partnership through the [SECOND_LIFE] website. + You can propose to another Resident or dissolve an existing partnership through the [SECOND_LIFE] website. Go to the Second Life web site for more information on partnering? - - + + @@ -505,14 +508,13 @@ Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NA - - + + -ATTENTION: Clicking 'sell to anyone' makes your land available to the entire Second Life community, even those not in this region. + ATTENTION: Clicking 'sell to anyone' makes your land available to the entire Second Life community, even those not in this region. The selected [LAND_SIZE] m2 land is being set for sale. Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NAME]. - - @@ -1013,6 +1015,55 @@ Are you sure you want to delete these items? because you have specified the -safe option. + + + You do not appear to have the proper hardware requirements for Second Life. Second Life requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system. + +If you continue to have problems, please visit: http://www.secondlife.com/support + + + + + Warning: Your system does not meet Second Life's minimum system requirements. If you continue using Second Life, you may experience poor performance. Unfortunately, we cannot provide technical support for unsupported system configurations. + +MINSPECS +Do you wish to visit [_URL] for more information? + + + + + http://www.secondlife.com/corporate/sysreqs.php + + + + + - Your graphics card does not meet the minimum requirements. + + + + + - Your CPU speed does not meet the minimum requirements. + + + + + 796 + + + + + - Your system memory does not meet the minimum requirements. + + + + + 510 + + Display settings have been set to recommended levels @@ -1025,10 +1076,10 @@ based on your system configuration. [SECOND_LIFE] crashed while initializing graphics drivers. -Shaders will be disabled in order to avoid some common driver errors. +Graphics Quality will be set to low to avoid some common driver errors. This will disable some graphics features. We recommend updating your graphics card drivers. -Shaders can be re-enabled in Preferences > Graphics Detail. +Graphics Quality can be raised in Preferences > Graphics. @@ -1568,6 +1619,20 @@ have permission to modify. No frontmost floater to save. + + +Your search query was modified and the +words that were too short were removed. + +Searched for: [FINALQUERY] + + + + +Your search terms were too short +so no search was performed. + + Collada export failed: Unknown server error. @@ -1684,27 +1749,6 @@ Cannot find the region this land is in. Please use Tools -> Report Bug to report this. - - - Unable to set land owner: -No parcel selected. - - - - - Unable to buy land because selection spans multiple regions. - -Please select a smaller area and try again. - - - - - Unable to buy land: -Multiple parcels selected. - -Try selecting a single parcel. - - Unable to deed land: @@ -1750,14 +1794,6 @@ Preferences > Audio & Video.) Disable - - - Unable to buy land: -Waiting for server to report cost. - -Please try again. - - Unable to deed land: @@ -1766,59 +1802,12 @@ Waiting for server to report ownership. Please try again. - - - Unable to buy land: -The selection doesn't contain any public land. - - - - - Unable to buy land: -You have selected a parcel owned -by another Resident. - - - - - Unable to buy land: -Cannot find the region this land is in. - -Please use Tools -> Report Bug to report this. - - - - - Unable to buy land: -The region [REGION] does not allow transfer of land. - - Unable to deed land: The region [REGION] does not allow transfer of land. - - - Unable to buy land for the group: -You are not an officer in your current group. - -Please activate another group using Edit -> Groups... - - - - - Buying this [AREA] m2 of land costs L$[PRICE]. -You only have L$[BALANCE]. - - - - - Unable to abandon land: -No parcel selected. - - Unable to abandon land: @@ -2066,7 +2055,7 @@ Click Quit to exit [SECOND_LIFE] immediately. You do not have permission to buy land for your active group. - + Friends can give permissions to track each other on the map and @@ -2152,11 +2141,6 @@ of the above content is considered Mature according to the Community Standards. - - - Error encoding snapshot! - - You must specify a name for your classified. @@ -2471,7 +2455,7 @@ Please check your network connection. -We're having trouble connecting. There may be a problem with your internet connection or the Second Life servers. + We're having trouble connecting. There may be a problem with your internet connection or the Second Life servers. You can either check your internet connection and try again in a few minutes, click Help to connect to our support site, or click Teleport to attempt to teleport home. @@ -2779,26 +2763,6 @@ Download to your Applications folder? Cancel - - - Classified ads appear in the 'Classified' section of the -Find directory for one week. -Fill out your ad, then click 'Publish...' to add it to the -directory. -You'll be asked for a price to pay when clicking Publish. -Paying more makes your ad appear higher in the list, and -also appear higher when people search for keywords. - - - When adding a new Classified - - - - Go to www.secondlife.com to manage your account? @@ -3310,7 +3274,7 @@ This is DANGEROUS and should only be done to invoke the hack allowing objects/L$ to be transfered in/out of a grid. It will change thousands of regions and make the -spaceserver hiccup. +spaceserver hiccup. -Checking this box will block parcel owners from listing their parcels in search + Checking this box will block parcel owners from listing their parcels in search Default: Off -Checking this box will show: + Checking this box will show: - this parcel in search results -- this parcel's public objects +- this parcel's public objects @@ -3885,7 +3849,7 @@ Default: off Access to this estate will be limited to Residents listed here and any groups below. This setting is -only available when Visible from Mainland is +only available when Public Access is unchecked. @@ -3893,19 +3857,27 @@ unchecked. Access to this estate will be limited to groups listed here and any Residents above. This setting is -only available when Visible from Mainland is +only available when Public Access is unchecked. + + + Setting this to a valid email address will cause +abuse reports on this estate to be sent to that address. +Setting it blank will cause abuse reports to be sent +only to Linden Lab. + + Residents on this list are denied access to your estate, -regardless of any other settings. +regardless of any other settings. - - Parcels in this estate are allowed to have their own voice + + Parcels in this estate are allowed to have their own voice channels in which residents may hear and talk with others nearby. @@ -3913,9 +3885,9 @@ Default: off - -This version of Second Life is not compatible with the Voice Chat feature in this region. In order for Voice Chat to function correctly you will need to update Second Life. - + + This version of Second Life is not compatible with the Voice Chat feature in this region. In order for Voice Chat to function correctly you will need to update Second Life. + @@ -4140,7 +4112,7 @@ Move the inventory item(s)? Warning: The Pay Object click action has been set, but it -will only work if a script is added with a money() event. +will only work if a script is added with a money() event. When Setting 'Pay' on objects without money() events @@ -4179,6 +4151,20 @@ will only work if a script is added with a money() event. Cancel + + + Inventory fetch from server timed out. Retry? + + + Retry Fetch Inventory Descendents + + + + Are you sure you want to quit? @@ -4193,9 +4179,9 @@ will only work if a script is added with a money() event. Continue - + -Use this tool to report violations of the Terms of Service + Use this tool to report violations of the Terms of Service and Community Standards. See: http://secondlife.com/corporate/tos.php @@ -4210,7 +4196,7 @@ http://secondlife.com/community/blotter.php -IMPORTANT: This report will go to the owner of the + IMPORTANT: This report will go to the owner of the region you are currently in and not to Linden Lab. As a service to residents and visitors, the owner of @@ -4226,12 +4212,12 @@ About Land.) The resolution of this report applies only to this Region; Residents access to other areas of Second Life will not be affected by the outcome of this report. Only Linden Lab can -restrict access to the entirety of Second Life. +restrict access to the entirety of Second Life. -Use this tool to *only* report technical features that do not perform + Use this tool to *only* report technical features that do not perform as described or expected, please provide as much detail as possible, You may reply to the auto-response email to add more details to your report. @@ -4393,6 +4379,17 @@ your cookies? Cancel + + + Are you sure you want to clear your list of saved URLs? + + + + Are you sure you want to permanently remove @@ -4410,7 +4407,7 @@ the contents of your Lost And Found folder? -The following SLURL has been copied to your clipboard: + The following SLURL has been copied to your clipboard: [SLURL] Put it in a web page to give others easy access to this location or @@ -4420,40 +4417,395 @@ try it out yourself by pasting it into the address bar of your web browser. When copying a SLURL to your clipboard + + + This panel controls window size and resolution and the quality of the client's graphics. The graphics preferences interface allows you to choose between four graphics levels: Low, Mid, High, and Ultra. One may customize their graphics settings by checking the Custom checkbox and manipulating the following settings: + +Shaders: Enable or disable various types of pixel shaders. + +Reflection Detail: Sets the types of objects that water can reflect. + +Avatar Rendering: Sets options that affect how the client renders avatars. + +Draw Distance: Affects how far out from your viewpoint objects will be rendered in the scene. + +Max Particle Count: Sets the maximum number of particles you are able to see on your screen at once. + +Post Process Quality: Sets the resolution with which Glow is rendered. + +Mesh Detail: Sets the amout of detail used in rendering certain objects. + +Lighting Detail: Selects what types of lights you would like to render. + +Terrain Detail: Sets the amount of terrain detail you would like to see. + +Sky Detail: Sets the amount of tesselation of the sky dome. A higher value takes longer to render, but makes the sun look more rounded. + + + + + Do you wish to overwrite the saved preset? + + + + + + + Do you wish to delete [SKY]? + + + + + + + You cannot edit or delete a default preset. + + + + + This day cycle file references a missing sky file: [SKY]. + + + + + PostProcess Effect exists. Do you still wish overwrite it? + + + + + + + Edit the WindLight sliders to create and save a set of skies. + + + + + Set which skies to turn to throughout the day. + + + + + These settings adjust the way the environment looks locally on your computer. Your graphics card needs to support atmospheric shaders in order to have access to all of the settings. + +Adjust the "Time of Day" slider to change the day's phase locally on the viewer. + +Adjust the "Cloud Cover" slider to control how much the clouds cover the sky. + +Pick a color in the "Water Color" color picker to change the color of the water. + +Adjust the "Water Fog" slider to control how dense the fog is underwater. + +Click "Use Estate Time" to reset the time of day to the region's current time of day and remain linked to it. + +Click "Advanced Sky" to bring up an editor with more advanced settings for the sky. + +Click "Advanced Water" to bring up an editor with more advanced settings for the water. + + + + + The Day Cycle Editor gives you control over the sky during Second Life's day/night cycle. This is the cycle that is used by the Basic Environment Editor's Time of Day slider. + +The Day Cycle Editor works by setting keyframes. These are nodes (represented by the gray blips on the time graph) that have Sky Presets associated with them. As the Time of Day progresses, the WindLight sky "animates" as it interpolates between these keyframes. + +The yellow arrow above the timeline represents your current view, based on Time of Day. Click and drag it to see how your day will animate. You may add or delete keyframes by pressing the Add Key and Delete Key buttons to the right of the timeline. + +You can set the time position of a keyframe by either dragging it along the timeline, or by setting its value manually in the Key Frame Settings frame. Within the Key Frame Settings frame, you'll be able to associate the keyframe with its respective WindLight preset. + +Length of Cycle dictates the overall duration of a "day". Setting this to a low value (for instance, 2 min.) will mean your entire 24-hour timeline will animate in only two real minutes! Once you are satisfied with your timeline and keyframe cycle, use the Play and Stop buttons to preview the results. Remember- you can also move the yellow time-indicator arrow above the timeline to see the cycle animate interactively. Using the Use Estate Time button will synchronize your day length and time of day with the Estate's day cycle. + +Once you are pleased with your Day Cycle, you can save and load it with the Save Test Day and Load Test Day buttons. Note that, for now, we only allow one Day Cycle. + + + + + Use the Red/Green/Blue (RGB) sliders to adjust the color of the sky. You can use the Intensity (I) slider to move all three RGB sliders in unison. + + + + + Haze Horizon is one of the most useful parameters for +adjusting overall light exposure in the scene. It is +effective for simulating many exposure settings, +such as white-outs from the sun and darker, +closed-iris settings. + + + + + Blue Density affects the overall color saturation of the sky and fog. If you move the Intensity (I) slider to the right, colors will become brighter and more vibrant. If you move it all the way to the left, the colors will become duller, eventually fading to black and white. If you want to fine-tune the sky's color balance, you can control individual elements of saturation by using the Red/Green/Blue (RGB) sliders. + + + + + Haze Density controls the level of dull, gray +haze in the atmosphere. It is effective for +simulating scenes with high levels of smoke +and man-made pollutants. It is also effective +for simulating fog and mist. + + + + + The Density Multiplier can be used to affect the overall atmospheric density. At lower settings, it creates a feeling of "thin air", and at higher settings, it creates a very heavy, smoggy effect. + + + + + Adjusts WindLight's perceived distance. A value of +zero effectively turns off WindLight's influence +on terrain and objects. Values greater than 1 simulate +greater distances for thicker atmospheric effects. + + + + + Max Altitude adjusts the altitude calculations WindLight +performs when computing its atmospheric lighting. At +later times of day, it is useful for adjusting how +"deep" the sunset appears. + + + + + Adjusts the color and intensity of the direct light in the scene. + + + + + Adjusts the color and intensity of ambient atmospheric light in the scene. + + + + + The Size slider controls the size of the sun. +The Focus slider controls how blurred the sun +is over the sky. + + + + + Adjust the screen's distribution of light and dark. + + + + + Adjusts the brightness of the stars in the sky. + + + + + Controls the location of the sun in the sky. +Similar to elevation. + + + + + Controls the location of the sun in the sky. +Similar to azimuth. + + + + + Edits the color of the clouds. It is generally +recommended to keep it whitish, +but hey, have fun if you want. + + + + + Controls the detail image layered on top +of the main cloud image. X and Y control +its position. D (Density) controls how puffy or +fractured the clouds appear. + + + + + Allows you to control the position of the clouds +with the X and Y sliders and how dense they are +with the the D slider. + + + + + Controls how much the clouds cover the sky. + + + + + Controls the scaling of the cloud image on the sky dome. + + + + + Controls the speed of the clouds as they move in the X direction. + + + + + Controls the speed of the clouds as they move in the Y direction. + + + + + Check this box to enable rendering of Second Life's older classic clouds in addition to WindLight's clouds. + + + + + Chooses the color of the underwater fog. + + + + + Controls how dense the water fog is and how far you can see underwater. + + + + + Modifies the effect of the Fog Density Exponent to control how far you can see when your avatar is underwater. + + + + + Controls how much the surface of the water glows. + + + + + Controls the scaling of the three wavelets that make up the water. + + + + + Controls how much light is reflected at different angles. + + + + + Controls how much light intensity is reflected. + + + + + Controls how much light is refracted from looking above the surface of the water. + + + + + Controls how much light is refracted from looking from below the surface of the water. + + + + + Controls how waves and reflections are mixed. + + + + + Controls what normal map is layered across the water to determine reflections/refractions. + + + + + Controls where and how fast the large scaled version of the normal map moves in the X and Y direction. + + + + + Controls where and how fast the the small scaled version of the normal map moves in the X and Y direction. + + + + + Give me a name for the new sky. + + + New Preset + + + + + + + Preset already exists! + + + + + Give me a name for the new water preset. + + + New Preset + + + + + + + Preset already exists! + + + + + You cannot edit or delete a default preset. + + - - Error starting a new chat session with [RECIPIENT]. + + Error starting a new chat session with [RECIPIENT]. [REASON] - - Error starting a new chat session with [RECIPIENT]. + + Error starting a new chat session with [RECIPIENT]. [REASON] - - Error [EVENT] [RECIPIENT]. + + Error [EVENT] [RECIPIENT]. [REASON] - - Your chat session with [NAME] must close. + + Your chat session with [NAME] must close. [REASON] @@ -4462,10 +4814,10 @@ try it out yourself by pasting it into the address bar of your web browser. they are part of an attachment. - - + -

Granting this request gives a script ongoing permission to take Linden dollars (L$) from your account. To revoke this permission, the object owner must delete the object or reset the scripts in the object.

+ Granting this request gives a script ongoing permission to take Linden dollars (L$) from your account. To revoke this permission, the object owner must delete the object or reset the scripts in the object.
- + -Second Life doesn't know how to handle the link: + Second Life doesn't know how to handle the link: [SLURL] Most links are similar to this: @@ -4513,7 +4865,9 @@ Would you like to visit the Second Life website to verify your age? - https://secondlife.com/account/verification.php + + https://secondlife.com/account/verification.php + @@ -4531,7 +4885,8 @@ Would you like to visit the Second Life website to set this up? - https://secondlife.com/account/ + + https://secondlife.com/account/ + - diff --git a/linden/indra/newview/skins/xui/en-us/floater_about.xml b/linden/indra/newview/skins/xui/en-us/floater_about.xml index d01ef3f..e9253ff 100644 --- a/linden/indra/newview/skins/xui/en-us/floater_about.xml +++ b/linden/indra/newview/skins/xui/en-us/floater_about.xml @@ -7,7 +7,8 @@ follows="left|top|right|bottom" font="SansSerifSmall" height="168" left="6" max_length="65536" mouse_opaque="true" name="credits_editor" text_color="1, 1, 1, 1" text_readonly_color="1, 1, 1, 1" width="458" - word_wrap="true">Second Life is brought to you by Philip, Andrew, Tessa, Cory, Frank, James, Doug, Hunter, Richard, John, Eric, Avi, AaronB, AaronY, Ian, Peter, Mark, Robin, Stephen, Tracy, Ryan, Alberto, Haney, Tanya, JimJ, Dan, Ben, Stephanie, Tim, Evan, Catherine, Colin, Chris, Reuben, Charity, Jeska, James, JonHenry, Kelly, Callum, Char, Daniel, DavidF, Don, Jeff, Lauren, Lee, Michael, Ramzi, Vektor, Steve, TomY, Tess, Kona, Brent, Clarissa, PeterP, Jesse, Annette, Cyn, Blue, Ginsu, Jonathan, Karen, Adam, Nova, Deana, Lizzie, Patsy, DavidK, Isaac, Pathfinder, Monroe, Jill, Benny, Altruima, Rheya, Jennifer, Jack, DaveP, Brad, Mick, Babbage, Elisabeth, Brian, Beth, Data, Ethan, Wendy, Nicole, Sky, Jeffrey, Zero, Coffee, Tesla, Kenny, Makiko, Nigel, Teeple, Lucy, Mia, Dee, Guy, Harry, Liana, Branka, Jimbo, Aura, Vasuda, SarahD, bethanye, Torley, Runitai, MikeS, PaulM, Milo, Hermia, JoeM, Melanie, Rejean, DSmith, SMiller, Susan, Jose, DongYun, Justin, Andrey, Syrah, Donovan, Henrik, Nora, Lexie, AC, Donna, ChrisC, Alex, Leyla, Kyle, Mathew, Devin, Joshua, DanC, Jessica, Harmony, Claudia, Tramel, Glenn, Betsy, Fritz, Jun, Adam, Cassandra, Ken, RyanW, Spike, Tofu, Varas, Andy, Luke, RobLa, Chiyo, JohnZ, Dustin, George, Del, PeterP, Migyeong, Matthew, RMullane, CChampion, JTurbin, JamesC, Viola, Lightfoot, Jacqui, Sturm, Adrian, Buttercup, Alfred, Sunil, Alfred, Noel, Irfan, Jill, Yool, Jane, Yuki, Yoz, Matthew, Arthur, Jennifer, Karl, Brian, Ben, Janine, Christopher, Madhavi, Everett, Anthony, Joon, Jake, sean, Adreanne, Stephany, KellyJo, Jeremy, Pramod, Joshua, Sean, Christopher, Amy, Ceren, Katherine, jon, Sudheendra, James, Stephan, Kari, Kartic, Todd, Thomas, Joki, Rebecca, Belinda, Bert, Roger, Bridie, Kristi, Brian, Maria, John, Aric, Nathanel, Melinda, Darrell, Jennifer, Sandy, Greg, Rob, Brad, Chris, Eric, Palmer, Asi, Katja, Lisa, Minda, Jen, Aaron, Bryan, Mark, Jonathan, Jamie, Laurel, William, Matthew, Steve, David, Remy, James, Tim, Lee, Brian, Ashlei, Sam, Mike, Ethan, Austin, Wanda, Paul, Brian, Rachel, Valentyn, Emma Williams, Autum, Steven, Laley, Charles, Jessica, Sue, Gillian, CG, Kip, Kristen, Shamiran, Blake, Brett, Erica, Kent, Joel, Plexus, Twilight, Joppa, Enus, Kraft, Naveen, Simon, Q, Ronp, Laurap, Ram, KyleJM, Marty, Kend, Daveh, Prospero, Melissa, Nat, Hamilton, Green, Seraph, Ekim, Miz, Jimmy, Kosmo, Rome, Doris, JT, Benoc, Whump, Mango, Trinity, Patch, TJ, Christy, Bao, Joohwan, Kate, Oreh, Angela, Johan, Cheah, Lan, Matias, Brandy, Cogsworth, Aleks, Mitchell, Space, Einstein, Bambers, Colton, Malbers, Maggie, Umesh, Santosh, Rose, Stash, Rothman, Winnie, Stella, Niall and many others. + word_wrap="true"> + Second Life is brought to you by Philip, Andrew, Tessa, Cory, Frank, James, Doug, Hunter, Richard, John, Eric, Avi, AaronB, AaronY, Ian, Peter, Mark, Robin, Stephen, Tracy, Ryan, Alberto, Haney, Tanya, JimJ, Dan, Ben, Stephanie, Tim, Evan, Catherine, Colin, Chris, Reuben, Charity, Jeska, James, JonHenry, Kelly, Callum, Char, Daniel, DavidF, Don, Jeff, Lauren, Lee, Michael, Ramzi, Vektor, Steve, TomY, Tess, Kona, Brent, Clarissa, PeterP, Jesse, Annette, Cyn, Blue, Ginsu, Jonathan, Karen, Adam, Nova, Deana, Lizzie, Patsy, DavidK, Isaac, Pathfinder, Monroe, Jill, Benny, Altruima, Rheya, Jennifer, Jack, DaveP, Brad, Mick, Babbage, Elisabeth, Brian, Beth, Data, Ethan, Wendy, Nicole, Sky, Jeffrey, Zero, Coffee, Tesla, Kenny, Makiko, Nigel, Teeple, Lucy, Mia, Dee, Guy, Harry, Liana, Branka, Jimbo, Aura, Vasuda, SarahD, bethanye, Torley, Runitai, MikeS, PaulM, Milo, Hermia, JoeM, Melanie, Rejean, DSmith, SMiller, Susan, Jose, DongYun, Justin, Andrey, Syrah, Donovan, Henrik, Nora, Lexie, AC, Donna, ChrisC, Alex, Leyla, Kyle, Mathew, Devin, Joshua, DanC, Jessica, Harmony, Claudia, Tramel, Glenn, Betsy, Fritz, Jun, Adam, Cassandra, Ken, RyanW, Spike, Tofu, Varas, Andy, Luke, RobLa, Chiyo, JohnZ, Dustin, George, Del, PeterP, Migyeong, Matthew, RMullane, CChampion, JTurbin, JamesC, Viola, Lightfoot, Jacqui, Sturm, Adrian, Buttercup, Alfred, Sunil, Alfred, Noel, Irfan, Jill, Yool, Jane, Yuki, Yoz, Matthew, Arthur, Jennifer, Karl, Brian, Ben, Janine, Christopher, Madhavi, Everett, Anthony, Joon, Jake, sean, Adreanne, Stephany, KellyJo, Jeremy, Pramod, Joshua, Sean, Christopher, Amy, Ceren, Katherine, jon, Sudheendra, James, Stephan, Kari, Kartic, Todd, Thomas, Joki, Rebecca, Belinda, Bert, Roger, Bridie, Kristi, Brian, Maria, John, Aric, Nathanel, Melinda, Darrell, Jennifer, Sandy, Greg, Rob, Brad, Chris, Eric, Palmer, Asi, Katja, Lisa, Minda, Jen, Aaron, Bryan, Mark, Jonathan, Jamie, Laurel, William, Matthew, Steve, David, Remy, James, Tim, Lee, Brian, Ashlei, Sam, Mike, Ethan, Austin, Wanda, Paul, Brian, Rachel, Valentyn, Emma Williams, Autum, Steven, Laley, Charles, Jessica, Sue, Gillian, CG, Kip, Kristen, Shamiran, Blake, Brett, Erica, Kent, Joel, Plexus, Twilight, Joppa, Enus, Kraft, Naveen, Simon, Q, Ronp, Laurap, Ram, KyleJM, Marty, Kend, Daveh, Prospero, Melissa, Nat, Hamilton, Green, Seraph, Ekim, Miz, Jimmy, Kosmo, Rome, Doris, JT, Benoc, Whump, Mango, Trinity, Patch, TJ, Christy, Bao, Joohwan, Kate, Oreh, Angela, Johan, Cheah, Lan, Matias, Brandy, Cogsworth, Aleks, Mitchell, Space, Einstein, Bambers, Colton, Malbers, Maggie, Umesh, Santosh, Rose, Stash, Rothman, Winnie, Stella, Niall and many others. Thank you to the following residents for helping to ensure that this is the best version yet: aaron23 decuir, Abelv Vollmar, Abyssin Otoro, ActingIll Igaly, Adamas Carter, Addy Broome, Adelia Menges, Alexandra Rucker, Alexandrea Fride, Alissa Sabre, Alyx Jonson, Ann Otoole, Anton Fargis, Aradia Dielli, Araina jewell, Arcane Clawtooth, arcangelo vantelli, Are Sperber, Argent Stonecutter, arkady yost, Ashcroft Burnham, Ashen Arida, Auron Forcella, Azadine Umarov, Azildin Furst, Balp Allen, Balpien Hammerer, Barney Boomslang, Barrett Slade, becky pippen, Beeflin Grut, Beer Dailey, Behemoth Greenwood, bigmanu greene, bitova loon, Bonca Chikuwa, Bonnie Bechir, Brandon Catteneo, buttonpusher jones, Carina Raymaker, Ceera Murakami, Celierra Darling, ChatNoir Moonsoo, Cheetah Hammerer, chet neurocam, Cinthya Loveless, Cold Spitteler, Coral Quinnell, Crash Pointe, CrazyTB Oh, Creem Pye, Crom Chaffe, ctrl althouse, dade carver, Dael Ra, dakota schwade, Dale Innis, Damian McLeod, Danger Lytton, danielluh ashton, DanOfWA Flanagan, Davec Horsforth, Davidius Morigi, davie zinner, Day Oh, DBDigital Epsilon, Deany Fall, deBruce Munro, Decaf Coffey, Dedric Mauriac, Deeso Saeed, Dekka Raymaker, dexter eberhart, Dildo Spitz, Dizzy Banjo, djcabello klaar, Dnali Anabuki, Domchi Underwood, Doran Zemlja, Drew Dwi, Duckless Vandyke, Duncan Stenvaag, Dylan Rickenbacker, dzogchen Moody, Dzonatas Sol, Eddy Stryker, Edward Griffith, Edward Pearse, ein duesenburg, Elle Pollack, Elle74 Zaftig, Emileigh Starbrook, Emma Nowhere, ener bing, Erdrick Balbozar, eric domela, Evangeline Biedermann, Excalibur Longstaff, Fake Fitzgerald, Feldspar Millgrove, Feynt Mistral, Fluf Fredriksson, Forbid Utorid, Fortyniner Beck, Francesco Despres, Francisco Koolhoven, Franta Burt, Fury Rosewood, garde Burrel, Garmin Kawaguichi, Gavin Ichigo, Gellan Glenelg, Genie Demina, Gennifer Meredith, Gigs Taggart, Goldie Katsu, Gwyneth Llewelyn, Haravikk Mistral, Harleen Gretzky, Haruki Watanabe, Heather Manatiso, Henri Beauchamp, Honey Fairweather, Hypatia Callisto, Ice Brodie, icktoofay Kamachi, IntLibber Brautigan, Janise Dreamscape, Jay Shinobu, Jenni Ryba, Jeremy Ondricek, JetZep Zabelin, Jims Smythe, Jini Hammerer, Jopy Weber, JustOneMore Loon, Kaluura Boa, Kara Markova, Kevin Susenko, Khyra Ares, Kii Lilliehook, Kitty Barnett, Kris Kuttelwascher, Lanita Wingtips, Laura18 Streeter, Lee Ludd, Lettrius Jewell, Liberty Tesla, LilyAnna Carter, Lindal Kidd, Lisa Lowe, Lisa McConnell, Lola Machin, luca peck, Lupus Clawtooth, M1sha Dallin, Macsima Dagostino, Mana Janus, Mani Canning, Manjusri Binder, marceledward edman, march Korda, marchino villota, Marcus Llewellyn, MartinRJ Fayray, Matthew Dowd, Max Kleiber, mazzy fastback, McCabe Maxsted, Mckailen Kohnke, Meghan Dench, Melvin Starbrook, Mercia Mcmahon, Miakoda Carnell, Michelle2 Zenovka, Michi Lumin, mick parnall, Milla Michinaga, Millie Thompson, miranda Ashby, Mircea Lobo, MIssSara Beck, mouse mimistrobell, Myria Boa, Nanci Barthelmess, Nargus Asturias, Natalya Debevec, Nedrae Messmer, Nexeus Fatale, Niky Zenovka, Nimrod Szondi, Ninane Yoshikawa, Noch Tripsa, nokithecat writer, Nyko Merlin, Onyx Halberd, oryx tempel, Osprey Therian, Pac Hyun, Panagea McMillan, Patrick Ferrentino, PattehPh0x Katsu, ponk bing, Poppy Linden, Prajna Vella, Precious Rhiano, Prokofy Neva, Randall Lovenkraft, Rascal Ratelle, Raydon Writer, Rhaorth Antonelli, Rock Hayek, Ron Crimson, Ron Khondji, Ronald Richez, Rui Clary, Ruud Lathrop, Sakkano Imako, Sam Reinard, Sascha Vandyke, Scrippy Scofield, Sean18 McCarey, Sedona Mills, Sekonda Huet, Seraph Nephilim, Sergei Milos, Shadowquine Maltz, shai khalifa, sheilah flatley, Sheri Underwood, Shuggy Husky, Sierra Janus, Sigma Avro, Simil Miles, simon kline, Simon Nolan, Sindy Tsure, Sparks Keynes, Squirrel Wood, Stahi Columbia, StarSong Bright, Summer Seale, Sunn Thunders, Susan Koltai, Syler Zhora, Synack Fitzgerald, Tayra Dagostino, Tee Cramer, Teravus Ousley, Thomas Shikami, Tia Araw, Tillie Ariantho, Topher Brooks, Torley Linden, Twosteppin Jewell, tx Oh, urantia jewell, vaguegirl Petty, VeC Merlin, venus petrov, vv33d Beck, vynka dean, zann canto, zeebster colasanti, Zi Ree, Zion Tristan, Zorin Frobozz, Zyzzy Zarf @@ -31,12 +32,14 @@ All rights reserved. See licenses.txt for details. Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C) -Happiness is a warm puppy. -- Charles M. Schulz - +Happiness is a warm puppy. -- Charles M. Schulz + - + + You are at [POSITION] + diff --git a/linden/indra/newview/skins/xui/en-us/floater_about_land.xml b/linden/indra/newview/skins/xui/en-us/floater_about_land.xml index 85ac175..7e7c2f8 100644 --- a/linden/indra/newview/skins/xui/en-us/floater_about_land.xml +++ b/linden/indra/newview/skins/xui/en-us/floater_about_land.xml @@ -1,561 +1,554 @@