summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/contributions.txt7
-rw-r--r--indra/llcharacter/llkeyframemotion.cpp58
-rw-r--r--indra/llcharacter/llkeyframemotion.h1
-rw-r--r--indra/llcharacter/llmotioncontroller.cpp9
-rw-r--r--indra/llcharacter/llmotioncontroller.h2
-rw-r--r--indra/llcharacter/llpose.cpp23
-rw-r--r--indra/llcommon/llfasttimer.h7
-rw-r--r--indra/llcommon/llfile.cpp1
-rw-r--r--indra/llcommon/llkeythrottle.h5
-rw-r--r--indra/llmath/llcamera.cpp127
-rw-r--r--indra/llmath/llcamera.h22
-rw-r--r--indra/llmath/llcoordframe.cpp6
-rw-r--r--indra/llmath/llmath.h16
-rw-r--r--indra/llmath/lloctree.h382
-rw-r--r--indra/llmath/lltreenode.h89
-rw-r--r--indra/llmath/llvolume.cpp277
-rw-r--r--indra/llmath/llvolume.h14
-rw-r--r--indra/llmath/llvolumemgr.cpp23
-rw-r--r--indra/llmath/llvolumemgr.h1
-rw-r--r--indra/llmath/v3color.cpp8
-rw-r--r--indra/llmath/v3color.h10
-rw-r--r--indra/llmath/v4color.cpp10
-rw-r--r--indra/llmath/v4color.h4
-rw-r--r--indra/llmath/v4math.h3
-rw-r--r--indra/llprimitive/lltextureentry.cpp1
-rw-r--r--indra/llrender/llfontgl.cpp73
-rw-r--r--indra/llrender/llimagegl.cpp16
-rw-r--r--indra/llrender/llimagegl.h3
-rw-r--r--indra/llrender/llrendertarget.cpp185
-rw-r--r--indra/llrender/llrendertarget.h116
-rw-r--r--indra/llrender/llvertexbuffer.cpp538
-rw-r--r--indra/llrender/llvertexbuffer.h67
-rw-r--r--indra/llui/llbutton.cpp9
-rw-r--r--indra/llui/llcheckboxctrl.cpp11
-rw-r--r--indra/llui/llfloater.cpp30
-rw-r--r--indra/llui/llmenugl.cpp33
-rw-r--r--indra/llui/llmultislider.cpp677
-rw-r--r--indra/llui/llmultislider.h129
-rw-r--r--indra/llui/llmultisliderctrl.cpp634
-rw-r--r--indra/llui/llmultisliderctrl.h160
-rw-r--r--indra/llui/llpanel.h2
-rw-r--r--indra/llui/llscrollbar.cpp5
-rw-r--r--indra/llui/llscrollcontainer.cpp3
-rw-r--r--indra/llui/llscrolllistctrl.cpp7
-rw-r--r--indra/llui/llslider.h4
-rw-r--r--indra/llui/llsliderctrl.h13
-rw-r--r--indra/llui/llspinctrl.h2
-rw-r--r--indra/llui/lltabcontainer.cpp13
-rw-r--r--indra/llui/lltexteditor.cpp8
-rw-r--r--indra/llui/llui.cpp1034
-rw-r--r--indra/llui/llui.h2
-rw-r--r--indra/llui/lluictrlfactory.cpp16
-rw-r--r--indra/llui/lluictrlfactory.h2
-rw-r--r--indra/llui/llview.cpp25
-rw-r--r--indra/llui/llviewborder.cpp41
-rw-r--r--indra/llui/llviewborder.h3
-rw-r--r--indra/llwindow/lldxhardware.cpp2
-rw-r--r--indra/llwindow/llwindow.cpp4
-rw-r--r--indra/llwindow/llwindow.h2
-rw-r--r--indra/llwindow/llwindowmacosx.cpp29
-rw-r--r--indra/llwindow/llwindowsdl.cpp13
-rw-r--r--indra/llwindow/llwindowwin32.cpp14
-rw-r--r--indra/llwindow/llwindowwin32.h1
-rw-r--r--indra/newview/app_settings/high_graphics.xml39
-rw-r--r--indra/newview/app_settings/low_graphics.xml39
-rw-r--r--indra/newview/app_settings/mid_graphics.xml39
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl22
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl19
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl28
-rw-r--r--indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class1/effects/glowF.glsl31
-rw-r--r--indra/newview/app_settings/shaders/class1/effects/glowV.glsl22
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/terrainF.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/terrainV.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl23
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl45
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterF.glsl96
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl20
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterV.glsl90
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/highlightF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/highlightV.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightF.glsl30
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl34
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl26
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightV.glsl89
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl35
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl29
-rwxr-xr-xindra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl13
-rwxr-xr-xindra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl29
-rwxr-xr-xindra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl23
-rwxr-xr-xindra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/shinyF.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/shinyV.glsl25
-rwxr-xr-xindra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleV.glsl22
-rwxr-xr-xindra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl34
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl19
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl19
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/transportF.glsl26
-rw-r--r--indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl21
-rw-r--r--indra/newview/app_settings/shaders/class2/effects/blurF.glsl31
-rw-r--r--indra/newview/app_settings/shaders/class2/effects/blurV.glsl35
-rw-r--r--indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl31
-rw-r--r--indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class2/effects/extractF.glsl22
-rw-r--r--indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl42
-rw-r--r--indra/newview/app_settings/shaders/class2/effects/simpleF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class2/environment/terrainF.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class2/environment/terrainV.glsl52
-rwxr-xr-xindra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl39
-rw-r--r--indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl88
-rw-r--r--indra/newview/app_settings/shaders/class2/environment/waterF.glsl223
-rw-r--r--indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl54
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/lightF.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl23
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl30
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl21
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl29
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl27
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/lightV.glsl128
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl21
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl34
-rwxr-xr-xindra/newview/app_settings/shaders/class2/objects/shinyV.glsl31
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl24
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl137
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl34
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl60
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl76
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl163
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl24
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/skyF.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/skyV.glsl138
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/transportF.glsl35
-rw-r--r--indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl112
-rw-r--r--indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl41
-rw-r--r--indra/newview/app_settings/shaders/shader_heirarchy.txt176
-rw-r--r--indra/newview/app_settings/ultra_graphics.xml39
-rw-r--r--indra/newview/app_settings/windlight/clouds2.tgabin0 -> 262935 bytes
-rw-r--r--indra/newview/app_settings/windlight/days/Default.xml36
-rw-r--r--indra/newview/app_settings/windlight/postprocesseffects.xml2
-rw-r--r--indra/newview/app_settings/windlight/skies/A%2D12AM.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/A%2D12PM.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/A%2D3AM.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/A%2D3PM.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/A%2D6AM.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/A%2D6PM.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/A%2D9AM.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/A%2D9PM.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Barcelona.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Blizzard.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Blue%20Midday.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Default.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Fine%20Day.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Foggy.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Funky%20Funky.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Gelatto.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Ghost.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Midday%201.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Midday%202.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Midday%203.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Midday%204.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Night.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Pirate.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Purple.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml141
-rw-r--r--indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml141
-rw-r--r--indra/newview/app_settings/windlight/water/Default.xml43
-rw-r--r--indra/newview/app_settings/windlight/water/Glassy.xml43
-rw-r--r--indra/newview/app_settings/windlight/water/Murky.xml43
-rw-r--r--indra/newview/app_settings/windlight/water/Pond.xml43
-rw-r--r--indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml43
-rw-r--r--indra/newview/app_settings/windlight/water/Second%20Plague.xml43
-rw-r--r--indra/newview/app_settings/windlight/water/Valdez.xml43
-rw-r--r--indra/newview/featuretable.txt338
-rw-r--r--indra/newview/featuretable_linux.txt337
-rw-r--r--indra/newview/featuretable_mac.txt325
-rw-r--r--indra/newview/featuretable_solaris.txt2
-rw-r--r--indra/newview/gpu_table.txt314
-rw-r--r--indra/newview/installers/windows/installer_template.nsi1894
-rw-r--r--indra/newview/licenses-linux.txt43
-rw-r--r--indra/newview/licenses-mac.txt43
-rw-r--r--indra/newview/licenses-solaris.txt43
-rw-r--r--indra/newview/licenses-win32.txt45
-rwxr-xr-xindra/newview/linux_tools/wrapper.sh4
-rw-r--r--indra/newview/llagent.cpp121
-rw-r--r--indra/newview/llagent.h1
-rw-r--r--indra/newview/llappviewer.cpp170
-rw-r--r--indra/newview/llbox.cpp28
-rw-r--r--indra/newview/llcallingcard.cpp6
-rw-r--r--indra/newview/llcloud.cpp35
-rw-r--r--indra/newview/llcloud.h1
-rw-r--r--indra/newview/llcolorswatch.cpp11
-rw-r--r--indra/newview/lldrawable.cpp359
-rw-r--r--indra/newview/lldrawable.h28
-rw-r--r--indra/newview/lldrawpool.cpp240
-rw-r--r--indra/newview/lldrawpool.h33
-rw-r--r--indra/newview/lldrawpoolalpha.cpp288
-rw-r--r--indra/newview/lldrawpoolalpha.h18
-rw-r--r--indra/newview/lldrawpoolavatar.cpp309
-rw-r--r--indra/newview/lldrawpoolavatar.h6
-rw-r--r--indra/newview/lldrawpoolbump.cpp530
-rw-r--r--indra/newview/lldrawpoolbump.h40
-rw-r--r--indra/newview/lldrawpoolclouds.h1
-rw-r--r--indra/newview/lldrawpoolground.cpp14
-rw-r--r--indra/newview/lldrawpoolground.h1
-rw-r--r--indra/newview/lldrawpoolsimple.cpp165
-rw-r--r--indra/newview/lldrawpoolsimple.h3
-rw-r--r--indra/newview/lldrawpoolsky.cpp58
-rw-r--r--indra/newview/lldrawpoolsky.h4
-rw-r--r--indra/newview/lldrawpoolterrain.cpp274
-rw-r--r--indra/newview/lldrawpoolterrain.h6
-rw-r--r--indra/newview/lldrawpooltree.cpp112
-rw-r--r--indra/newview/lldrawpooltree.h3
-rw-r--r--indra/newview/lldrawpoolwater.cpp393
-rw-r--r--indra/newview/lldrawpoolwater.h14
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp343
-rw-r--r--indra/newview/lldrawpoolwlsky.h84
-rw-r--r--indra/newview/lldynamictexture.cpp14
-rw-r--r--indra/newview/llface.cpp587
-rw-r--r--indra/newview/llface.h92
-rw-r--r--indra/newview/llface.inl81
-rw-r--r--indra/newview/llfasttimerview.cpp175
-rw-r--r--indra/newview/llfasttimerview.h1
-rw-r--r--indra/newview/llfeaturemanager.cpp338
-rw-r--r--indra/newview/llfeaturemanager.h56
-rw-r--r--indra/newview/llflexibleobject.cpp78
-rw-r--r--indra/newview/llflexibleobject.h3
-rw-r--r--indra/newview/llfloateranimpreview.cpp38
-rw-r--r--indra/newview/llfloaterauction.cpp2
-rw-r--r--indra/newview/llfloatercolorpicker.cpp65
-rw-r--r--indra/newview/llfloatercolorpicker.h2
-rw-r--r--indra/newview/llfloaterdaycycle.cpp612
-rw-r--r--indra/newview/llfloaterdaycycle.h146
-rw-r--r--indra/newview/llfloaterenvsettings.cpp384
-rw-r--r--indra/newview/llfloaterenvsettings.h106
-rw-r--r--indra/newview/llfloaterhardwaresettings.cpp207
-rw-r--r--indra/newview/llfloaterhardwaresettings.h102
-rw-r--r--indra/newview/llfloaterimagepreview.cpp130
-rw-r--r--indra/newview/llfloaterpostprocess.cpp273
-rw-r--r--indra/newview/llfloaterpostprocess.h90
-rw-r--r--indra/newview/llfloaterpreference.cpp44
-rw-r--r--indra/newview/llfloaterpreference.h10
-rw-r--r--indra/newview/llfloaterregioninfo.cpp20
-rw-r--r--indra/newview/llfloaterregioninfo.h5
-rw-r--r--indra/newview/llfloaterreporter.cpp2
-rw-r--r--indra/newview/llfloatersnapshot.cpp504
-rw-r--r--indra/newview/llfloaterwater.cpp735
-rw-r--r--indra/newview/llfloaterwater.h133
-rw-r--r--indra/newview/llfloaterwindlight.cpp998
-rw-r--r--indra/newview/llfloaterwindlight.h142
-rw-r--r--indra/newview/llfolderview.cpp4
-rw-r--r--indra/newview/llglsandbox.cpp435
-rw-r--r--indra/newview/llhudeffectbeam.cpp45
-rw-r--r--indra/newview/llhudeffectlookat.cpp20
-rw-r--r--indra/newview/llhudeffectpointat.cpp19
-rw-r--r--indra/newview/llhudeffecttrail.cpp10
-rw-r--r--indra/newview/llhudicon.cpp32
-rw-r--r--indra/newview/llhudmanager.cpp3
-rw-r--r--indra/newview/llhudmanager.h3
-rw-r--r--indra/newview/llhudobject.cpp9
-rw-r--r--indra/newview/llhudrender.cpp10
-rw-r--r--indra/newview/llhudtext.cpp36
-rw-r--r--indra/newview/lljoystickbutton.cpp23
-rw-r--r--indra/newview/llmanip.cpp45
-rw-r--r--indra/newview/llmaniprotate.cpp51
-rw-r--r--indra/newview/llmanipscale.cpp143
-rw-r--r--indra/newview/llmaniptranslate.cpp386
-rw-r--r--indra/newview/llmemoryview.cpp7
-rw-r--r--indra/newview/llnetmap.cpp107
-rw-r--r--indra/newview/lloverlaybar.cpp1
-rw-r--r--indra/newview/llpanelface.cpp65
-rw-r--r--indra/newview/llpanelface.h3
-rw-r--r--indra/newview/llpanelgrouplandmoney.cpp1
-rw-r--r--indra/newview/llpanelobject.cpp15
-rw-r--r--indra/newview/llpanelvolume.cpp13
-rw-r--r--indra/newview/llpreviewanim.cpp27
-rw-r--r--indra/newview/llpreviewanim.h1
-rw-r--r--indra/newview/llpreviewtexture.cpp1
-rw-r--r--indra/newview/llprogressview.cpp5
-rw-r--r--indra/newview/llselectmgr.cpp104
-rw-r--r--indra/newview/llselectmgr.h2
-rw-r--r--indra/newview/llsky.cpp100
-rw-r--r--indra/newview/llsky.h13
-rw-r--r--indra/newview/llspatialpartition.cpp2125
-rw-r--r--indra/newview/llspatialpartition.h213
-rw-r--r--indra/newview/llsprite.cpp10
-rw-r--r--indra/newview/llstartup.cpp8
-rw-r--r--indra/newview/llsurface.cpp77
-rw-r--r--indra/newview/llsurface.h2
-rw-r--r--indra/newview/llsurfacepatch.cpp19
-rw-r--r--indra/newview/lltexlayer.cpp60
-rw-r--r--indra/newview/lltexturectrl.cpp61
-rw-r--r--indra/newview/lltextureview.cpp25
-rw-r--r--indra/newview/lltoolbrush.cpp17
-rw-r--r--indra/newview/lltoolgun.cpp1
-rw-r--r--indra/newview/lltoolmorph.cpp28
-rw-r--r--indra/newview/lltoolselectrect.cpp9
-rw-r--r--indra/newview/lltracker.cpp45
-rw-r--r--indra/newview/llviewercamera.cpp195
-rw-r--r--indra/newview/llviewercamera.h7
-rw-r--r--indra/newview/llviewercontrol.h3
-rw-r--r--indra/newview/llviewerdisplay.cpp594
-rw-r--r--indra/newview/llviewerdisplay.h5
-rw-r--r--indra/newview/llviewerjoint.cpp205
-rw-r--r--indra/newview/llviewerjoint.h1
-rw-r--r--indra/newview/llviewerjointattachment.cpp52
-rw-r--r--indra/newview/llviewerjointattachment.h3
-rw-r--r--indra/newview/llviewerjointmesh.cpp290
-rw-r--r--indra/newview/llviewerjointmesh.h5
-rw-r--r--indra/newview/llviewerjointmesh_sse.cpp2
-rw-r--r--indra/newview/llviewerjointmesh_sse2.cpp2
-rw-r--r--indra/newview/llviewerjointmesh_vec.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp216
-rw-r--r--indra/newview/llviewermenufile.cpp15
-rw-r--r--indra/newview/llviewermessage.cpp1
-rw-r--r--indra/newview/llviewerobject.cpp84
-rw-r--r--indra/newview/llviewerobject.h24
-rw-r--r--indra/newview/llviewerobjectlist.cpp45
-rw-r--r--indra/newview/llviewerobjectlist.h1
-rw-r--r--indra/newview/llviewerparceloverlay.cpp38
-rw-r--r--indra/newview/llviewerpartsim.cpp200
-rw-r--r--indra/newview/llviewerpartsim.h34
-rw-r--r--indra/newview/llviewerpartsource.cpp65
-rw-r--r--indra/newview/llviewerpartsource.h2
-rw-r--r--indra/newview/llviewerregion.cpp37
-rw-r--r--indra/newview/llviewerregion.h27
-rw-r--r--indra/newview/llviewerstats.cpp6
-rw-r--r--indra/newview/llviewerwindow.cpp339
-rw-r--r--indra/newview/llviewerwindow.h6
-rw-r--r--indra/newview/llvoavatar.cpp1008
-rw-r--r--indra/newview/llvoavatar.h56
-rw-r--r--indra/newview/llvoclouds.cpp159
-rw-r--r--indra/newview/llvoclouds.h3
-rw-r--r--indra/newview/llvograss.cpp8
-rw-r--r--indra/newview/llvograss.h2
-rw-r--r--indra/newview/llvoground.cpp3
-rw-r--r--indra/newview/llvoicevisualizer.cpp50
-rw-r--r--indra/newview/llvopartgroup.cpp207
-rw-r--r--indra/newview/llvopartgroup.h5
-rw-r--r--indra/newview/llvosky.cpp1505
-rw-r--r--indra/newview/llvosky.h407
-rw-r--r--indra/newview/llvosurfacepatch.cpp94
-rw-r--r--indra/newview/llvosurfacepatch.h12
-rw-r--r--indra/newview/llvotextbubble.cpp5
-rw-r--r--indra/newview/llvotextbubble.h2
-rw-r--r--indra/newview/llvotree.cpp195
-rw-r--r--indra/newview/llvotree.h4
-rw-r--r--indra/newview/llvovolume.cpp726
-rw-r--r--indra/newview/llvovolume.h31
-rw-r--r--indra/newview/llvowater.cpp84
-rw-r--r--indra/newview/llvowater.h4
-rw-r--r--indra/newview/llvowlsky.cpp821
-rw-r--r--indra/newview/llvowlsky.h110
-rw-r--r--indra/newview/llwaterparammanager.cpp433
-rw-r--r--indra/newview/llwaterparammanager.h401
-rw-r--r--indra/newview/llwaterparamset.cpp233
-rw-r--r--indra/newview/llwaterparamset.h156
-rw-r--r--indra/newview/llwlanimator.cpp168
-rw-r--r--indra/newview/llwlanimator.h76
-rw-r--r--indra/newview/llwldaycycle.cpp233
-rw-r--r--indra/newview/llwldaycycle.h105
-rw-r--r--indra/newview/llwlparammanager.cpp572
-rw-r--r--indra/newview/llwlparammanager.h292
-rw-r--r--indra/newview/llwlparamset.cpp403
-rw-r--r--indra/newview/llwlparamset.h252
-rw-r--r--indra/newview/llworld.cpp87
-rw-r--r--indra/newview/llworld.h3
-rw-r--r--indra/newview/llworldmapview.cpp212
-rw-r--r--indra/newview/pipeline.cpp2886
-rw-r--r--indra/newview/pipeline.h201
-rwxr-xr-xindra/newview/viewer_manifest.py2
399 files changed, 32943 insertions, 13019 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt
index e3f12fe439..c57a2792d9 100644
--- a/doc/contributions.txt
+++ b/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
@@ -44,9 +47,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
@@ -172,6 +178,7 @@ McCabe Maxsted
Michelle2 Zenovka
VWR-2652
VWR-2834
+ VWR-3749
Mm Alder
VWR-3777
Mr Greggan
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index 76fa0b93ee..1d00f18f2d 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -2030,64 +2030,6 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
}
}
-
-//-----------------------------------------------------------------------------
-// writeCAL3D()
-//-----------------------------------------------------------------------------
-void LLKeyframeMotion::writeCAL3D(apr_file_t* fp)
-{
-// <ANIMATION VERSION="1000" DURATION="1.03333" NUMTRACKS="58">
-// <TRACK BONEID="0" NUMKEYFRAMES="31">
-// <KEYFRAME TIME="0">
-// <TRANSLATION>0 0 48.8332</TRANSLATION>
-// <ROTATION>0.0512905 0.05657 0.66973 0.738668</ROTATION>
-// </KEYFRAME>
-// </TRACK>
-// </ANIMATION>
-
- apr_file_printf(fp, "<ANIMATION VERSION=\"1000\" DURATION=\"%.5f\" NUMTRACKS=\"%d\">\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, " <TRACK BONEID=\"%d\" NUMKEYFRAMES=\"%d\">\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, " <KEYFRAME TIME=\"%0.3f\">\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, " <TRANSLATION>%0.4f %0.4f %0.4f</TRANSLATION>\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, " <TRANSLATION>%0.4f %0.4f %0.4f</TRANSLATION>\n", nominal_pos.mV[VX], nominal_pos.mV[VY], nominal_pos.mV[VZ]);
- }
-
- LLQuaternion rot_val = ~rot_keyp->mRotation;
- apr_file_printf(fp, " <ROTATION>%0.4f %0.4f %0.4f %0.4f</ROTATION>\n", rot_val.mQ[VX], rot_val.mQ[VY], rot_val.mQ[VZ], rot_val.mQ[VW]);
- apr_file_printf(fp, " </KEYFRAME>\n");
- }
- apr_file_printf(fp, " </TRACK>\n");
- }
- apr_file_printf(fp, "</ANIMATION>\n");
-}
-
//--------------------------------------------------------------------
// LLKeyframeDataCache::dumpDiagInfo()
//--------------------------------------------------------------------
diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h
index 9cea7f3a59..8d6ebbf4b7 100644
--- a/indra/llcharacter/llkeyframemotion.h
+++ b/indra/llcharacter/llkeyframemotion.h
@@ -158,7 +158,6 @@ public:
U32 getFileSize();
BOOL serialize(LLDataPacker& dp) const;
BOOL deserialize(LLDataPacker& dp);
- void writeCAL3D(apr_file_t* fp);
BOOL isLoaded() { return mJointMotionList != NULL; }
diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp
index 603ee6a27b..fff19dbefe 100644
--- a/indra/llcharacter/llmotioncontroller.cpp
+++ b/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/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h
index 63c9219fbf..effea0940a 100644
--- a/indra/llcharacter/llmotioncontroller.h
+++ b/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/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp
index 557bbd2d56..2120cb223e 100644
--- a/indra/llcharacter/llpose.cpp
+++ b/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/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 3c7232daa8..e92f04441c 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/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/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index 241b13f84f..2a18e5c64c 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -286,6 +286,7 @@ llofstream::llofstream(const char *_Filename,
llofstream::~llofstream()
{ // destroy the object
+ close();
delete _Filebuffer;
}
diff --git a/indra/llcommon/llkeythrottle.h b/indra/llcommon/llkeythrottle.h
index 775ecdfc99..d831eadd59 100644
--- a/indra/llcommon/llkeythrottle.h
+++ b/indra/llcommon/llkeythrottle.h
@@ -192,10 +192,7 @@ public:
{
noteAction(id);
typename LLKeyThrottleImpl<T>::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/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp
index 2ec9ba8503..3b9ba9d0f7 100644
--- a/indra/llmath/llcamera.cpp
+++ b/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 &center, const LLVector3& radius)
+S32 LLCamera::AABBInFrustum(const LLVector3 &center, const LLVector3& radius)
{
static const LLVector3 scaler[] = {
LLVector3(-1,-1,-1),
@@ -166,10 +180,56 @@ int LLCamera::AABBInFrustum(const LLVector3 &center, 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 &center, 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/indra/llmath/llcamera.h b/indra/llmath/llcamera.h
index 67ffb2e450..bd894753f8 100644
--- a/indra/llmath/llcamera.h
+++ b/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 &center, const F32 radius) const { return sphereInFrustum(center, radius); }
S32 AABBInFrustum(const LLVector3 &center, const LLVector3& radius);
+ S32 AABBInFrustumNoFarClip(const LLVector3 &center, const LLVector3& radius);
+
//does a quick 'n dirty sphere-sphere check
S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius);
diff --git a/indra/llmath/llcoordframe.cpp b/indra/llmath/llcoordframe.cpp
index 70d4646264..f108454731 100644
--- a/indra/llmath/llcoordframe.cpp
+++ b/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/indra/llmath/llmath.h b/indra/llmath/llmath.h
index f1b223f559..6df241d3ab 100644
--- a/indra/llmath/llmath.h
+++ b/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/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index def6cb415a..fab8070259 100644
--- a/indra/llmath/lloctree.h
+++ b/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 T> class LLOctreeState;
template <class T> class LLOctreeNode;
template <class T>
@@ -64,15 +63,27 @@ public:
virtual void handleChildRemoval(const oct_node* parent, const oct_node* child) = 0;
};
+template <class T>
+class LLOctreeTraveler : public LLTreeTraveler<T>
+{
+public:
+ virtual void traverse(const LLTreeNode<T>* node);
+ virtual void visit(const LLTreeNode<T>* state) { }
+ virtual void visit(const LLOctreeNode<T>* branch) = 0;
+};
template <class T>
class LLOctreeNode : public LLTreeNode<T>
{
public:
-
+ typedef LLOctreeTraveler<T> oct_traveler;
+ typedef LLTreeTraveler<T> tree_traveler;
+ typedef typename std::set<LLPointer<T> > element_list;
+ typedef typename std::set<LLPointer<T> >::iterator element_iter;
+ typedef typename std::set<LLPointer<T> >::const_iterator const_element_iter;
+ typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
+ typedef typename std::vector<LLOctreeNode<T>* > child_list;
typedef LLTreeNode<T> BaseType;
- typedef LLTreeState<T> tree_state;
- typedef LLOctreeState<T> oct_state;
typedef LLOctreeNode<T> oct_node;
typedef LLOctreeListener<T> 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 &center, LLVector3d &size, T* data)
+ static void pushCenter(LLVector3d &center, 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 T>
-class LLOctreeTraveler : public LLTreeTraveler<T>
-{
-public:
- virtual void traverse(const LLTreeNode<T>* node);
- virtual void visit(const LLTreeState<T>* state) { }
- virtual void visit(const LLOctreeState<T>* branch) = 0;
-};
-
-//will pass requests to a child, might make a new child
-template <class T>
-class LLOctreeState : public LLTreeState<T>
-{
-public:
- typedef LLTreeState<T> BaseType;
- typedef LLOctreeTraveler<T> oct_traveler;
- typedef LLOctreeNode<T> oct_node;
- typedef LLOctreeListener<T> oct_listener;
- typedef LLTreeTraveler<T> tree_traveler;
- typedef typename std::set<LLPointer<T> > element_list;
- typedef typename std::set<LLPointer<T> >::iterator element_iter;
- typedef typename std::set<LLPointer<T> >::const_iterator const_element_iter;
- typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
- typedef typename std::vector<LLOctreeNode<T>* > 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<T>* node = getOctNode();
+ LLOctreeNode<T>* 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<T>* node = getOctNode();
- LLOctreeNode<T>* parent = node->getOctParent();
+ LLOctreeNode<T>* 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<T>::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<T>* newstate = new LLOctreeState<T>();
- child = new LLOctreeNode<T>(center, size, newstate, node);
+ child = new LLOctreeNode<T>(center, size, this);
addChild(child);
-
+
child->insert(data);
}
}
else
{
//it's not in here, give it to the root
- LLOctreeNode<T>* 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<T>* 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 T>
-class LLOctreeRoot : public LLOctreeState<T>
+class LLOctreeRoot : public LLOctreeNode<T>
{
public:
- typedef LLOctreeState<T> BaseType;
+ typedef LLOctreeNode<T> BaseType;
typedef LLOctreeNode<T> 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<T>* 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<T>::insert(data);
+ oct_node* node = getNodeAt(data);
+ if (node == this)
+ {
+ LLOctreeNode<T>::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<T>::pushCenter(center, size, data);
- node->setCenter(center);
- node->setSize(size*2);
- node->updateMinMax();
+ this->setCenter(center);
+ this->setSize(size*2);
+ this->updateMinMax();
}
- LLOctreeState<T>::insert(data);
+ LLOctreeNode<T>::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<T>::pushCenter(newcenter, size, data);
- node->setCenter(newcenter);
- node->setSize(size*2);
- node->updateMinMax();
-
- //copy our children to a new branch
- LLOctreeState<T>* newstate = new LLOctreeState<T>();
- LLOctreeNode<T>* newnode = new LLOctreeNode<T>(center, size, newstate, node);
-
- for (U32 i = 0; i < this->getChildCount(); i++)
+ while (!(this->getSize().mdV[0] > data->getBinRadius() && isInside(data->getPositionGroup())))
{
- LLOctreeNode<T>* 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<T>::pushCenter(newcenter, size, data);
+ this->setCenter(newcenter);
+ this->setSize(size*2);
+ this->updateMinMax();
+
+ //copy our children to a new branch
+ LLOctreeNode<T>* newnode = new LLOctreeNode<T>(center, size, this);
+
+ for (U32 i = 0; i < this->getChildCount(); i++)
+ {
+ LLOctreeNode<T>* 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 <class T>
-void LLOctreeTraveler<T>::traverse(const LLTreeNode<T>* node)
+void LLOctreeTraveler<T>::traverse(const LLTreeNode<T>* tree_node)
{
- const LLOctreeState<T>* state = (const LLOctreeState<T>*) node->getState();
- state->accept(this);
- for (U32 i = 0; i < state->getChildCount(); i++)
+ const LLOctreeNode<T>* node = (const LLOctreeNode<T>*) tree_node;
+ node->accept(this);
+ for (U32 i = 0; i < node->getChildCount(); i++)
{
- traverse(state->getChild(i));
+ traverse(node->getChild(i));
}
}
diff --git a/indra/llmath/lltreenode.h b/indra/llmath/lltreenode.h
index 6cafee01d4..6685915bcf 100644
--- a/indra/llmath/lltreenode.h
+++ b/indra/llmath/lltreenode.h
@@ -40,23 +40,6 @@ template <class T> class LLTreeTraveler;
template <class T> class LLTreeListener;
template <class T>
-class LLTreeState
-{
-public:
- LLTreeState(LLTreeNode<T>* node) { setNode(node); }
- virtual ~LLTreeState() { };
- virtual bool insert(T* data) = 0;
- virtual bool remove(T* data) = 0;
- virtual void setNode(LLTreeNode<T>* node);
- virtual const LLTreeNode<T>* getNode() const { return mNode; }
- virtual LLTreeNode<T>* getNode() { return mNode; }
- virtual void accept(LLTreeTraveler<T>* traveler) const = 0;
- virtual LLTreeListener<T>* getListener(U32 index) const;
-private:
- LLTreeNode<T>* mNode;
-};
-
-template <class T>
class LLTreeListener: public LLRefCount
{
public:
@@ -70,19 +53,14 @@ template <class T>
class LLTreeNode
{
public:
- LLTreeNode(LLTreeState<T>* state) { setState(state); }
virtual ~LLTreeNode();
- LLTreeState<T>* getState() { return mState; }
- const LLTreeState<T>* getState() const { return mState; }
-
- void setState(LLTreeState<T>* state);
- void insert(T* data);
- bool remove(T* data);
- void notifyRemoval(T* data);
- inline U32 getListenerCount() { return mListeners.size(); }
- inline LLTreeListener<T>* getListener(U32 index) const { return mListeners[index]; }
- inline void addListener(LLTreeListener<T>* 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<T>* getListener(U32 index) const { return mListeners[index]; }
+ virtual void addListener(LLTreeListener<T>* listener) { mListeners.push_back(listener); }
protected:
void destroyListeners()
@@ -94,7 +72,6 @@ protected:
mListeners.clear();
}
- LLTreeState<T>* mState;
public:
std::vector<LLPointer<LLTreeListener<T> > > mListeners;
};
@@ -105,7 +82,7 @@ class LLTreeTraveler
public:
virtual ~LLTreeTraveler() { };
virtual void traverse(const LLTreeNode<T>* node) = 0;
- virtual void visit(const LLTreeState<T>* state) = 0;
+ virtual void visit(const LLTreeNode<T>* node) = 0;
};
template <class T>
@@ -115,25 +92,19 @@ LLTreeNode<T>::~LLTreeNode()
};
template <class T>
-void LLTreeNode<T>::insert(T* data)
+bool LLTreeNode<T>::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 <class T>
bool LLTreeNode<T>::remove(T* data)
{
- if (mState->remove(data))
- {
- return true;
- }
- return false;
+ return true;
};
template <class T>
@@ -145,38 +116,4 @@ void LLTreeNode<T>::notifyRemoval(T* data)
}
}
-template <class T>
-void LLTreeNode<T>::setState(LLTreeState<T>* 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 <class T>
-void LLTreeState<T>::setNode(LLTreeNode<T>* node)
-{
- mNode = node;
- if (node && node->getState() != this)
- {
- node->setState(this);
- }
-};
-
-template <class T>
-LLTreeListener<T>* LLTreeState<T>::getListener(U32 index) const
-{
- return mNode->getListener(index);
-}
-
#endif
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 037357c92e..ab2eef0ee9 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -1639,12 +1639,27 @@ LLVolume::LLVolume(const LLVolumeParams &params, 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);
}
}
}
@@ -3967,18 +3981,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 +4015,7 @@ void LerpPlanarVertex(LLVolumeFace::VertexData& v0,
vout.mBinormal = v0.mBinormal;
}
-BOOL LLVolumeFace::createUnCutCubeCap()
+BOOL LLVolumeFace::createUnCutCubeCap(BOOL partial_build)
{
const std::vector<LLVolume::Point>& mesh = mVolumep->getMesh();
const std::vector<LLVector3>& profile = mVolumep->getProfile().mProfile;
@@ -4055,6 +4070,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<grid_size+1;gx++){
@@ -4082,22 +4103,25 @@ BOOL LLVolumeFace::createUnCutCubeCap()
mCenter = (min + max) * 0.5f;
- int idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0};
- for(int gx = 0;gx<grid_size;gx++){
- for(int gy = 0;gy<grid_size;gy++){
- if (mTypeMask & TOP_MASK){
- for(int i=5;i>=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<grid_size;gx++){
+ for(int gy = 0;gy<grid_size;gy++){
+ if (mTypeMask & TOP_MASK){
+ for(int i=5;i>=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 +4130,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 +4142,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 +4232,10 @@ BOOL LLVolumeFace::createCap()
{
mVertices.push_back(vd);
num_vertices++;
- vector_append(mIndices, 3);
+ if (!partial_build)
+ {
+ vector_append(mIndices, 3);
+ }
}
@@ -4213,6 +4245,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 +4519,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 +4578,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 +4696,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 +4763,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 +4904,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/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 3dadc56261..3e61947947 100644
--- a/indra/llmath/llvolume.h
+++ b/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<VertexData> mVertices;
- std::vector<S32> mIndices;
+ std::vector<U16> mIndices;
std::vector<S32> mEdge;
LLVolume *mVolumep; // Deliberately NOT reference counted - djs 11/20/03 - otherwise would make an annoying circular reference
@@ -811,9 +813,9 @@ public:
LLStrider<LLColor4U> &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<Point>& 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);
diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp
index eae6ab7f4a..945d74f7c1 100644
--- a/indra/llmath/llvolumemgr.cpp
+++ b/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/indra/llmath/llvolumemgr.h b/indra/llmath/llvolumemgr.h
index 7aa0a3f3bf..3d7b663670 100644
--- a/indra/llmath/llvolumemgr.h
+++ b/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/indra/llmath/v3color.cpp b/indra/llmath/v3color.cpp
index 462075c763..8a49be5615 100644
--- a/indra/llmath/v3color.cpp
+++ b/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/indra/llmath/v3color.h b/indra/llmath/v3color.h
index d09af7a8c4..56820148d5 100644
--- a/indra/llmath/v3color.h
+++ b/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/indra/llmath/v4color.cpp b/indra/llmath/v4color.cpp
index 4ce8e10527..21166472e4 100644
--- a/indra/llmath/v4color.cpp
+++ b/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/indra/llmath/v4color.h b/indra/llmath/v4color.h
index 0514870ef6..bd990444b5 100644
--- a/indra/llmath/v4color.h
+++ b/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/indra/llmath/v4math.h b/indra/llmath/v4math.h
index 57dcad35fe..34b5f9e33c 100644
--- a/indra/llmath/v4math.h
+++ b/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/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index e6eee9bf13..837f8ef361 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -389,4 +389,3 @@ S32 LLTextureEntry::setGlow(F32 glow)
}
return 0;
}
-
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index dd67dbc379..2e767ebb9c 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/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/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 748e405065..2a8424a09b 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/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();
}
@@ -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/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index cbfa3c2202..20cf4ae10f 100644
--- a/indra/llrender/llimagegl.h
+++ b/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/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
new file mode 100644
index 0000000000..c082b93164
--- /dev/null
+++ b/indra/llrender/llrendertarget.cpp
@@ -0,0 +1,185 @@
+/**
+ * @file llrendertarget.cpp
+ * @brief LLRenderTarget implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
new file mode 100644
index 0000000000..0c0eab2b10
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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);
+ ... <issue drawing commands> ...
+ target.flush();
+
+ ...
+
+ //use target as a texture
+ target.bindTexture();
+ ... <issue drawing commands> ...
+
+*/
+
+
+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/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 2a54fca250..9303e00228 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -31,6 +31,8 @@
#include "linden_common.h"
+#include <boost/static_assert.hpp>
+
#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<U32> 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<TYPE_MAX; i++)
{
U32 mask = 1<<i;
if (typemask & mask)
{
- mOffsets[i] = stride;
+ if (offsets)
+ {
+ offsets[i] = stride;
+ }
stride += sTypeOffsets[i];
}
}
- mTypeMask = typemask;
- mStride = stride;
- sCount++;
+
+ return stride;
}
// protected, use unref()
@@ -206,23 +200,80 @@ LLVertexBuffer::~LLVertexBuffer()
destroyGLBuffer();
destroyGLIndices();
sCount--;
-
- if (mLocked)
- {
- //pull off of locked list
- for (buffer_list_t::iterator i = sLockedList.begin(); i != sLockedList.end(); ++i)
- {
- if (*i == this)
- {
- sLockedList.erase(i);
- break;
- }
- }
- }
};
//----------------------------------------------------------------------------
+void LLVertexBuffer::genBuffer()
+{
+ if (mUsage == GL_STREAM_DRAW_ARB)
+ {
+ mGLBuffer = sStreamVBOPool.allocate();
+ }
+ else if (mUsage == GL_DYNAMIC_DRAW_ARB)
+ {
+ mGLBuffer = sDynamicVBOPool.allocate();
+ }
+ else
+ {
+ BOOST_STATIC_ASSERT(sizeof(mGLBuffer) == sizeof(GLuint));
+ glGenBuffersARB(1, (GLuint*)&mGLBuffer);
+ }
+ sGLCount++;
+}
+
+void LLVertexBuffer::genIndices()
+{
+ if (mUsage == GL_STREAM_DRAW_ARB)
+ {
+ mGLIndices = sStreamIBOPool.allocate();
+ }
+ else if (mUsage == GL_DYNAMIC_DRAW_ARB)
+ {
+ mGLIndices = sDynamicIBOPool.allocate();
+ }
+ else
+ {
+ BOOST_STATIC_ASSERT(sizeof(mGLBuffer) == sizeof(GLuint));
+ glGenBuffersARB(1, (GLuint*)&mGLIndices);
+ }
+ sGLCount++;
+}
+
+void LLVertexBuffer::releaseBuffer()
+{
+ if (mUsage == GL_STREAM_DRAW_ARB)
+ {
+ sStreamVBOPool.release(mGLBuffer);
+ }
+ else if (mUsage == GL_DYNAMIC_DRAW_ARB)
+ {
+ sDynamicVBOPool.release(mGLBuffer);
+ }
+ else
+ {
+ sDeleteList.push_back(mGLBuffer);
+ }
+ sGLCount--;
+}
+
+void LLVertexBuffer::releaseIndices()
+{
+ if (mUsage == GL_STREAM_DRAW_ARB)
+ {
+ sStreamIBOPool.release(mGLIndices);
+ }
+ else if (mUsage == GL_DYNAMIC_DRAW_ARB)
+ {
+ sDynamicIBOPool.release(mGLIndices);
+ }
+ else
+ {
+ sDeleteList.push_back(mGLIndices);
+ }
+ sGLCount--;
+}
+
void LLVertexBuffer::createGLBuffer()
{
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
@@ -238,20 +289,20 @@ void LLVertexBuffer::createGLBuffer()
return;
}
- mMappedData = new U8[size];
- memset(mMappedData, 0, size);
mEmpty = TRUE;
if (useVBOs())
{
- glGenBuffersARB(1, (GLuint*) &mGLBuffer);
+ mMappedData = NULL;
+ genBuffer();
mResized = TRUE;
- sGLCount++;
}
else
{
static int gl_buffer_idx = 0;
mGLBuffer = ++gl_buffer_idx;
+ mMappedData = new U8[size];
+ memset(mMappedData, 0, size);
}
}
@@ -270,18 +321,18 @@ void LLVertexBuffer::createGLIndices()
return;
}
- mMappedIndexData = new U8[size];
- memset(mMappedIndexData, 0, size);
mEmpty = TRUE;
if (useVBOs())
{
- glGenBuffersARB(1, (GLuint*) &mGLIndices);
+ mMappedIndexData = NULL;
+ genIndices();
mResized = TRUE;
- sGLCount++;
}
else
{
+ mMappedIndexData = new U8[size];
+ memset(mMappedIndexData, 0, size);
static int gl_buffer_idx = 0;
mGLIndices = ++gl_buffer_idx;
}
@@ -294,12 +345,19 @@ void LLVertexBuffer::destroyGLBuffer()
{
if (useVBOs())
{
- sDeleteList.push_back(mGLBuffer);
+ if (mMappedData || mMappedIndexData)
+ {
+ llerrs << "Vertex buffer destroyed while mapped!" << llendl;
+ }
+ releaseBuffer();
+ }
+ else
+ {
+ delete [] mMappedData;
+ mMappedData = NULL;
+ mEmpty = TRUE;
}
-
- delete [] mMappedData;
- mMappedData = NULL;
- mEmpty = TRUE;
+
sAllocatedBytes -= getSize();
}
@@ -313,12 +371,19 @@ void LLVertexBuffer::destroyGLIndices()
{
if (useVBOs())
{
- sDeleteList.push_back(mGLIndices);
+ if (mMappedData || mMappedIndexData)
+ {
+ llerrs << "Vertex buffer destroyed while mapped." << llendl;
+ }
+ releaseIndices();
+ }
+ else
+ {
+ delete [] mMappedIndexData;
+ mMappedIndexData = NULL;
+ mEmpty = TRUE;
}
-
- delete [] mMappedIndexData;
- mMappedIndexData = NULL;
- mEmpty = TRUE;
+
sAllocatedBytes -= getIndicesSize();
}
@@ -328,6 +393,15 @@ void LLVertexBuffer::destroyGLIndices()
void LLVertexBuffer::updateNumVerts(S32 nverts)
{
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
+
+ if (nverts >= 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<DirtyRegion>::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<DirtyRegion>::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<LLVector3>& strider, S32 index)
{
return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index);
}
-bool LLVertexBuffer::getIndexStrider(LLStrider<U32>& strider, S32 index)
+bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index)
{
- return VertexBufferStrider<U32,TYPE_INDEX>::get(*this, strider, index);
+ return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index);
}
bool LLVertexBuffer::getTexCoordStrider(LLStrider<LLVector2>& 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/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index cf36eb664c..e2a4196b0e 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/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<LLVector3>& strider, S32 index=0);
- bool getIndexStrider(LLStrider<U32>& strider, S32 index=0);
+ bool getIndexStrider(LLStrider<U16>& strider, S32 index=0);
bool getTexCoordStrider(LLStrider<LLVector2>& strider, S32 index=0);
bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0);
bool getNormalStrider(LLStrider<LLVector3>& 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<U32> sDeleteList;
typedef std::list<LLVertexBuffer*> 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/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 435e1d1701..8132396cb5 100644
--- a/indra/llui/llbutton.cpp
+++ b/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
@@ -601,9 +602,9 @@ void LLButton::draw()
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
@@ -612,9 +613,9 @@ void LLButton::draw()
mImagep->draw(0, 0, getRect().getWidth(), getRect().getHeight(), getEnabled() ? mImageColor : mDisabledImageColor );
if (mCurGlowStrength > 0.01f)
{
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
mImagep->drawSolid(0, 0, getRect().getWidth(), getRect().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_MINUS_SRC_ALPHA);
}
}
else
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index 536e9a6dc6..0b3156fa1e 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/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);
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 68719bea40..fed39b7917 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2123,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();
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 4e94aff7a5..00b4c37bb0 100644
--- a/indra/llui/llmenugl.cpp
+++ b/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"
@@ -470,7 +471,7 @@ void LLMenuItemGL::draw( void )
// let disabled items be highlighted, just don't draw them as such
if( getEnabled() && getHighlight() && !mBriefItem)
{
- glColor4fv( sHighlightBackground.mV );
+ gGL.color4fv( sHighlightBackground.mV );
gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 );
}
@@ -580,7 +581,7 @@ LLMenuItemSeparatorGL::LLMenuItemSeparatorGL( const LLString &name ) :
void LLMenuItemSeparatorGL::draw( void )
{
- glColor4fv( getDisabledColor().mV );
+ gGL.color4fv( getDisabledColor().mV );
const S32 y = getRect().getHeight() / 2;
const S32 PAD = 6;
gl_line_2d( PAD, y, getRect().getWidth() - PAD, y );
@@ -701,17 +702,17 @@ void LLMenuItemTearOffGL::draw()
// disabled items can be highlighted, but shouldn't render as such
if( getEnabled() && getHighlight() && !isBriefItem())
{
- glColor4fv( getHighlightBGColor().mV );
+ gGL.color4fv( getHighlightBGColor().mV );
gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 );
}
if (getEnabled())
{
- glColor4fv( getEnabledColor().mV );
+ gGL.color4fv( getEnabledColor().mV );
}
else
{
- glColor4fv( getDisabledColor().mV );
+ gGL.color4fv( getDisabledColor().mV );
}
const S32 y = getRect().getHeight() / 3;
const S32 PAD = 6;
@@ -1638,7 +1639,7 @@ void LLMenuItemBranchDownGL::draw( void )
if( getHighlight() )
{
- glColor4fv( getHighlightBGColor().mV );
+ gGL.color4fv( getHighlightBGColor().mV );
gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0 );
}
@@ -2949,7 +2950,7 @@ void LLMenuGL::draw( void )
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);
}
@@ -3476,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");
@@ -3517,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;
@@ -3541,10 +3542,10 @@ void LLPieMenu::drawBackground(LLMenuItemGL* itemp, LLColor4& color)
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;
@@ -3564,7 +3565,7 @@ void LLPieMenu::drawBackground(LLMenuItemGL* itemp, LLColor4& color)
i++;
}
}
- glPopMatrix();
+ gGL.popMatrix();
}
// virtual
diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp
new file mode 100644
index 0000000000..b4bf3a92d5
--- /dev/null
+++ b/indra/llui/llmultislider.cpp
@@ -0,0 +1,677 @@
+/**
+ * @file llmultisldr.cpp
+ * @brief LLMultiSlider base class
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <sstream>
+
+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<LLString, LLRect>::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<LLString, LLRect>::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<LLString, LLRect>::iterator mIt;
+ std::map<LLString, LLRect>::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<LLImageGL> 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/indra/llui/llmultislider.h b/indra/llui/llmultislider.h
new file mode 100644
index 0000000000..67f627d21c
--- /dev/null
+++ b/indra/llui/llmultislider.h
@@ -0,0 +1,129 @@
+/**
+ * @file llmultislider.h
+ * @brief A simple multislider
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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<LLString, LLRect> 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/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp
new file mode 100644
index 0000000000..6f921a4e5e
--- /dev/null
+++ b/indra/llui/llmultisliderctrl.cpp
@@ -0,0 +1,634 @@
+/**
+ * @file llmultisliderctrl.cpp
+ * @brief LLMultiSliderCtrl base class
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h
new file mode 100644
index 0000000000..028f54ed5e
--- /dev/null
+++ b/indra/llui/llmultisliderctrl.h
@@ -0,0 +1,160 @@
+/**
+ * @file llmultisliderctrl.h
+ * @brief LLMultiSliderCtrl base class
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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/indra/llui/llpanel.h b/indra/llui/llpanel.h
index 6c2df683e4..96417d358b 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -188,7 +188,7 @@ 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);
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index 056a94afb8..c3afb32570 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/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,
@@ -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);
}
}
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index b9d5141eb7..991ba0ed04 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -33,6 +33,7 @@
#include "linden_common.h"
#include "llgl.h"
+#include "llglimmediate.h"
#include "llscrollcontainer.h"
#include "llscrollbar.h"
@@ -459,7 +460,7 @@ void LLScrollableContainerView::draw()
if( mIsOpaque )
{
LLGLSNoTexture no_texture;
- glColor4fv( mBackgroundColor.mV );
+ gGL.color4fv( mBackgroundColor.mV );
gl_rect_2d( mInnerRect );
}
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 4227a34777..35e8f7300b 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -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"
@@ -280,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)
{
@@ -392,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 );
}
@@ -1711,7 +1712,7 @@ void LLScrollListCtrl::draw()
if (mBackgroundVisible)
{
LLGLSNoTexture no_texture;
- glColor4fv( getEnabled() ? mBgWriteableColor.mV : mBgReadOnlyColor.mV );
+ gGL.color4fv( getEnabled() ? mBgWriteableColor.mV : mBgReadOnlyColor.mV );
gl_rect_2d(background);
}
diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h
index 6b1acfeaaa..9ca51120fc 100644
--- a/indra/llui/llslider.h
+++ b/indra/llui/llslider.h
@@ -70,8 +70,8 @@ public:
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 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; }
diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h
index f154c230f4..4f96b0915c 100644
--- a/indra/llui/llsliderctrl.h
+++ b/indra/llui/llsliderctrl.h
@@ -83,9 +83,9 @@ public:
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(); }
@@ -102,7 +102,12 @@ 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) { mSlider->setControlName(control_name, context); }
+ 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);
diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h
index 77a91f80c1..2e1c06d2c4 100644
--- a/indra/llui/llspinctrl.h
+++ b/indra/llui/llspinctrl.h
@@ -86,6 +86,8 @@ public:
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; }
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 4568ebac29..0e64c6df5c 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -40,6 +40,7 @@
#include "llcriticaldamp.h"
#include "lluictrlfactory.h"
#include "lltabcontainervertical.h"
+#include "llglimmediate.h"
const F32 SCROLL_STEP_TIME = 0.4f;
@@ -287,15 +288,15 @@ void LLTabContainer::draw()
if( mIsVertical && has_scroll_arrows )
{
// Redraw the arrows so that they appears on top.
- glPushMatrix();
- glTranslatef((F32)mPrevArrowBtn->getRect().mLeft, (F32)mPrevArrowBtn->getRect().mBottom, 0.f);
+ gGL.pushMatrix();
+ gGL.translatef((F32)mPrevArrowBtn->getRect().mLeft, (F32)mPrevArrowBtn->getRect().mBottom, 0.f);
mPrevArrowBtn->draw();
- glPopMatrix();
+ gGL.popMatrix();
- glPushMatrix();
- glTranslatef((F32)mNextArrowBtn->getRect().mLeft, (F32)mNextArrowBtn->getRect().mBottom, 0.f);
+ gGL.pushMatrix();
+ gGL.translatef((F32)mNextArrowBtn->getRect().mLeft, (F32)mNextArrowBtn->getRect().mBottom, 0.f);
mNextArrowBtn->draw();
- glPopMatrix();
+ gGL.popMatrix();
}
}
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 540283c3fe..c76576895c 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/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"
@@ -424,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)
{
@@ -2601,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 )
{
@@ -2729,7 +2730,7 @@ 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));
@@ -2750,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,
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index ad523db78b..aed7893df7 100644
--- a/indra/llui/llui.cpp
+++ b/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));
}
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index b5b15eef23..e7750087cf 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -224,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,
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 47919408ab..4acfc69f3a 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/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"
@@ -92,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
@@ -206,6 +210,8 @@ LLUICtrlFactory::LLUICtrlFactory()
LLUICtrlCreator<LLSliderCtrl>::registerCreator(LL_SLIDER_CTRL_TAG, this);
LLUICtrlCreator<LLSlider>::registerCreator(LL_SLIDER_TAG, this);
LLUICtrlCreator<LLSlider>::registerCreator(LL_VOLUME_SLIDER_CTRL_TAG, this);
+ LLUICtrlCreator<LLMultiSliderCtrl>::registerCreator(LL_MULTI_SLIDER_CTRL_TAG, this);
+ LLUICtrlCreator<LLMultiSlider>::registerCreator(LL_MULTI_SLIDER_TAG, this);
LLUICtrlCreator<LLSpinCtrl>::registerCreator(LL_SPIN_CTRL_TAG, this);
LLUICtrlCreator<LLTextBox>::registerCreator(LL_TEXT_BOX_TAG, this);
LLUICtrlCreator<LLRadioGroup>::registerCreator(LL_RADIO_GROUP_TAG, this);
@@ -729,6 +735,16 @@ LLScrollingPanelList* LLUICtrlFactory::getScrollingPanelList(const LLPanel* pane
return panelp->getChild<LLScrollingPanelList>(name);
}
+LLMultiSliderCtrl* LLUICtrlFactory::getMultiSliderByName(const LLPanel* panelp, const LLString& name)
+{
+ return panelp->getChild<LLMultiSliderCtrl>(name);
+}
+
+LLMultiSlider* LLUICtrlFactory::getMultiSliderBarByName(const LLPanel* panelp, const LLString& name)
+{
+ return panelp->getChild<LLMultiSlider>(name);
+}
+
LLCtrlListInterface* LLUICtrlFactory::getListInterfaceByName(const LLPanel* panelp, const LLString& name)
{
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 1b90e64322..c2a6cfe510 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -91,6 +91,8 @@ public:
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( const LLPanel* panelp, const LLString& name);
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 56e24085ac..0a37c03ac5 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -37,6 +37,7 @@
#include <cassert>
#include <boost/tokenizer.hpp>
+#include "llglimmediate.h"
#include "llevent.h"
#include "llfontgl.h"
#include "llfocusmgr.h"
@@ -1290,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(),
diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp
index 546eb23c03..301efa3872 100644
--- a/indra/llui/llviewborder.cpp
+++ b/indra/llui/llviewborder.cpp
@@ -30,6 +30,7 @@
#include "linden_common.h"
#include "llviewborder.h"
+#include "llglimmediate.h"
#include "llfocusmgr.h"
LLViewBorder::LLViewBorder( const LLString& name, const LLRect& rect, EBevel bevel, EStyle style, S32 width )
@@ -145,11 +146,11 @@ void LLViewBorder::drawOnePixelLines()
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);
@@ -205,19 +206,19 @@ void LLViewBorder::drawTwoPixelLines()
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);
}
@@ -228,7 +229,7 @@ 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 );
@@ -243,12 +244,12 @@ void LLViewBorder::drawTextures()
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 //
// / \ //
@@ -256,21 +257,21 @@ 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)
diff --git a/indra/llui/llviewborder.h b/indra/llui/llviewborder.h
index e9fd8aa4e1..d35663c857 100644
--- a/indra/llui/llviewborder.h
+++ b/indra/llui/llviewborder.h
@@ -64,6 +64,9 @@ public:
const LLColor4& highlight_light, const LLColor4& highlight_dark );
void setTexture( const class LLUUID &image_id );
+ LLColor4 getHighlightLight() {return mHighlightLight;}
+ LLColor4 getShadowDark() {return mHighlightDark;}
+
EStyle getStyle() const { return mStyle; }
void setKeyboardFocusHighlight( BOOL b ) { mHasKeyboardFocus = b; }
diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp
index 2aff05232e..ab43e6d7d9 100644
--- a/indra/llwindow/lldxhardware.cpp
+++ b/indra/llwindow/lldxhardware.cpp
@@ -35,7 +35,9 @@
#include "linden_common.h"
+#define INITGUID
#include <dxdiag.h>
+#undef INITGUID
#include <boost/tokenizer.hpp>
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index e845afe320..fce0d055e6 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/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];
}
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 0554d3a8db..bc444ae811 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -258,7 +258,7 @@ protected:
ESwapMethod mSwapMethod;
BOOL mHideCursorPermanent;
U32 mFlags;
- F32 mJoyAxis[6];
+ F32 mJoyAxis[8];
U8 mJoyButtonState[16];
U16 mHighSurrogate;
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index fe127b407e..5184a6caec 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/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;
}
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index e7475d577d..686be3385e 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -505,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
@@ -587,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)
{
@@ -629,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)
{
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 3c270d9175..0bba56f74f 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -44,6 +44,7 @@
// Require DirectInput version 8
#define DIRECTINPUT_VERSION 0x0800
+
#include <dinput.h>
@@ -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;
@@ -3199,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/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 9ad99b0201..b21df8981e 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/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/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml
new file mode 100644
index 0000000000..6368f7099e
--- /dev/null
+++ b/indra/newview/app_settings/high_graphics.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<settings version = "101">
+ <!--NO SHADERS-->
+ <RenderAvatarCloth value="FALSE"/>
+ <!--Default for now-->
+ <RenderAvatarLODFactor value="1.0"/>
+ <!--NO SHADERS-->
+ <RenderAvatarVP value="TRUE"/>
+ <!--Short Range-->
+ <RenderFarClip value="128"/>
+ <!--Default for now-->
+ <RenderFlexTimeFactor value="1"/>
+ <!--256... but they don't use this-->
+ <RenderGlowResolutionPow value="9"/>
+ <!--Sun/Moon only-->
+ <RenderLightingDetail value="1"/>
+ <!--Low number-->
+ <RenderMaxPartCount value="4096"/>
+ <!--bump okay-->
+ <RenderObjectBump value="TRUE"/>
+ <!--NO SHADERS-->
+ <RenderReflectionDetail value="2"/>
+ <!--Simple-->
+ <RenderTerrainDetail value="1"/>
+ <!--Default for now-->
+ <RenderTerrainLODFactor value="2"/>
+ <!--Default for now-->
+ <RenderTreeLODFactor value="0.5"/>
+ <!--Try Impostors-->
+ <RenderUseImpostors value="TRUE"/>
+ <!--Default for now-->
+ <RenderVolumeLODFactor value="1.125"/>
+ <!--NO SHADERS-->
+ <RenderWaterReflections value="FALSE"/>
+ <!--NO SHADERS-->
+ <VertexShaderEnable value="TRUE"/>
+ <!--NO SHADERS-->
+ <WindLightUseAtmosShaders value="TRUE"/>
+</settings>
diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml
new file mode 100644
index 0000000000..3f67a70d7a
--- /dev/null
+++ b/indra/newview/app_settings/low_graphics.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<settings version = "101">
+ <!--NO SHADERS-->
+ <RenderAvatarCloth value="FALSE"/>
+ <!--Default for now-->
+ <RenderAvatarLODFactor value="0.5"/>
+ <!--NO SHADERS-->
+ <RenderAvatarVP value="FALSE"/>
+ <!--Short Range-->
+ <RenderFarClip value="64"/>
+ <!--Default for now-->
+ <RenderFlexTimeFactor value="0.5"/>
+ <!--256... but they don't use this-->
+ <RenderGlowResolutionPow value="8"/>
+ <!--Sun/Moon only-->
+ <RenderLightingDetail value="0"/>
+ <!--Low number-->
+ <RenderMaxPartCount value="1024"/>
+ <!--bump okay-->
+ <RenderObjectBump value="FALSE"/>
+ <!--NO SHADERS-->
+ <RenderReflectionDetail value="0"/>
+ <!--Simple-->
+ <RenderTerrainDetail value="0"/>
+ <!--Default for now-->
+ <RenderTerrainLODFactor value="1.0"/>
+ <!--Default for now-->
+ <RenderTreeLODFactor value="0.5"/>
+ <!--Try Impostors-->
+ <RenderUseImpostors value="TRUE"/>
+ <!--Default for now-->
+ <RenderVolumeLODFactor value="1.125"/>
+ <!--NO SHADERS-->
+ <RenderWaterReflections value="FALSE"/>
+ <!--NO SHADERS-->
+ <VertexShaderEnable value="FALSE"/>
+ <!--NO SHADERS-->
+ <WindLightUseAtmosShaders value="FALSE"/>
+</settings>
diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml
new file mode 100644
index 0000000000..12da77da40
--- /dev/null
+++ b/indra/newview/app_settings/mid_graphics.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<settings version = "101">
+ <!--NO SHADERS-->
+ <RenderAvatarCloth value="FALSE"/>
+ <!--Default for now-->
+ <RenderAvatarLODFactor value="0.5"/>
+ <!--NO SHADERS-->
+ <RenderAvatarVP value="TRUE"/>
+ <!--Short Range-->
+ <RenderFarClip value="96"/>
+ <!--Default for now-->
+ <RenderFlexTimeFactor value="1"/>
+ <!--256... but they don't use this-->
+ <RenderGlowResolutionPow value="8"/>
+ <!--Sun/Moon only-->
+ <RenderLightingDetail value="1"/>
+ <!--Low number-->
+ <RenderMaxPartCount value="2048"/>
+ <!--bump okay-->
+ <RenderObjectBump value="TRUE"/>
+ <!--NO SHADERS-->
+ <RenderReflectionDetail value="0"/>
+ <!--Simple-->
+ <RenderTerrainDetail value="1"/>
+ <!--Default for now-->
+ <RenderTerrainLODFactor value="1.0"/>
+ <!--Default for now-->
+ <RenderTreeLODFactor value="0.5"/>
+ <!--Try Impostors-->
+ <RenderUseImpostors value="TRUE"/>
+ <!--Default for now-->
+ <RenderVolumeLODFactor value="1.125"/>
+ <!--NO SHADERS-->
+ <RenderWaterReflections value="FALSE"/>
+ <!--NO SHADERS-->
+ <VertexShaderEnable value="TRUE"/>
+ <!--NO SHADERS-->
+ <WindLightUseAtmosShaders value="FALSE"/>
+</settings>
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl
index 5731add4d5..b6cc7f7712 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
index 1fcc001911..292dbfdab4 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
index 50f9b0192e..ee3410d732 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl
index 5731add4d5..4d93c19441 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
index d436b4e00a..b3c988a924 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl
index b311afb59c..2019300418 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl
index b6dcbe1693..12d8f9d2f9 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
new file mode 100644
index 0000000000..dbdfe1174c
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl
new file mode 100644
index 0000000000..61dfd2f126
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/effects/glowF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl
new file mode 100644
index 0000000000..21c7ad765f
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/effects/glowV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl
new file mode 100644
index 0000000000..13ce7c7854
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
index fde370155d..2278c6916d 100644
--- a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
index 3153a80e93..112d669819 100644
--- a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
new file mode 100644
index 0000000000..e2f68e8826
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
new file mode 100644
index 0000000000..f1740a4dcd
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
index f8b8031ce6..1c14381df9 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
new file mode 100644
index 0000000000..59e44fa871
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
index 873a6fcb34..d332798103 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl
index 1e342fb51b..328c41652d 100644
--- a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
index bb6707b2a9..a9ea6e856a 100644
--- a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
index c169fceb88..9ab986be6d 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
new file mode 100644
index 0000000000..b12cca9126
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
new file mode 100644
index 0000000000..bc795a7513
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
new file mode 100644
index 0000000000..b13088fb19
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl
new file mode 100644
index 0000000000..bbbd9f3dfe
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
new file mode 100644
index 0000000000..3e8fdfb3e4
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
new file mode 100644
index 0000000000..c6f7f8b81b
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
new file mode 100644
index 0000000000..75f61ccdf1
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl
new file mode 100644
index 0000000000..853212923c
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
index e3816318a1..8c2813a859 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
new file mode 100644
index 0000000000..81dff1ef39
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl
new file mode 100644
index 0000000000..218585fb86
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
new file mode 100644
index 0000000000..e5361033ef
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
new file mode 100755
index 0000000000..1b0ffb911a
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl
new file mode 100644
index 0000000000..936c228b4e
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
new file mode 100755
index 0000000000..ba2aa024dc
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
new file mode 100755
index 0000000000..e64ccb844d
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl
new file mode 100755
index 0000000000..fd855aa910
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl
index 694213219e..bdb0b05f97 100644
--- a/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
index 16fba0154b..c2e1ddf734 100644
--- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl
new file mode 100755
index 0000000000..0a2a5f624b
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl
index ce5ab12b74..7dacca4fe1 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
index 2aa3521931..0df89c8fc3 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
+++ b/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/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl
new file mode 100755
index 0000000000..e066b3d02f
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
new file mode 100644
index 0000000000..248c322011
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
new file mode 100644
index 0000000000..c2c39e2e10
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
new file mode 100644
index 0000000000..551b643403
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
new file mode 100644
index 0000000000..c001a4070b
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
new file mode 100644
index 0000000000..1b263b0854
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
new file mode 100644
index 0000000000..c1ffda1596
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
new file mode 100644
index 0000000000..7097906fdd
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
index 7957eddb31..3dd62d2d14 100644
--- a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
+++ b/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/indra/newview/app_settings/shaders/class2/effects/blurF.glsl b/indra/newview/app_settings/shaders/class2/effects/blurF.glsl
new file mode 100644
index 0000000000..94433202af
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/effects/blurV.glsl b/indra/newview/app_settings/shaders/class2/effects/blurV.glsl
new file mode 100644
index 0000000000..ba65b16cc1
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl b/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl
new file mode 100644
index 0000000000..623ef7a81a
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl b/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl
new file mode 100644
index 0000000000..29c2a0948c
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/effects/extractF.glsl b/indra/newview/app_settings/shaders/class2/effects/extractF.glsl
new file mode 100644
index 0000000000..a1583b13eb
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl b/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl
new file mode 100644
index 0000000000..271d5cf8d6
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl b/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl
new file mode 100644
index 0000000000..e55d278b81
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl
new file mode 100644
index 0000000000..4253bc21c3
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl
new file mode 100644
index 0000000000..119d55a2cd
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl
new file mode 100755
index 0000000000..3a98970f8c
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl
new file mode 100644
index 0000000000..1998fea227
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/environment/waterF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
index 11a057b177..8f3d11badc 100644
--- a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl
+++ b/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),
+ 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/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl
new file mode 100644
index 0000000000..522c990cf8
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl
index 6f732ed731..b372d66298 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl
+++ b/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/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl
new file mode 100644
index 0000000000..e6b6d85808
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl
new file mode 100644
index 0000000000..8f408c0436
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl
new file mode 100644
index 0000000000..060ad9cb67
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl
new file mode 100644
index 0000000000..b3927c77a6
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl
new file mode 100644
index 0000000000..f090306be6
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl
new file mode 100644
index 0000000000..c3384ffc5d
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl
index b15960dea2..ff3bcb5cd2 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl
+++ b/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/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl
new file mode 100644
index 0000000000..086954cd47
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
new file mode 100644
index 0000000000..edd1a8a946
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
new file mode 100644
index 0000000000..f4c59734a4
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl
new file mode 100755
index 0000000000..0d52f32a2e
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
new file mode 100644
index 0000000000..92c0664a5e
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
new file mode 100644
index 0000000000..32d5ed5db2
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
new file mode 100644
index 0000000000..e40372e819
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
new file mode 100644
index 0000000000..0dbf2d35e7
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
new file mode 100644
index 0000000000..b528837a5f
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
new file mode 100644
index 0000000000..b7d7e5a2c2
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
new file mode 100644
index 0000000000..e149d5861f
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
new file mode 100644
index 0000000000..5410889ed8
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
new file mode 100644
index 0000000000..bc6d6d33ff
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
new file mode 100644
index 0000000000..e396aea6c9
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
new file mode 100644
index 0000000000..b7678cac66
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
index 2505afea65..04c10536e0 100644
--- a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
+++ b/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/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl
new file mode 100644
index 0000000000..bf5c78f3ea
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
new file mode 100644
index 0000000000..1c5234c450
--- /dev/null
+++ b/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/indra/newview/app_settings/shaders/shader_heirarchy.txt b/indra/newview/app_settings/shaders/shader_heirarchy.txt
new file mode 100644
index 0000000000..d8bbf69b38
--- /dev/null
+++ b/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/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml
new file mode 100644
index 0000000000..f16ec6c30f
--- /dev/null
+++ b/indra/newview/app_settings/ultra_graphics.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<settings version = "101">
+ <!--NO SHADERS-->
+ <RenderAvatarCloth value="TRUE"/>
+ <!--Default for now-->
+ <RenderAvatarLODFactor value="1.0"/>
+ <!--NO SHADERS-->
+ <RenderAvatarVP value="TRUE"/>
+ <!--Short Range-->
+ <RenderFarClip value="256"/>
+ <!--Default for now-->
+ <RenderFlexTimeFactor value="1"/>
+ <!--256... but they don't use this-->
+ <RenderGlowResolutionPow value="9"/>
+ <!--Sun/Moon only-->
+ <RenderLightingDetail value="1"/>
+ <!--Low number-->
+ <RenderMaxPartCount value="4096"/>
+ <!--bump okay-->
+ <RenderObjectBump value="TRUE"/>
+ <!--NO SHADERS-->
+ <RenderReflectionDetail value="3"/>
+ <!--Simple-->
+ <RenderTerrainDetail value="1"/>
+ <!--Default for now-->
+ <RenderTerrainLODFactor value="2.0"/>
+ <!--Default for now-->
+ <RenderTreeLODFactor value="1.0"/>
+ <!--Try Impostors-->
+ <RenderUseImpostors value="TRUE"/>
+ <!--Default for now-->
+ <RenderVolumeLODFactor value="2.0"/>
+ <!--NO SHADERS-->
+ <RenderWaterReflections value="TRUE"/>
+ <!--NO SHADERS-->
+ <VertexShaderEnable value="TRUE"/>
+ <!--NO SHADERS-->
+ <WindLightUseAtmosShaders value="TRUE"/>
+</settings>
diff --git a/indra/newview/app_settings/windlight/clouds2.tga b/indra/newview/app_settings/windlight/clouds2.tga
new file mode 100644
index 0000000000..c95ce7fec4
--- /dev/null
+++ b/indra/newview/app_settings/windlight/clouds2.tga
Binary files differ
diff --git a/indra/newview/app_settings/windlight/days/Default.xml b/indra/newview/app_settings/windlight/days/Default.xml
new file mode 100644
index 0000000000..3d3afd5075
--- /dev/null
+++ b/indra/newview/app_settings/windlight/days/Default.xml
@@ -0,0 +1,36 @@
+<llsd>
+ <array>
+ <array>
+ <real>0</real>
+ <string>A-12AM</string>
+ </array>
+ <array>
+ <real>0.125</real>
+ <string>A-3AM</string>
+ </array>
+ <array>
+ <real>0.25</real>
+ <string>A-6AM</string>
+ </array>
+ <array>
+ <real>0.375</real>
+ <string>A-9AM</string>
+ </array>
+ <array>
+ <real>0.5</real>
+ <string>A-12PM</string>
+ </array>
+ <array>
+ <real>0.625</real>
+ <string>A-3PM</string>
+ </array>
+ <array>
+ <real>0.75</real>
+ <string>A-6PM</string>
+ </array>
+ <array>
+ <real>0.875</real>
+ <string>A-9PM</string>
+ </array>
+ </array>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/postprocesseffects.xml b/indra/newview/app_settings/windlight/postprocesseffects.xml
new file mode 100644
index 0000000000..4645215a47
--- /dev/null
+++ b/indra/newview/app_settings/windlight/postprocesseffects.xml
@@ -0,0 +1,2 @@
+<llsd><map><key>Asi Weird</key><map><key>bloom_strength</key><real>4.5799999237060547</real><key>bloom_width</key><real>12.539999961853027</real><key>brightness</key><real>0.89999997615814209</real><key>brightness_multiplier</key><real>3</real><key>contrast</key><real>0.22999998927116394</real><key>contrast_base</key><array><real>1</real><real>1</real><real>1</real><real>0.5</real></array><key>enable_bloom</key><integer>1</integer><key>enable_color_filter</key><integer>1</integer><key>enable_night_vision</key><boolean>0</boolean><key>extract_high</key><real>1</real><key>extract_low</key><real>0.47999998927116394</real><key>noise_size</key><real>25</real><key>noise_strength</key><real>0.40000000000000002</real><key>saturation</key><real>-1</real></map><key>NegativeSaturation</key><map><key>bloom_strength</key><real>1.5</real><key>bloom_width</key><real>2.25</real><key>brightness</key><real>1</real><key>brightness_multiplier</key><real>3</real><key>contrast</key><real>1</real><key>contrast_base</key><array><real>1</real><real>1</real><real>1</real><real>0.5</real></array><key>enable_bloom</key><boolean>0</boolean><key>enable_color_filter</key><integer>1</integer><key>enable_night_vision</key><boolean>0</boolean><key>extract_high</key><real>1</real><key>extract_low</key><real>0.94999999999999996</real><key>noise_size</key><real>25</real><key>noise_strength</key><real>0.40000000000000002</real><key>saturation</key><real>-1</real></map><key>NightVision</key><map><key>bloom_strength</key><real>1.5</real><key>bloom_width</key><real>2.25</real><key>brightness</key><real>1</real><key>brightness_multiplier</key><real>3</real><key>contrast</key><real>1</real><key>contrast_base</key><array><real>1</real><real>1</real><real>1</real><real>0.5</real></array><key>enable_bloom</key><boolean>0</boolean><key>enable_color_filter</key><boolean>0</boolean><key>enable_night_vision</key><integer>1</integer><key>extract_high</key><real>1</real><key>extract_low</key><real>0.94999999999999996</real><key>noise_size</key><real>25</real><key>noise_strength</key><real>0.40000000000000002</real><key>saturation</key><real>1</real></map><key>WGhost</key><map><key>bloom_strength</key><real>2.0399999618530273</real><key>bloom_width</key><real>2.25</real><key>brightness</key><real>1</real><key>brightness_multiplier</key><real>3</real><key>contrast</key><real>1</real><key>contrast_base</key><array><real>1</real><real>1</real><real>1</real><real>0.5</real></array><key>enable_bloom</key><integer>1</integer><key>enable_color_filter</key><boolean>0</boolean><key>enable_night_vision</key><boolean>0</boolean><key>extract_high</key><real>1</real><key>extract_low</key><real>0.22999998927116394</real><key>noise_size</key><real>25</real><key>noise_strength</key><real>0.40000000000000002</real><key>saturation</key><real>1</real></map><key>default</key><map><key>bloom_strength</key><real>1.5</real><key>bloom_width</key><real>2.25</real><key>brightness</key><real>1</real><key>brightness_multiplier</key><real>3</real><key>contrast</key><real>1</real><key>contrast_base</key><array><real>1</real><real>1</real><real>1</real><real>0.5</real></array><key>enable_bloom</key><boolean>0</boolean><key>enable_color_filter</key><boolean>0</boolean><key>enable_night_vision</key><boolean>0</boolean><key>extract_high</key><real>1</real><key>extract_low</key><real>0.94999999999999996</real><key>noise_size</key><real>25</real><key>noise_strength</key><real>0.40000000000000002</real><key>saturation</key><real>1</real></map></map></llsd>
+><map><key>bloom_strength</key><real>1.5</real><key>bloom_width</key><real>2.25</real><key>brightness</key><real>1</real><key>brightness_multiplier</key><real>3</real><key>contrast</key><real>1</real><key>contrast_base</key><array><real>1</real><real>1</real><real>1</real><real>0.5</real></array><key>enable_bloom</key><boolean>0</boolean><key>enable_color_filter</key><boolean>0</boolean><key>enable_night_vision</key><boolean>0</boolean><key>extract_high</key><real>1</real><key>extract_low</key><real>0.94999999999999996</real><key>noise_size</key><real>25</real><key>noise_strength</key><real>0.40000000000000002</real><key>saturation</key><real>1</real></map></map></llsd>
diff --git a/indra/newview/app_settings/windlight/skies/A%2D12AM.xml b/indra/newview/app_settings/windlight/skies/A%2D12AM.xml
new file mode 100644
index 0000000000..0aba31214a
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/A%2D12AM.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.20405027270317078</real>
+ <real>0.24246673285961151</real>
+ <real>0.32999998331069946</real>
+ <real>0.10999999940395355</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.44999998807907104</real>
+ <real>0.44999998807907104</real>
+ <real>0.44999998807907104</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.23999999463558197</real>
+ <real>0.23999999463558197</real>
+ <real>0.23999999463558197</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.87999999523162842</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.49940013885498</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.26999998092651367</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00030000001424923539</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>0</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.47999998927116394</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>4</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>1</real>
+ <real>-4.8876205482883961e-007</real>
+ <real>1</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>906.20001220703125</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>22</integer>
+ <key>star_brightness</key>
+ <real>2</real>
+ <key>sun_angle</key>
+ <real>4.7123894691467285</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.34876692295074463</real>
+ <real>0.35574248433113098</real>
+ <real>0.65999996662139893</real>
+ <real>0.2199999988079071</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/A%2D12PM.xml b/indra/newview/app_settings/windlight/skies/A%2D12PM.xml
new file mode 100644
index 0000000000..119b3e1418
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/A%2D12PM.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>1.0499999523162842</real>
+ <real>1.0499999523162842</real>
+ <real>1.0499999523162842</real>
+ <real>0.34999999403953552</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.24475815892219543</real>
+ <real>0.44872328639030457</real>
+ <real>0.75999999046325684</real>
+ <real>0.37999999523162842</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.49548381567001343</real>
+ <real>0.49548381567001343</real>
+ <real>0.63999998569488525</real>
+ <real>0.31999999284744263</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.40999999642372131</real>
+ <real>0.40999999642372131</real>
+ <real>0.40999999642372131</real>
+ <real>0.40999999642372131</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.199999809265137</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.26999998092651367</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00017999998817685992</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>0.80000001192092896</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.47999998927116394</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.18999999761581421</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>1</real>
+ <real>-4.3711388286737929e-008</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>1605</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>22</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>1.5707963705062866</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.7342105507850647</real>
+ <real>0.78157895803451538</real>
+ <real>0.89999997615814209</real>
+ <real>0.29999998211860657</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/A%2D3AM.xml b/indra/newview/app_settings/windlight/skies/A%2D3AM.xml
new file mode 100644
index 0000000000..f790d3d961
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/A%2D3AM.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.22259476780891418</real>
+ <real>0.26450252532958984</real>
+ <real>0.35999998450279236</real>
+ <real>0.11999999731779099</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.44999116536295314</real>
+ <real>0.44999854555993368</real>
+ <real>0.45001013284446073</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.23999616268583132</real>
+ <real>0.239999227803052</real>
+ <real>0.24000028550619668</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.22615400241566114</real>
+ <real>0.22615400241566114</real>
+ <real>0.22615400241566114</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.88000000953681223</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.499400354105791</real>
+ <real>10.011000104419489</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.26999998092651367</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.0003000046529240592</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>7.8213197608078763e-005</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5.0000000000023022</real>
+ <real>0.0010000000214220922</real>
+ <real>-0.47999999165507345</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>3.9999044060931555</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>4.6348559691012062e-006</real>
+ <real>0.19915600437461423</real>
+ <real>0.19915600437461423</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.70710653066635132</real>
+ <real>-0.70710700750350952</real>
+ <real>1</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>906.19008370909478</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>22</integer>
+ <key>star_brightness</key>
+ <real>1.9999420642852783</real>
+ <key>sun_angle</key>
+ <real>5.4977874755859375</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.60242295265197754</real>
+ <real>0.61447036266326904</real>
+ <real>1.1399999856948853</real>
+ <real>0.37999999523162842</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/A%2D3PM.xml b/indra/newview/app_settings/windlight/skies/A%2D3PM.xml
new file mode 100644
index 0000000000..ec9706773e
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/A%2D3PM.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>1.0499999523162842</real>
+ <real>1.0499999523162842</real>
+ <real>1.0499999523162842</real>
+ <real>0.34999999403953552</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.2447581488182351</real>
+ <real>0.44872328639030457</real>
+ <real>0.75999999046325684</real>
+ <real>0.38000004053115788</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.49548382097675159</real>
+ <real>0.49548381382419748</real>
+ <real>0.63999999284744291</real>
+ <real>0.31999999642372146</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.40999999165535073</real>
+ <real>0.40999999165535073</real>
+ <real>0.40999999165535073</real>
+ <real>0.40999999165535073</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.99999999999999289</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.4199999868869746</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.199999809265137</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.26999998092651367</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00017999998817685818</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>0.80000001192093606</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.47999998927116394</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.18999999761581243</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.70710659027099609</real>
+ <real>-0.70710694789886475</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>1605</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>22</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>2.3561947345733643</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.73421055078505759</real>
+ <real>0.78157895803450828</real>
+ <real>0.89999997615813498</real>
+ <real>0.29999998211860301</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/A%2D6AM.xml b/indra/newview/app_settings/windlight/skies/A%2D6AM.xml
new file mode 100644
index 0000000000..bbc7aeec59
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/A%2D6AM.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.80999994277954102</real>
+ <real>0.46289783716201782</real>
+ <real>0.62999993562698364</real>
+ <real>0.26999998092651367</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.15793180465698242</real>
+ <real>0.43499568104743958</real>
+ <real>0.87000000476837158</real>
+ <real>0.87000000476837158</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.20673196017742157</real>
+ <real>0.40988314151763916</real>
+ <real>0.47999998927116394</real>
+ <real>0.47999998927116394</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.22616604226328718</real>
+ <real>0.22616604226328718</real>
+ <real>0.22616604226328718</real>
+ <real>0.99997219085526012</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.88000025272481253</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.49940013883861</real>
+ <real>10.010999679576344</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.26999998092651367</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00062000000616535544</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>2.6999279499073054</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5.0009990693069994</real>
+ <real>0.0010000000474963411</real>
+ <real>-0.48000101923815919</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.53999996185302734</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.15999999642372131</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.094108223915100098</real>
+ <real>0.99556195735931396</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>563</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>22</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>0.094247691333293915</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>2.369999885559082</real>
+ <real>2.369999885559082</real>
+ <real>2.369999885559082</real>
+ <real>0.78999996185302734</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/A%2D6PM.xml b/indra/newview/app_settings/windlight/skies/A%2D6PM.xml
new file mode 100644
index 0000000000..6e82f2eb21
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/A%2D6PM.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.14840038120746613</real>
+ <real>0.17633917927742004</real>
+ <real>0.23999999463558197</real>
+ <real>0.079999998211860657</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.14522500336170197</real>
+ <real>0.39999699592590332</real>
+ <real>0.80000197887420654</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.10767599940299988</real>
+ <real>0.21348699927330017</real>
+ <real>0.25</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.87999999523162842</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.49940013885498</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.26999998092651367</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00046000001020729542</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>2.7000000476837158</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.47999998927116394</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.15999999642372131</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.07532646507024765</real>
+ <real>-0.99715894460678101</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>562.5</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>22</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>3.0661947727203369</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>2.8385701179504395</real>
+ <real>2.8385701179504395</real>
+ <real>2.8385701179504395</real>
+ <real>1</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/A%2D9AM.xml b/indra/newview/app_settings/windlight/skies/A%2D9AM.xml
new file mode 100644
index 0000000000..413e3a27d9
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/A%2D9AM.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>1.0499999949065426</real>
+ <real>1.0499999988079054</real>
+ <real>1.0499999988079054</real>
+ <real>0.3500000095367426</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.15999999642372131</real>
+ <real>0.44872328639030457</real>
+ <real>0.75999999046325684</real>
+ <real>0.75999999046325684</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.53999996185302734</real>
+ <real>0.47999998927116394</real>
+ <real>0.69999998807907104</real>
+ <real>0.34999999403953552</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.37000000476837158</real>
+ <real>0.37000000476837158</real>
+ <real>0.37000000476837158</real>
+ <real>0.37000000476837158</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.99999998569455784</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999997615814166</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.199999844956437</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.27333331108093262</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00017999998102430359</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>0.80000008344649842</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>4.9999999284740397</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.47999999046327346</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.70000003576435432</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.18999999284767277</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.70710676908493042</real>
+ <real>0.70710676908493042</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>1605</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>22</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>0.78539818525314331</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.73421054104441197</real>
+ <real>0.7815789463510896</real>
+ <real>0.89999995470046912</real>
+ <real>0.29999997496605069</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/A%2D9PM.xml b/indra/newview/app_settings/windlight/skies/A%2D9PM.xml
new file mode 100644
index 0000000000..292f6713b7
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/A%2D9PM.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.20404692765200849</real>
+ <real>0.24246276689169122</real>
+ <real>0.33000383615406292</real>
+ <real>0.1100123608103587</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.44999116536295314</real>
+ <real>0.44999854555993368</real>
+ <real>0.45001013284446073</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.23999616268583132</real>
+ <real>0.239999227803052</real>
+ <real>0.24000028550619668</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.22615400241566114</real>
+ <real>0.22615400241566114</real>
+ <real>0.22615400241566114</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.88000000953681223</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.499400354105791</real>
+ <real>10.011000104419489</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.26999998092651367</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.0003000046529240592</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>7.8213197608078763e-005</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5.0000000000023022</real>
+ <real>0.0010000000214220922</real>
+ <real>-0.47999999165507345</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>3.9999044060931555</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>4.6348559691012062e-006</real>
+ <real>0.19915600437461423</real>
+ <real>0.19915600437461423</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.70710688829421997</real>
+ <real>0.70710664987564087</real>
+ <real>1</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>906.19008370909478</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>22</integer>
+ <key>star_brightness</key>
+ <real>1.9999420642852783</real>
+ <key>sun_angle</key>
+ <real>3.9269909858703613</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.34878980098432066</real>
+ <real>0.35576509414380553</real>
+ <real>0.66003586768772493</real>
+ <real>0.22001197576412324</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Barcelona.xml b/indra/newview/app_settings/windlight/skies/Barcelona.xml
new file mode 100644
index 0000000000..ea9cab8fbb
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Barcelona.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.22260047495365143</real>
+ <real>0.26450866460800171</real>
+ <real>0.35999998450279236</real>
+ <real>0.11999999731779099</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.14522500336170197</real>
+ <real>0.39999699592590332</real>
+ <real>0.80000197887420654</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.15130999684333801</real>
+ <real>0.30000001192092896</real>
+ <real>0.35131001472473145</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.50999999046325684</real>
+ <real>0.50999999046325684</real>
+ <real>0.50999999046325684</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.49940013885498</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.30000001192092896</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.0003499999875202775</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>6</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.33000001311302185</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.062790460884571075</real>
+ <real>-0.99802672863006592</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>600</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>21</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>3.0787608623504639</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>1.1699999570846558</real>
+ <real>1.1699999570846558</real>
+ <real>1.1699999570846558</real>
+ <real>0.38999998569488525</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Blizzard.xml b/indra/newview/app_settings/windlight/skies/Blizzard.xml
new file mode 100644
index 0000000000..d17d2790a8
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Blizzard.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.4823022186756134</real>
+ <real>0.57310229539871216</real>
+ <real>0.77999997138977051</real>
+ <real>0.25999999046325684</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.14522500336170197</real>
+ <real>0.39999699592590332</real>
+ <real>0.80000197887420654</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.15130999684333801</real>
+ <real>0.30000001192092896</real>
+ <real>0.35131001472473145</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.12862999737262726</real>
+ <real>0.12862999737262726</real>
+ <real>0.12862999737262726</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.88419097661972046</real>
+ <real>0.53047597408294678</real>
+ <real>0.4270470142364502</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.38419300317764282</real>
+ <real>0.5</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10</real>
+ <real>10</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.61711597442626953</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.0001250890054507181</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>11.40000057220459</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>6.4079799652099609</real>
+ <real>0.0012815999798476696</real>
+ <real>-0.42292699217796326</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>4</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.21744099259376526</real>
+ <real>0.21744099259376526</real>
+ <real>0.21744099259376526</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.15643447637557983</real>
+ <real>0.98768836259841919</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>4000</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>2</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>0.15707963705062866</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>3</real>
+ <real>3</real>
+ <real>3</real>
+ <real>1</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Blue%20Midday.xml b/indra/newview/app_settings/windlight/skies/Blue%20Midday.xml
new file mode 100644
index 0000000000..570f059961
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Blue%20Midday.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.14999999105930328</real>
+ <real>0.14999999105930328</real>
+ <real>0.14999999105930328</real>
+ <real>0.049999997019767761</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.18153078854084015</real>
+ <real>0.49999505281448364</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.43070217967033386</real>
+ <real>0.85394656658172607</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.53962135314941406</real>
+ <real>0.53962135314941406</real>
+ <real>0.53962135314941406</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.69569224119186401</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.10999999195337296</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.49940013885498</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.3765256404876709</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.0003499999875202775</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>2.9846153259277344</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>4.2061538696289062</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.44246155023574829</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>2.8830769062042236</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.49740666151046753</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.86074197292327881</real>
+ <real>-0.50904154777526855</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>600</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>10</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>2.1048672199249268</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.88526362180709839</real>
+ <real>1.2300000190734863</real>
+ <real>1.2300000190734863</real>
+ <real>0.40999999642372131</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml b/indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml
new file mode 100644
index 0000000000..4925b29eea
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Coastal%20Afternoon.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.89040267467498779</real>
+ <real>1.0580335855484009</real>
+ <real>1.4399999380111694</real>
+ <real>0.47999998927116394</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.14522500336170197</real>
+ <real>0.39999699592590332</real>
+ <real>0.80000197887420654</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.15130999684333801</real>
+ <real>0.30000001192092896</real>
+ <real>0.35131001472473145</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.21396400034427643</real>
+ <real>0.21396400034427643</real>
+ <real>0.21396400034427643</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.16495099663734436</real>
+ <real>0.09771379828453064</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.079754598438739777</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>9.644780158996582</real>
+ <real>10.423800468444824</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.30061298608779907</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00015800200344529003</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.33000001311302185</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.13210900127887726</real>
+ <real>0.13210900127887726</real>
+ <real>0.13210900127887726</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.031410444527864456</real>
+ <real>-0.99950659275054932</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>600</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>3</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>3.1101770401000977</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>3</real>
+ <real>3</real>
+ <real>3</real>
+ <real>1</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml b/indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml
new file mode 100644
index 0000000000..f4736cf4c6
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Coastal%20Sunset.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.31535112857818604</real>
+ <real>0.37471914291381836</real>
+ <real>0.50999999046325684</real>
+ <real>0.17000000178813934</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.11645399779081345</real>
+ <real>0.32075101137161255</real>
+ <real>0.64150899648666382</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.054176401346921921</real>
+ <real>0.10741499811410904</real>
+ <real>0.12578600645065308</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.21396400034427643</real>
+ <real>0.21396400034427643</real>
+ <real>0.21396400034427643</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.27044001221656799</real>
+ <real>1</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.10062900185585022</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>9.644780158996582</real>
+ <real>10.423800468444824</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.32704401016235352</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00015849100600462407</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>3.4000000953674316</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>6.867919921875</real>
+ <real>0.0013735899701714516</real>
+ <real>-0.45328301191329956</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.6792449951171875</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.13210900127887726</real>
+ <real>0.13210900127887726</real>
+ <real>0.13210900127887726</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.031410444527864456</real>
+ <real>-0.99950659275054932</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>1308.1800537109375</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>5</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>3.1101770401000977</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>3</real>
+ <real>3</real>
+ <real>3</real>
+ <real>1</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Default.xml b/indra/newview/app_settings/windlight/skies/Default.xml
new file mode 100644
index 0000000000..13a2c75046
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Default.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>1.0499999523162842</real>
+ <real>1.0499999523162842</real>
+ <real>1.0499999523162842</real>
+ <real>0.34999999403953552</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.24475815892219543</real>
+ <real>0.44872328639030457</real>
+ <real>0.75999999046325684</real>
+ <real>0.37999999523162842</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.49548381567001343</real>
+ <real>0.49548381567001343</real>
+ <real>0.63999998569488525</real>
+ <real>0.31999999284744263</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.40999999642372131</real>
+ <real>0.40999999642372131</real>
+ <real>0.40999999642372131</real>
+ <real>0.40999999642372131</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.199999809265137</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.26999998092651367</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00017999998817685992</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>0.80000001192092896</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.47999998927116394</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.18999999761581421</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.91269159317016602</real>
+ <real>-0.40864911675453186</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>1605</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>22</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>1.9917697906494141</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.7342105507850647</real>
+ <real>0.78157895803451538</real>
+ <real>0.89999997615814209</real>
+ <real>0.29999998211860657</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml b/indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml
new file mode 100644
index 0000000000..b2a611163d
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Desert%20Sunset.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.07420019805431366</real>
+ <real>0.088169597089290619</real>
+ <real>0.11999999731779099</real>
+ <real>1</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.14522500336170197</real>
+ <real>0.39999699592590332</real>
+ <real>0.80000197887420654</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.10767599940299988</real>
+ <real>0.21348699927330017</real>
+ <real>0.25</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.199999809265137</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.37999999523162842</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00046000001020729542</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>2</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1.6100000143051147</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.47999998927116394</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.15999999642372131</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.062790460884571075</real>
+ <real>-0.99802672863006592</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>562.5</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>22</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>3.0787608623504639</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>2.8385701179504395</real>
+ <real>2.8385701179504395</real>
+ <real>2.8385701179504395</real>
+ <real>1</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Fine%20Day.xml b/indra/newview/app_settings/windlight/skies/Fine%20Day.xml
new file mode 100644
index 0000000000..e053815be1
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Fine%20Day.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.21194984018802643</real>
+ <real>0.25700280070304871</real>
+ <real>0.25999999046325684</real>
+ <real>0.25999999046325684</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.10031381994485855</real>
+ <real>0.2849995493888855</real>
+ <real>0.56999999284744263</real>
+ <real>0.56999999284744263</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.15806557238101959</real>
+ <real>0.31211116909980774</real>
+ <real>0.52999997138977051</real>
+ <real>0.52999997138977051</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.62000000476837158</real>
+ <real>0.72737622261047363</real>
+ <real>0.73626559972763062</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.89999997615814209</real>
+ <real>0.93999999761581421</real>
+ <real>0.74000000953674316</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.11999999731779099</real>
+ <real>0.20999999344348907</real>
+ <real>0.029999999329447746</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.25999999046325684</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>9.993240904292179</real>
+ <real>10.010000228881836</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.29999998211860657</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00013000000035390258</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>10.100000381469727</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>3.8955750465393066</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1.4699999094009399</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>11.200000762939453</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.64999997615814209</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.35999998450279236</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.11999999731779099</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0.66304093599319458</real>
+ <real>0.24868990480899811</real>
+ <real>-0.70606660842895508</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>789</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>24</integer>
+ <key>star_brightness</key>
+ <real>0.18999999761581421</real>
+ <key>sun_angle</key>
+ <real>0.25132742524147034</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>2.25</real>
+ <real>1.2599999904632568</real>
+ <real>0.59999996423721313</real>
+ <real>2.25</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml b/indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml
new file mode 100644
index 0000000000..8576ec125c
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.029999999329447746</real>
+ <real>0</real>
+ <real>0</real>
+ <real>0.029999999329447746</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.097999997437000275</real>
+ <real>0.2800000011920929</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.11999999731779099</real>
+ <real>0.35094299912452698</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.48999997973442078</real>
+ <real>0.79000002145767212</real>
+ <real>0.80000001192092896</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.53999996185302734</real>
+ <real>0.5</real>
+ <real>0.75999999046325684</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.38999998569488525</real>
+ <real>0.5</real>
+ <real>0.039999999105930328</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.43999999761581421</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>11.809999465942383</real>
+ <real>12.799999237060547</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.32999998331069946</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00021999998716637492</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>4</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>3.2044246196746826</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1.5399999618530273</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>3.8000010331979865</real>
+ <real>0.001000000059761974</real>
+ <real>-0.49999996688498527</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.20999999344348907</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.049999997019767761</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0.056814663112163544</real>
+ <real>0.42577928304672241</real>
+ <real>-0.90304160118103027</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>676.10003662109375</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>18</integer>
+ <key>star_brightness</key>
+ <real>0.44999998807907104</real>
+ <key>sun_angle</key>
+ <real>0.4398229718208313</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>1.7999999523162842</real>
+ <real>1.4099999666213989</real>
+ <real>1.0199999809265137</real>
+ <real>1.7999999523162842</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Foggy.xml b/indra/newview/app_settings/windlight/skies/Foggy.xml
new file mode 100644
index 0000000000..cb7395d589
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Foggy.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.32999998331069946</real>
+ <real>0.32999998331069946</real>
+ <real>0.32999998331069946</real>
+ <real>0.10999999940395355</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.14522500336170197</real>
+ <real>0.39999699592590332</real>
+ <real>0.80000197887420654</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.43070214986801147</real>
+ <real>0.85394668579101563</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0.69999998807907104</real>
+ <real>0.69999998807907104</real>
+ <real>0.69999998807907104</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.53999996185302734</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.29999998211860657</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.49940013885498</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.39999997615814209</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.0003499999875202775</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>4</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>3.7999999523162842</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.5</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>4</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.64999997615814209</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>1</real>
+ <real>-4.3711388286737929e-008</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>600</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>18</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>1.5707963705062866</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.53999996185302734</real>
+ <real>0.53999996185302734</real>
+ <real>0.53999996185302734</real>
+ <real>0.17999999225139618</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml b/indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml
new file mode 100644
index 0000000000..32be0d25e6
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Funky%20Funky%20Funky.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.29999998211860657</real>
+ <real>0.23511900007724762</real>
+ <real>0.31999999284744263</real>
+ <real>1</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.13977900147438049</real>
+ <real>0.38499599695205688</real>
+ <real>0.76999998092651367</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.18999999761581421</real>
+ <real>0.18999999761581421</real>
+ <real>0.18999999761581421</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>5.3780298233032227</real>
+ <real>1.9675600528717041</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>5.3780298233032227</real>
+ <real>1.9675600528717041</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.739999771118164</real>
+ <real>10.600000381469727</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.31000000238418579</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00052000000141561031</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>3.4000000953674316</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>0.77999997138977051</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.47999998927116394</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>1.1000000238418579</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.12999999523162842</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.53582650423049927</real>
+ <real>-0.84432810544967651</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>656.20001220703125</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>28</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>2.5761063098907471</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>2.1299998760223389</real>
+ <real>1.5299999713897705</real>
+ <real>2.8385701179504395</real>
+ <real>1</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Funky%20Funky.xml b/indra/newview/app_settings/windlight/skies/Funky%20Funky.xml
new file mode 100644
index 0000000000..ae16b2d135
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Funky%20Funky.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.32999998331069946</real>
+ <real>0.32999998331069946</real>
+ <real>0.32999998331069946</real>
+ <real>0.10999999940395355</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.14522500336170197</real>
+ <real>0.39999699592590332</real>
+ <real>0.80000197887420654</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.15130999684333801</real>
+ <real>0.30000001192092896</real>
+ <real>0.35131001472473145</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.65280699729919434</real>
+ <real>0.50335597991943359</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.65280699729919434</real>
+ <real>0.50335597991943359</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.49940013885498</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.33064401149749756</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.0003499999875202775</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.33000001311302185</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.062790460884571075</real>
+ <real>-0.99802672863006592</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>600</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>11</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>3.0787608623504639</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.86811381578445435</real>
+ <real>2.2200000286102295</real>
+ <real>2.2200000286102295</real>
+ <real>0.74000000953674316</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Gelatto.xml b/indra/newview/app_settings/windlight/skies/Gelatto.xml
new file mode 100644
index 0000000000..66b3d317b8
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Gelatto.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0</real>
+ <real>0.15999999642372131</real>
+ <real>0</real>
+ <real>0.15999999642372131</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.019999999552965164</real>
+ <real>0.22999770939350128</real>
+ <real>0.45999997854232788</real>
+ <real>0.55000001192092896</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0</real>
+ <real>0.6319204568862915</real>
+ <real>0.74000000953674316</real>
+ <real>0.84999996423721313</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.53999996185302734</real>
+ <real>0.50999999046325684</real>
+ <real>0.23999999463558197</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.059999998658895493</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.2800000011920929</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>20</real>
+ <real>20</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.32999998331069946</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00016999999934341758</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>8.1000003814697266</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>3.7699110507965088</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>0</boolean>
+ <boolean>0</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1.5399999618530273</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>0.39999961853027344</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.49999997019767761</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>3.2599999904632568</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.4699999988079071</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0.58749508857727051</real>
+ <real>-0.031410761177539825</real>
+ <real>-0.80861783027648926</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>1267.5999755859375</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>18</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>-0.031415928155183792</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.75</real>
+ <real>0.71999996900558472</real>
+ <real>0.37800011038780212</real>
+ <real>0.80999994277954102</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Ghost.xml b/indra/newview/app_settings/windlight/skies/Ghost.xml
new file mode 100644
index 0000000000..447202ed51
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Ghost.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.23999999463558197</real>
+ <real>0.23999999463558197</real>
+ <real>0.23999999463558197</real>
+ <real>0.079999998211860657</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.16700799763202667</real>
+ <real>0.45999500155448914</real>
+ <real>0.92000001668930054</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.18089599907398224</real>
+ <real>0.35865798592567444</real>
+ <real>0.41999998688697815</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.40999999642372131</real>
+ <real>0.40999999642372131</real>
+ <real>0.40999999642372131</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>11.539999961853027</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.36000001430511475</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00042999998549930751</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>8.1000003814697266</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.51999998092651367</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.75</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.18000000715255737</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.89100658893585205</real>
+ <real>0.45399042963981628</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>718.70001220703125</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>23</integer>
+ <key>star_brightness</key>
+ <real>2</real>
+ <key>sun_angle</key>
+ <real>1.0995575189590454</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.33000001311302185</real>
+ <real>0.33000001311302185</real>
+ <real>0.33000001311302185</real>
+ <real>1</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml b/indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml
new file mode 100644
index 0000000000..098844e16e
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Incongruent%20Truths.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0</real>
+ <real>0</real>
+ <real>0.44999998807907104</real>
+ <real>0.44999998807907104</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.13997539444089213</real>
+ <real>0.38665792478461469</real>
+ <real>0.77332294252195766</real>
+ <real>0.95108884837904384</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0</real>
+ <real>0.22876684367656708</real>
+ <real>0.290018230676651</real>
+ <real>0.31999999284744263</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.25999999046325684</real>
+ <real>0.28883209824562073</real>
+ <real>0.28994369506835938</real>
+ <real>0.28999999165534973</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.17999999225139618</real>
+ <real>0.50999999046325684</real>
+ <real>0.91999995708465576</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.079999998211860657</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.25</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.436104517528292</real>
+ <real>10</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.34000000357627869</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.0002899999963119626</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>1.3000000715255737</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>2.2619466781616211</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1.5399999618530273</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>4.0000009536743164</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.74999994039535522</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.12999999523162842</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.14999999105930328</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>-0.74630612134933472</real>
+ <real>0.24868990480899811</real>
+ <real>-0.61739814281463623</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>394.39999389648437</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>18</integer>
+ <key>star_brightness</key>
+ <real>0.44999998807907104</real>
+ <key>sun_angle</key>
+ <real>0.25132742524147034</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>2.25</real>
+ <real>1.957500696182251</real>
+ <real>1.170000433921814</real>
+ <real>0.75</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Midday%201.xml b/indra/newview/app_settings/windlight/skies/Midday%201.xml
new file mode 100644
index 0000000000..13a2c75046
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Midday%201.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>1.0499999523162842</real>
+ <real>1.0499999523162842</real>
+ <real>1.0499999523162842</real>
+ <real>0.34999999403953552</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.24475815892219543</real>
+ <real>0.44872328639030457</real>
+ <real>0.75999999046325684</real>
+ <real>0.37999999523162842</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.49548381567001343</real>
+ <real>0.49548381567001343</real>
+ <real>0.63999998569488525</real>
+ <real>0.31999999284744263</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.40999999642372131</real>
+ <real>0.40999999642372131</real>
+ <real>0.40999999642372131</real>
+ <real>0.40999999642372131</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>1.6884100437164307</real>
+ <real>0.52609699964523315</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.199999809265137</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.26999998092651367</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00017999998817685992</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>0.80000001192092896</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.47999998927116394</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.18999999761581421</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.91269159317016602</real>
+ <real>-0.40864911675453186</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>1605</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>22</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>1.9917697906494141</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.7342105507850647</real>
+ <real>0.78157895803451538</real>
+ <real>0.89999997615814209</real>
+ <real>0.29999998211860657</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Midday%202.xml b/indra/newview/app_settings/windlight/skies/Midday%202.xml
new file mode 100644
index 0000000000..04f2ba85ee
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Midday%202.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0</real>
+ <real>0</real>
+ <real>0</real>
+ <real>0</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.14522500336170197</real>
+ <real>0.39999699592590332</real>
+ <real>0.80000197887420654</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.43070214986801147</real>
+ <real>0.85394668579101563</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0.69999998807907104</real>
+ <real>0.69999998807907104</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.53999996185302734</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.29999998211860657</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.199999809265137</real>
+ <real>10.069999694824219</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.22999998927116394</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.0003499999875202775</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>0</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1.6100000143051147</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>3.7999999523162842</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.5</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>1</real>
+ <real>-4.3711388286737929e-008</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>600</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>-1163005939</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>1.5707963705062866</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.80999994277954102</real>
+ <real>0.80999994277954102</real>
+ <real>0.80999994277954102</real>
+ <real>0.26999998092651367</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Midday%203.xml b/indra/newview/app_settings/windlight/skies/Midday%203.xml
new file mode 100644
index 0000000000..a23dcab60b
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Midday%203.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.33000001311302185</real>
+ <real>0.33000001311302185</real>
+ <real>0.33000001311302185</real>
+ <real>1</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.16449999809265137</real>
+ <real>0.4699999988079071</real>
+ <real>0.93999999761581421</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.17547200620174408</real>
+ <real>0.35094299912452698</real>
+ <real>0.62000000476837158</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.5899999737739563</real>
+ <real>0.79000002145767212</real>
+ <real>0.80000001192092896</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>2.8148899078369141</real>
+ <real>5.6909198760986328</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>5.9584097862243652</real>
+ <real>6.9909601211547852</real>
+ <real>0.070000000298023224</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>9.9300003051757813</real>
+ <real>10.199999809265137</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.25999999046325684</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00039000000106170774</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1.6100000143051147</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-1.1599999666213989</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.20999999344348907</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.11999999731779099</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>1</real>
+ <real>-4.3711388286737929e-008</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>2250</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>24</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>1.5707963705062866</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>1.2599999904632568</real>
+ <real>1.2599999904632568</real>
+ <real>1.2599999904632568</real>
+ <real>1</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Midday%204.xml b/indra/newview/app_settings/windlight/skies/Midday%204.xml
new file mode 100644
index 0000000000..255e314e0f
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Midday%204.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.33000001311302185</real>
+ <real>0.33000001311302185</real>
+ <real>0.33000001311302185</real>
+ <real>1</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.097999997437000275</real>
+ <real>0.2800000011920929</real>
+ <real>0.56000000238418579</real>
+ <real>0.56000000238418579</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.17547200620174408</real>
+ <real>0.35094299912452698</real>
+ <real>0.61000001430511475</real>
+ <real>0.61000001430511475</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.5899999737739563</real>
+ <real>0.79000002145767212</real>
+ <real>0.80000001192092896</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>2.8148899078369141</real>
+ <real>5.6909198760986328</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>5.9584097862243652</real>
+ <real>6.9909601211547852</real>
+ <real>0.070000000298023224</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.32999998331069946</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>9.9300003051757813</real>
+ <real>10.199999809265137</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.22999998927116394</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00039000000106170774</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1.6100000143051147</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>3.8000011444091797</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.49999997019767761</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.20999999344348907</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.19999998807907104</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>1</real>
+ <real>-4.3711388286737929e-008</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>1802.800048828125</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>24</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>1.5707963705062866</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>1.2599999904632568</real>
+ <real>1.2599999904632568</real>
+ <real>1.2599999904632568</real>
+ <real>0.41999998688697815</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Night.xml b/indra/newview/app_settings/windlight/skies/Night.xml
new file mode 100644
index 0000000000..c4938949ce
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Night.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.20405027105862608</real>
+ <real>0.24246673976617727</real>
+ <real>0.32999997392212316</real>
+ <real>0.11000000166951449</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.44999999369830818</real>
+ <real>0.44999999398335949</real>
+ <real>0.4499999944309046</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.23999999567946317</real>
+ <real>0.23999999579784967</real>
+ <real>0.23999999583870221</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.22615400241575034</real>
+ <real>0.22615400241575034</real>
+ <real>0.22615400241575034</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.88000000953711155</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.49940035411295</real>
+ <real>10.011000104431371</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.36000001430511475</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00030000001824737163</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>3.0208916693946743e-009</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000214212465</real>
+ <real>-0.47999999165502744</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>3.9999999963077992</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>1.7901579546794781e-010</real>
+ <real>0.19915600437467304</real>
+ <real>0.19915600437467304</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>1</real>
+ <real>3.0028815672267228e-005</real>
+ <real>1</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>906.20003957594895</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>26</integer>
+ <key>star_brightness</key>
+ <real>2</real>
+ <key>sun_angle</key>
+ <real>4.7123589515686035</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.34876692389196384</real>
+ <real>0.3557424864638451</real>
+ <real>0.65999994893325931</real>
+ <real>0.22000000284673543</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Pirate.xml b/indra/newview/app_settings/windlight/skies/Pirate.xml
new file mode 100644
index 0000000000..dcb9c27ba4
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Pirate.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.27825063467025757</real>
+ <real>0.33063584566116333</real>
+ <real>0.44999998807907104</real>
+ <real>0.14999999105930328</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.14522500336170197</real>
+ <real>0.39999699592590332</real>
+ <real>0.80000197887420654</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.15130999684333801</real>
+ <real>0.30000001192092896</real>
+ <real>0.35131001472473145</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>1.2046600580215454</real>
+ <real>0.51547497510910034</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>1.2046600580215454</real>
+ <real>0.51547497510910034</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.49940013885498</real>
+ <real>10.01099967956543</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.33064401149749756</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.0003499999875202775</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>3.4000000953674316</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.36000001430511475</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.69999998807907104</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.062790460884571075</real>
+ <real>-0.99802672863006592</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>600</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>27</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>3.0787608623504639</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>2.8385701179504395</real>
+ <real>2.8385701179504395</real>
+ <real>2.8385701179504395</real>
+ <real>1</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Purple.xml b/indra/newview/app_settings/windlight/skies/Purple.xml
new file mode 100644
index 0000000000..0e9ac3f36e
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Purple.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.1978670060634613</real>
+ <real>0.23511900007724762</real>
+ <real>0.31999999284744263</real>
+ <real>1</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.13977900147438049</real>
+ <real>0.38499599695205688</real>
+ <real>0.76999998092651367</real>
+ <real>1</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.18999999761581421</real>
+ <real>0.18999999761581421</real>
+ <real>0.18999999761581421</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>0.22615399956703186</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>5.3780298233032227</real>
+ <real>1.9675600528717041</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>5.3780298233032227</real>
+ <real>1.9675600528717041</real>
+ <real>0.125</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.41999998688697815</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>10.739999771118164</real>
+ <real>10.600000381469727</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.31000000238418579</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00052000000141561031</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>3.4000000953674316</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>0</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>5</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.47999998927116394</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>1.1000000238418579</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.12999999523162842</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0</real>
+ <real>0.094108030200004578</real>
+ <real>-0.99556201696395874</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>656.20001220703125</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>28</integer>
+ <key>star_brightness</key>
+ <real>0</real>
+ <key>sun_angle</key>
+ <real>3.0473451614379883</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>1.5</real>
+ <real>1.5299999713897705</real>
+ <real>2.8385701179504395</real>
+ <real>1</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml b/indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml
new file mode 100644
index 0000000000..70df6b0e60
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Sailor%27s%20Delight.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0.8399999737739563</real>
+ <real>0.090738050639629364</real>
+ <real>0.1234893873333931</real>
+ <real>0.8399999737739563</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0.93999999761581421</real>
+ <real>0.69999998807907104</real>
+ <real>0.25</real>
+ <real>0.93999999761581421</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>1</real>
+ <real>0.59999996423721313</real>
+ <real>0.25001853704452515</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.65999996662139893</real>
+ <real>0.38999998569488525</real>
+ <real>0.22618354856967926</real>
+ <real>0.65999996662139893</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.76999998092651367</real>
+ <real>0.50999999046325684</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.5</real>
+ <real>0.5899999737739563</real>
+ <real>0.019999999552965164</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.26999998092651367</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>9.4499998092651367</real>
+ <real>9.4399995803833008</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.5</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00019999999494757503</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>6.7000002861022949</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>3.7070791721343994</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1.4800000190734863</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>0.79999923706054688</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.94999998807907104</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.89999997615814209</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.29999998211860657</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>0.53160154819488525</real>
+ <real>0.12533323466777802</real>
+ <real>-0.83767020702362061</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>281.70001220703125</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>18</integer>
+ <key>star_brightness</key>
+ <real>1.3799999952316284</real>
+ <key>sun_angle</key>
+ <real>0.12566371262073517</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>0.75</real>
+ <real>1.6800000667572021</real>
+ <real>1.0777359008789062</real>
+ <real>0.56000000238418579</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml b/indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml
new file mode 100644
index 0000000000..4c44a1bdb2
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/Sheer%20Surreality.xml
@@ -0,0 +1,141 @@
+<llsd>
+ <map>
+ <key>ambient</key>
+ <array>
+ <real>0</real>
+ <real>0.059999998658895493</real>
+ <real>0</real>
+ <real>0.059999998658895493</real>
+ </array>
+ <key>blue_density</key>
+ <array>
+ <real>0</real>
+ <real>0.099999994039535522</real>
+ <real>0.32999998331069946</real>
+ <real>0.32999998331069946</real>
+ </array>
+ <key>blue_horizon</key>
+ <array>
+ <real>0.029999999329447746</real>
+ <real>0</real>
+ <real>1</real>
+ <real>1</real>
+ </array>
+ <key>cloud_color</key>
+ <array>
+ <real>0.81999999284744263</real>
+ <real>0.18999999761581421</real>
+ <real>0.039999999105930328</real>
+ <real>0.81999999284744263</real>
+ </array>
+ <key>cloud_pos_density1</key>
+ <array>
+ <real>0.74000000953674316</real>
+ <real>0.93999999761581421</real>
+ <real>0.20999999344348907</real>
+ <real>1</real>
+ </array>
+ <key>cloud_pos_density2</key>
+ <array>
+ <real>0.65999996662139893</real>
+ <real>0.52999997138977051</real>
+ <real>0.0099999997764825821</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scale</key>
+ <array>
+ <real>0.14000000059604645</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>cloud_scroll_rate</key>
+ <array>
+ <real>18</real>
+ <real>20</real>
+ </array>
+ <key>cloud_shadow</key>
+ <array>
+ <real>0.37999999523162842</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>density_multiplier</key>
+ <array>
+ <real>0.00018000000272877514</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>distance_multiplier</key>
+ <array>
+ <real>6.7000002861022949</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>east_angle</key>
+ <real>2.3247785568237305</real>
+ <key>enable_cloud_scroll</key>
+ <array>
+ <boolean>1</boolean>
+ <boolean>1</boolean>
+ </array>
+ <key>gamma</key>
+ <array>
+ <real>1.9499999284744263</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>glow</key>
+ <array>
+ <real>17.399999618530273</real>
+ <real>0.0010000000474974513</real>
+ <real>-0.64999997615814209</real>
+ <real>1</real>
+ </array>
+ <key>haze_density</key>
+ <array>
+ <real>0.40999999642372131</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>haze_horizon</key>
+ <array>
+ <real>0.17000000178813934</real>
+ <real>0.19915600121021271</real>
+ <real>0.19915600121021271</real>
+ <real>1</real>
+ </array>
+ <key>lightnorm</key>
+ <array>
+ <real>-0.72322052717208862</real>
+ <real>0.12533323466777802</real>
+ <real>-0.67914927005767822</real>
+ <real>0</real>
+ </array>
+ <key>max_y</key>
+ <array>
+ <real>263</real>
+ <real>0</real>
+ <real>0</real>
+ <real>1</real>
+ </array>
+ <key>preset_num</key>
+ <integer>24</integer>
+ <key>star_brightness</key>
+ <real>1.0399999618530273</real>
+ <key>sun_angle</key>
+ <real>0.12566371262073517</real>
+ <key>sunlight_color</key>
+ <array>
+ <real>1.5899999141693115</real>
+ <real>1.5299999713897705</real>
+ <real>0.53999996185302734</real>
+ <real>1.5899999141693115</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/water/Default.xml b/indra/newview/app_settings/windlight/water/Default.xml
new file mode 100644
index 0000000000..dce4148c7d
--- /dev/null
+++ b/indra/newview/app_settings/windlight/water/Default.xml
@@ -0,0 +1,43 @@
+<llsd>
+ <map>
+ <key>blurMultiplier</key>
+ <real>0.040000002831220627</real>
+ <key>fresnelOffset</key>
+ <real>0.5</real>
+ <key>fresnelScale</key>
+ <real>0.39999997615814209</real>
+ <key>normScale</key>
+ <array>
+ <integer>2</integer>
+ <integer>2</integer>
+ <integer>2</integer>
+ </array>
+ <key>normalMap</key>
+ <uuid>822ded49-9a6c-f61c-cb89-6df54f42cdf4</uuid>
+ <key>scaleAbove</key>
+ <real>0.029999999329447746</real>
+ <key>scaleBelow</key>
+ <real>0.20000000298023224</real>
+ <key>underWaterFogMod</key>
+ <real>0.25</real>
+ <key>waterFogColor</key>
+ <array>
+ <real>0.015686275437474251</real>
+ <real>0.14901961386203766</real>
+ <real>0.25098040699958801</real>
+ <real>1</real>
+ </array>
+ <key>waterFogDensity</key>
+ <real>16</real>
+ <key>wave1Dir</key>
+ <array>
+ <real>1.0499997138977051</real>
+ <real>-0.42000007629394531</real>
+ </array>
+ <key>wave2Dir</key>
+ <array>
+ <real>1.1099996566772461</real>
+ <real>-1.1600000858306885</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/water/Glassy.xml b/indra/newview/app_settings/windlight/water/Glassy.xml
new file mode 100644
index 0000000000..01183e4687
--- /dev/null
+++ b/indra/newview/app_settings/windlight/water/Glassy.xml
@@ -0,0 +1,43 @@
+<llsd>
+ <map>
+ <key>blurMultiplier</key>
+ <real>0.003000000026077032089233398</real>
+ <key>fresnelOffset</key>
+ <real>0.579999983310699462890625</real>
+ <key>fresnelScale</key>
+ <real>0.0999999940395355224609375</real>
+ <key>normScale</key>
+ <array>
+ <integer>2</integer>
+ <integer>2</integer>
+ <integer>2</integer>
+ </array>
+ <key>normalMap</key>
+ <uuid>822ded49-9a6c-f61c-cb89-6df54f42cdf4</uuid>
+ <key>scaleAbove</key>
+ <real>0.07999999821186065673828125</real>
+ <key>scaleBelow</key>
+ <real>0.2000000029802322387695312</real>
+ <key>underWaterFogMod</key>
+ <real>0.25</real>
+ <key>waterFogColor</key>
+ <array>
+ <real>0.04999999701976776123046875</real>
+ <real>0.37999999523162841796875</real>
+ <real>0.5299999713897705078125</real>
+ <real>0.5299999713897705078125</real>
+ </array>
+ <key>waterFogDensity</key>
+ <real>1</real>
+ <key>wave1Dir</key>
+ <array>
+ <real>0.5</real>
+ <real>-0.1700000017881393432617188</real>
+ </array>
+ <key>wave2Dir</key>
+ <array>
+ <real>0.579999983310699462890625</real>
+ <real>-0.670000016689300537109375</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/water/Murky.xml b/indra/newview/app_settings/windlight/water/Murky.xml
new file mode 100644
index 0000000000..1d9e022422
--- /dev/null
+++ b/indra/newview/app_settings/windlight/water/Murky.xml
@@ -0,0 +1,43 @@
+<llsd>
+ <map>
+ <key>blurMultiplier</key>
+ <real>0.0030000000260770321</real>
+ <key>fresnelOffset</key>
+ <real>0.39999997615814209</real>
+ <key>fresnelScale</key>
+ <real>0.5</real>
+ <key>normScale</key>
+ <array>
+ <integer>2</integer>
+ <integer>2</integer>
+ <integer>2</integer>
+ </array>
+ <key>normalMap</key>
+ <uuid>822ded49-9a6c-f61c-cb89-6df54f42cdf4</uuid>
+ <key>scaleAbove</key>
+ <real>0.079999998211860657</real>
+ <key>scaleBelow</key>
+ <real>0.20000000298023224</real>
+ <key>underWaterFogMod</key>
+ <real>0.76999998092651367</real>
+ <key>waterFogColor</key>
+ <array>
+ <real>0.08999999612569809</real>
+ <real>0.17000000178813934</real>
+ <real>0.20999999344348907</real>
+ <real>0.20999999344348907</real>
+ </array>
+ <key>waterFogDensity</key>
+ <real>16</real>
+ <key>wave1Dir</key>
+ <array>
+ <real>0.5</real>
+ <real>-0.17000000178813934</real>
+ </array>
+ <key>wave2Dir</key>
+ <array>
+ <real>0.57999998331069946</real>
+ <real>-0.67000001668930054</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/water/Pond.xml b/indra/newview/app_settings/windlight/water/Pond.xml
new file mode 100644
index 0000000000..59e3c441ea
--- /dev/null
+++ b/indra/newview/app_settings/windlight/water/Pond.xml
@@ -0,0 +1,43 @@
+<llsd>
+ <map>
+ <key>blurMultiplier</key>
+ <real>0.0030000000260770321</real>
+ <key>fresnelOffset</key>
+ <real>0.50999999046325684</real>
+ <key>fresnelScale</key>
+ <real>0.099999994039535522</real>
+ <key>normScale</key>
+ <array>
+ <integer>2</integer>
+ <integer>2</integer>
+ <integer>2</integer>
+ </array>
+ <key>normalMap</key>
+ <uuid>822ded49-9a6c-f61c-cb89-6df54f42cdf4</uuid>
+ <key>scaleAbove</key>
+ <real>0.079999998211860657</real>
+ <key>scaleBelow</key>
+ <real>0.20000000298023224</real>
+ <key>underWaterFogMod</key>
+ <real>0.25</real>
+ <key>waterFogColor</key>
+ <array>
+ <real>0.059999998658895493</real>
+ <real>0.37999999523162842</real>
+ <real>0.52999997138977051</real>
+ <real>0.52999997138977051</real>
+ </array>
+ <key>waterFogDensity</key>
+ <real>2.1000001430511475</real>
+ <key>wave1Dir</key>
+ <array>
+ <real>0.5</real>
+ <real>-0.17000000178813934</real>
+ </array>
+ <key>wave2Dir</key>
+ <array>
+ <real>0.57999998331069946</real>
+ <real>-0.67000001668930054</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml b/indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml
new file mode 100644
index 0000000000..6dbc4e8719
--- /dev/null
+++ b/indra/newview/app_settings/windlight/water/SNAKE%21%21%21.xml
@@ -0,0 +1,43 @@
+<llsd>
+ <map>
+ <key>blurMultiplier</key>
+ <real>0.0030000000260770321</real>
+ <key>fresnelOffset</key>
+ <real>0.57999998331069946</real>
+ <key>fresnelScale</key>
+ <real>0.099999994039535522</real>
+ <key>normScale</key>
+ <array>
+ <real>10</real>
+ <real>10</real>
+ <real>10</real>
+ </array>
+ <key>normalMap</key>
+ <uuid>470626e3-ac38-8554-d49b-90311c0176a9</uuid>
+ <key>scaleAbove</key>
+ <real>0.91999995708465576</real>
+ <key>scaleBelow</key>
+ <real>0.93999999761581421</real>
+ <key>underWaterFogMod</key>
+ <real>0.25</real>
+ <key>waterFogColor</key>
+ <array>
+ <real>0.049999997019767761</real>
+ <real>0.37999999523162842</real>
+ <real>0.52999997138977051</real>
+ <real>0.52999997138977051</real>
+ </array>
+ <key>waterFogDensity</key>
+ <real>3.2000000476837158</real>
+ <key>wave1Dir</key>
+ <array>
+ <real>0.5</real>
+ <real>-0.17000000178813934</real>
+ </array>
+ <key>wave2Dir</key>
+ <array>
+ <real>0.57999998331069946</real>
+ <real>-0.67000001668930054</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/water/Second%20Plague.xml b/indra/newview/app_settings/windlight/water/Second%20Plague.xml
new file mode 100644
index 0000000000..137483ab64
--- /dev/null
+++ b/indra/newview/app_settings/windlight/water/Second%20Plague.xml
@@ -0,0 +1,43 @@
+<llsd>
+ <map>
+ <key>blurMultiplier</key>
+ <real>0.017000000923871994</real>
+ <key>fresnelOffset</key>
+ <real>0.37000000476837158</real>
+ <key>fresnelScale</key>
+ <real>0</real>
+ <key>normScale</key>
+ <array>
+ <integer>2</integer>
+ <integer>2</integer>
+ <integer>2</integer>
+ </array>
+ <key>normalMap</key>
+ <uuid>822ded49-9a6c-f61c-cb89-6df54f42cdf4</uuid>
+ <key>scaleAbove</key>
+ <real>0.079999998211860657</real>
+ <key>scaleBelow</key>
+ <real>0.20000000298023224</real>
+ <key>underWaterFogMod</key>
+ <real>0.85999995470046997</real>
+ <key>waterFogColor</key>
+ <array>
+ <real>0.48999997973442078</real>
+ <real>0</real>
+ <real>0</real>
+ <real>0.48999997973442078</real>
+ </array>
+ <key>waterFogDensity</key>
+ <real>20</real>
+ <key>wave1Dir</key>
+ <array>
+ <real>0.5</real>
+ <real>-0.17000000178813934</real>
+ </array>
+ <key>wave2Dir</key>
+ <array>
+ <real>0.57999998331069946</real>
+ <real>-0.67000001668930054</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/app_settings/windlight/water/Valdez.xml b/indra/newview/app_settings/windlight/water/Valdez.xml
new file mode 100644
index 0000000000..eb70a142e0
--- /dev/null
+++ b/indra/newview/app_settings/windlight/water/Valdez.xml
@@ -0,0 +1,43 @@
+<llsd>
+ <map>
+ <key>blurMultiplier</key>
+ <real>0.0020000000949949026</real>
+ <key>fresnelOffset</key>
+ <real>0.28999999165534973</real>
+ <key>fresnelScale</key>
+ <real>0</real>
+ <key>normScale</key>
+ <array>
+ <integer>2</integer>
+ <integer>2</integer>
+ <integer>2</integer>
+ </array>
+ <key>normalMap</key>
+ <uuid>822ded49-9a6c-f61c-cb89-6df54f42cdf4</uuid>
+ <key>scaleAbove</key>
+ <real>0.079999998211860657</real>
+ <key>scaleBelow</key>
+ <real>0.20000000298023224</real>
+ <key>underWaterFogMod</key>
+ <real>1</real>
+ <key>waterFogColor</key>
+ <array>
+ <real>0</real>
+ <real>0</real>
+ <real>0</real>
+ <real>0</real>
+ </array>
+ <key>waterFogDensity</key>
+ <real>1024</real>
+ <key>wave1Dir</key>
+ <array>
+ <real>0.5</real>
+ <real>-0.17000000178813934</real>
+ </array>
+ <key>wave2Dir</key>
+ <array>
+ <real>0.57999998331069946</real>
+ <real>-0.67000001668930054</real>
+ </array>
+ </map>
+</llsd>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index f98b42bba2..8a023de5f6 100644
--- a/indra/newview/featuretable.txt
+++ b/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
// <name> <available> <recommended>
// <name> is the name of a feature
// <available> is 0 or 1, whether the feature is available
-// <recommended> is an S32 which is the recommended value
+// <recommended> is an F32 which is the recommended value
//
// For now, the first list read sets up all of the default values
//
@@ -23,102 +23,197 @@ 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
+
+//
+// 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 +221,110 @@ 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
+RenderTerrainDetail 1 0
+RenderVBOEnable 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_965
+UseOcclusion 0 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
+
+// Avatar hardware skinning causes
+// invisible avatars on x2600... so I masked
+// out other possible bad ones till it's fixed
+list ATI_Radeon_X2400
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+list ATI_Radeon_X2600
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+list ATI_Radeon_X2900
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+list ATI_Radeon_X3800
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+
+list ATI_Radeon_HD_2300
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+list ATI_Radeon_HD_2400
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 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_Mobility_Radeon_X3xx
-VertexShaderEnable 1 0
+list ATI_ASUS_AH24xx
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 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
-list ATI_Mobility_Radeon_X6xx
-VertexShaderEnable 1 0
+list NVIDIA_GeForce_Go_6100
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6200
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6500
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6600
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6700
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6800
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6
+RenderVBOEnable 1 0
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index f31fc0dbb6..ccffc8d424 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/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
// <name> <available> <recommended>
// <name> is the name of a feature
// <available> is 0 or 1, whether the feature is available
-// <recommended> is an S32 which is the recommended value
+// <recommended> is an F32 which is the recommended value
//
// For now, the first list read sets up all of the default values
//
@@ -23,104 +23,197 @@ 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
+
+//
+// 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 +221,100 @@ 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 Radeon8500
-RenderLighting 1 0
-RenderParticleCount 1 4096
+list ATI_Mobility_Radeon_9600
+RenderAvatarCloth 0 0
+VertexShaderEnable 0 0
+WindLightUseAtmosShaders 0 0
-// Hacked to be paranoid "safe"
-list Radeon9700
-RenderParticleCount 1 4096
+// Avatar hardware skinning causes
+// invisible avatars on x2600... so I masked
+// out other possible bad ones till it's fixed
+list ATI_Radeon_X2400
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+list ATI_Radeon_X2600
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+list ATI_Radeon_X2900
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+list ATI_Radeon_X3800
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
-// Hacked to be paranoid "safe"
-list MobilityRadeon9000
-RenderLighting 1 0
-RenderParticleCount 1 4096
+list ATI_Radeon_HD_2300
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+list ATI_Radeon_HD_2400
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 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 GeForceFX
+list NVIDIA_GeForce_Go_6100
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6200
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6500
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6600
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6700
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6800
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6
+RenderVBOEnable 1 0
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index fe5ae7a4ae..bebb51fc12 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/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
// <name> <available> <recommended>
// <name> is the name of a feature
// <available> is 0 or 1, whether the feature is available
-// <recommended> is an S32 which is the recommended value
+// <recommended> is an F32 which is the recommended value
//
// For now, the first list read sets up all of the default values
//
@@ -22,102 +22,199 @@ 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
+
+//
+// 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 +222,94 @@ 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
+RenderTerrainDetail 1 0
+RenderVBOEnable 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
-//
-// ATI settings
-//
-list ATI
+list Intel_965
+UseOcclusion 0 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
+
+// Avatar hardware skinning causes
+// invisible avatars on x2600... so I masked
+// out other possible bad ones till it's fixed
+list ATI_Radeon_X2400
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+list ATI_Radeon_X2600
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+list ATI_Radeon_X2900
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+list ATI_Radeon_X3800
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+
+list ATI_Radeon_HD_2300
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+list ATI_Radeon_HD_2400
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 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 NVIDIA_GeForce_Go_6100
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6200
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6500
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6600
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6700
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6800
+RenderVBOEnable 1 0
+list NVIDIA_GeForce_Go_6
+RenderVBOEnable 1 0
diff --git a/indra/newview/featuretable_solaris.txt b/indra/newview/featuretable_solaris.txt
index 6c7acfa187..7dd7c22cdf 100644
--- a/indra/newview/featuretable_solaris.txt
+++ b/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/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt
index 4b9bf655b5..5d73a70497 100644
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -1,139 +1,193 @@
//
// 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:
-// <chip name> <regexp> <class>
+// <chip name> <regexp> <class> <supported>
//
-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.* 3 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.* 2 1
+ATI Radeon HD 2400 .*ATI.*Radeon HD 24.* 2 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.* 1 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 X2400 .*ATI.*Radeon X24.* 3 1
+ATI Radeon X2600 .*ATI.*Radeon X26.* 3 1
+ATI Radeon X2900 .*ATI.*Radeon X29.* 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 0 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.* 2 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.* 1 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 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/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 7a225fa163..fa94a09a50 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/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\<user>\SecondLife\cache
-; Delete files in Documents and Settings\All Users\SecondLife\cache
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;Function RemoveCacheFiles
-;
-;; Delete files in Documents and Settings\<user>\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\<user>\SecondLife
-; Delete files in Documents and Settings\All Users\SecondLife
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-Function un.DocumentsAndSettingsFolder
-
-; Delete files in Documents and Settings\<user>\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\<user>\SecondLife\cache
+; Delete files in Documents and Settings\All Users\SecondLife\cache
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;Function RemoveCacheFiles
+;
+;; Delete files in Documents and Settings\<user>\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\<user>\SecondLife
+; Delete files in Documents and Settings\All Users\SecondLife
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+Function un.DocumentsAndSettingsFolder
+
+; Delete files in Documents and Settings\<user>\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/indra/newview/licenses-linux.txt b/indra/newview/licenses-linux.txt
index 795b7cc3df..b43c402e64 100644
--- a/indra/newview/licenses-linux.txt
+++ b/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/indra/newview/licenses-mac.txt b/indra/newview/licenses-mac.txt
index e87d244141..d488c7487e 100644
--- a/indra/newview/licenses-mac.txt
+++ b/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/indra/newview/licenses-solaris.txt b/indra/newview/licenses-solaris.txt
index 792330f706..c19f939a80 100644
--- a/indra/newview/licenses-solaris.txt
+++ b/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/indra/newview/licenses-win32.txt b/indra/newview/licenses-win32.txt
index 3d9ef9b3b5..5f6cf14c05 100644
--- a/indra/newview/licenses-win32.txt
+++ b/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/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index a5cb6ae8a7..e7c47cbba6 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/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
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index bd885f955c..156b4a395d 100644
--- a/indra/newview/llagent.cpp
+++ b/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);
@@ -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<LLViewerObject> >::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
@@ -4316,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<LLViewerObject> fade_object_ptr(mFocusObject);
-
- if (fade_object_ptr.notNull() && mFadeObjects.find(fade_object_ptr) == mFadeObjects.end())
- {
- mFadeObjects.insert(fade_object_ptr);
- }
- }
-
mFocusObject = object;
}
@@ -5783,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");
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 1b21a71212..6fe978b6cb 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -841,7 +841,6 @@ private:
U8 mGodLevel;
LLFrameTimer mFidgetTimer;
LLFrameTimer mFocusObjectFadeTimer;
- std::set<LLPointer <LLViewerObject> > mFadeObjects;
F32 mNextFidgetTime;
S32 mCurrentFidget;
BOOL mFirstLogin;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index fe1d93c7bc..106b2b1517 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -100,6 +100,9 @@
#include "lltracker.h"
#include "llviewerparcelmgr.h"
#include "llworldmapview.h"
+#include "llpostprocess.h"
+#include "llwlparammanager.h"
+#include "llwaterparammanager.h"
#include "lldebugview.h"
#include "llconsole.h"
@@ -127,6 +130,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"
@@ -458,8 +464,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");
@@ -492,6 +496,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())
{
@@ -1009,13 +1018,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);
@@ -1260,26 +1262,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);
@@ -1337,6 +1377,7 @@ bool LLAppViewer::mainLoop()
debugTime.reset();
}
#endif
+
if (!LLApp::isExiting())
{
// Scan keyboard for movement keys. Command keys and typing
@@ -1434,7 +1475,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)
{
@@ -1620,7 +1661,11 @@ bool LLAppViewer::cleanup()
LLSelectMgr::cleanupGlobals();
LLViewerObject::cleanupVOClasses();
-
+
+ LLWaterParamManager::cleanupClass();
+ LLWLParamManager::cleanupClass();
+ LLPostProcess::cleanupClass();
+
LLTracker::cleanupInstance();
// *FIX: This is handled in LLAppViewerWin32::cleanup().
@@ -2316,16 +2361,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");
- //
- // 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);
@@ -3268,8 +3330,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));
@@ -3372,8 +3433,6 @@ void LLAppViewer::idle()
// Update statistics for this frame
update_statistics(gFrameCount);
-
- gViewerWindow->updateDebugText();
}
////////////////////////////////////////
@@ -3403,11 +3462,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();
@@ -3415,19 +3470,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();
@@ -3444,11 +3486,6 @@ void LLAppViewer::idle()
}
}
- {
- LLFastTimer t(LLFastTimer::FTM_UPDATE_SKY);
- gSky.updateSky();
- }
-
//////////////////////////////////////
//
// Deletes objects...
@@ -3476,8 +3513,6 @@ void LLAppViewer::idle()
//
{
- //LLFastTimer t(LLFastTimer::FTM_TEMP3);
-
gFrameStats.start(LLFrameStats::UPDATE_EFFECTS);
gSelectMgr->updateEffects();
gHUDManager->cleanupEffects();
@@ -3552,16 +3587,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();
+ }
//////////////////////////////////////
//
@@ -3571,6 +3608,7 @@ void LLAppViewer::idle()
if (!gNoRender)
{
+ LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE);
gFrameStats.start(LLFrameStats::UPDATE_MOVE);
gPipeline.updateMove();
diff --git a/indra/newview/llbox.cpp b/indra/newview/llbox.cpp
index 6f0edf717e..d0505b6b06 100644
--- a/indra/newview/llbox.cpp
+++ b/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/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 108e2cafe0..0e0880959e 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/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);
@@ -452,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()
diff --git a/indra/newview/llcloud.cpp b/indra/newview/llcloud.cpp
index b3b6b411ab..ee793bf6e4 100644
--- a/indra/newview/llcloud.cpp
+++ b/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; j<CLOUD_GRIDS_PER_EDGE-1; j++)
-// {
-// y = j * mMetersPerGrid;
-
-// for(i=0; i<CLOUD_GRIDS_PER_EDGE; i++)
-// {
-// k = i + j*CLOUD_GRIDS_PER_EDGE;
-// x = i * mMetersPerGrid;
-
-// z = 0.5f * CLOUD_MAX_HEIGHT + 40.0f * *(mDensityp + k + CLOUD_GRIDS_PER_EDGE);
-// glColor3f(1.0f - *(mDensityp + k + CLOUD_GRIDS_PER_EDGE), *(mDensityp + k + CLOUD_GRIDS_PER_EDGE), 0.0f);
-// glVertex3f(x, y+mMetersPerGrid, z);
-
-// z = 0.5f * CLOUD_MAX_HEIGHT + 40.0f * *(mDensityp + k);
-// glColor3f(1.0f - *(mDensityp + k), *(mDensityp + k), 0.0f);
-// glVertex3f(x, y, z);
-
-// z = 0.5f * CLOUD_MAX_HEIGHT + 40.0f * *(mDensityp + k + 1);
-// glColor3f(1.0f - *(mDensityp + k + 1), *(mDensityp + k + 1), 0.0f);
-// glVertex3f(x+mMetersPerGrid, y, z);
-
-// }
-// }
-// glEnd();
-}
-
-
void LLCloudLayer::decompress(LLBitPack &bitpack, LLGroupHeader *group_headerp)
{
LLPatchHeader patch_header;
diff --git a/indra/newview/llcloud.h b/indra/newview/llcloud.h
index 1943cac2c2..4d5f652361 100644
--- a/indra/newview/llcloud.h
+++ b/indra/newview/llcloud.h
@@ -175,7 +175,6 @@ public:
F32 getDensityRegion(const LLVector3 &pos_region); // "position" is in local coordinates
- void renderDensityField();
void decompress(LLBitPack &bitpack, LLGroupHeader *group_header);
LLCloudLayer* getNeighbor(const S32 n) const { return mNeighbors[n]; }
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index b2b29ffc9f..caf506a21e 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -39,6 +39,7 @@
// Project includes
#include "llui.h"
+#include "llglimmediate.h"
#include "lluiconstants.h"
#include "llviewerwindow.h"
#include "llviewercontrol.h"
@@ -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
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 17593766b9..fd36ed666d 100644
--- a/indra/newview/lldrawable.cpp
+++ b/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<std::pair<F32,LLPointer<LLDrawable> > > 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<LLDrawable>* node)
{
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
- group->clearState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED);
+ group->setVisible();
LLOctreeTraveler<LLDrawable>::traverse(node);
}
- void visit(const LLOctreeState<LLDrawable>* branch)
+ void visit(const LLOctreeNode<LLDrawable>* 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<LLDrawable*>*
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<LLDrawable*>*
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/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 52082ad5b5..9a0dafe77b 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -83,7 +83,7 @@ public:
virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* 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<LLViewerObject>& 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<LLDrawable> 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<LLFace*> 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/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 9875221495..c987f3e035 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/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<LLFace*>::iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- LLFace *face = *iter;
-
- S32 geom_count = face->getGeomCount();
- for (S32 j=0;j<geom_count;j++)
- {
- LLVector3 p1;
- LLVector3 p2;
-
- intptr_t p = ((intptr_t)face*13) % 7;
- F32 r = table[p][0];
- F32 g = table[p][1];
- F32 b = table[p][2];
-
- //p1.mV[1] = y;
- //p2.mV[1] = y;
-
- p1.mV[2] = 1.0;
- p2.mV[2] = 1.0;
-
- glColor4f(r,g,b,0.5f);
-
- glBegin(GL_LINE_STRIP);
- glVertex3fv(p1.mV);
- glVertex3fv(p2.mV);
- glEnd();
-
- }
- }
-
- glColor4f(1,1,1,1);
- glBegin(GL_LINE_STRIP);
- 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();
-
- glPopMatrix();
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
-
-}
-
void LLFacePool::enqueue(LLFace* facep)
{
mDrawFace.push_back(facep);
@@ -411,38 +324,17 @@ BOOL LLFacePool::LLOverrideFaceColor::sOverrideFaceColor = FALSE;
void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color)
{
- if (mPool->getVertexShaderLevel() > 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 &params = *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/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index cd85a55d34..30a16a24ba 100644
--- a/indra/newview/lldrawpool.h
+++ b/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/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 0cba2c2923..4428854369 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/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<LLSpatialGroup*>& 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<LLSpatialGroup*>& 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<LLSpatialGroup*>& 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<LLSpatialGroup*>::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<LLSpatialGroup*>& 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<LLSpatialGroup*>::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::vector<LLSpatialGroup*
{
continue;
}
+
+ LLRenderPass::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);
-
- 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/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index 0e39003551..637ea25f80 100644
--- a/indra/newview/lldrawpoolalpha.h
+++ b/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<LLSpatialGroup*>& groups);
/*virtual*/ void prerender();
void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
- void renderAlpha(U32 mask, std::vector<LLSpatialGroup*>& groups);
- void renderAlphaHighlight(U32 mask, std::vector<LLSpatialGroup*>& 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/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 9df9c11531..316c002c1b 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/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/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index 1aa91bb69a..2de32de542 100644
--- a/indra/newview/lldrawpoolavatar.h
+++ b/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/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 4de13a3d88..f4bc157168 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/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/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h
index 15d84639fe..ae722b2fd3 100644
--- a/indra/newview/lldrawpoolbump.h
+++ b/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/indra/newview/lldrawpoolclouds.h b/indra/newview/lldrawpoolclouds.h
index e155acfb9e..1047afb8e5 100644
--- a/indra/newview/lldrawpoolclouds.h
+++ b/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/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp
index d84f0959bf..31c4e4fde9 100644
--- a/indra/newview/lldrawpoolground.cpp
+++ b/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/indra/newview/lldrawpoolground.h b/indra/newview/lldrawpoolground.h
index a804c904fa..fa73314de1 100644
--- a/indra/newview/lldrawpoolground.h
+++ b/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/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index 0a5d4576d8..174a9ac427 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/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/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h
index ff12610d2a..d2ad5124a6 100644
--- a/indra/newview/lldrawpoolsimple.h
+++ b/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/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index 677a563198..9276ee50e1 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/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/indra/newview/lldrawpoolsky.h b/indra/newview/lldrawpoolsky.h
index ceabde3d9d..1941e9f1a0 100644
--- a/indra/newview/lldrawpoolsky.h
+++ b/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/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index b48de1db85..d8ebf33d38 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/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<LLFace*>::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/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index dc95d7d4c4..91464a8a6a 100644
--- a/indra/newview/lldrawpoolterrain.h
+++ b/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<LLViewerImage*>& textures);
/*virtual*/ LLViewerImage *getTexture();
@@ -68,8 +70,6 @@ public:
LLPointer<LLViewerImage> m2DAlphaRampImagep;
LLPointer<LLViewerImage> 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/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index c8e0ff2052..f70904eba4 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/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/indra/newview/lldrawpooltree.h b/indra/newview/lldrawpooltree.h
index 7dee2382b2..c414ebcea9 100644
--- a/indra/newview/lldrawpooltree.h
+++ b/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/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index d7fc716c55..ca2f5ebb86 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/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<LLFace*>::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<LLFace*>::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/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index 24346c4a5f..d9b91db85c 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/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/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
new file mode 100644
index 0000000000..e080e4e29b
--- /dev/null
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -0,0 +1,343 @@
+/**
+ * @file lldrawpoolwlsky.cpp
+ * @brief LLDrawPoolWLSky class implementation
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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<LLImageGL> LLDrawPoolWLSky::sCloudNoiseTexture = NULL;
+
+LLPointer<LLImageRaw> 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<LLImageFormatted> 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/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h
new file mode 100644
index 0000000000..7e2137ffee
--- /dev/null
+++ b/indra/newview/lldrawpoolwlsky.h
@@ -0,0 +1,84 @@
+/**
+ * @file lldrawpoolwlsky.h
+ * @brief LLDrawPoolWLSky class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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<LLImageGL> sCloudNoiseTexture;
+ static LLPointer<LLImageRaw> sCloudNoiseRawImage;
+};
+
+#endif // LL_DRAWPOOLWLSKY_H
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 8f6b572a9d..a4b3d259bb 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -40,7 +40,10 @@
#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> LLDynamicTexture::sInstances[ LLDynamicTexture::ORDER_COUNT ];
@@ -216,15 +219,22 @@ BOOL LLDynamicTexture::updateAllInstances()
dynamicTexture = LLDynamicTexture::sInstances[order].getNextData())
{
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/indra/newview/llface.cpp b/indra/newview/llface.cpp
index be19b30c7b..3e8d518c02 100644
--- a/indra/newview/llface.cpp
+++ b/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<LLVector3> &vertices,
LLStrider<LLVector3> &normals,
- LLStrider<LLVector3> &binormals,
LLStrider<LLVector2> &tex_coords,
LLStrider<F32> &vertex_weights,
LLStrider<LLVector4> &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<LLVector3> &vertices,
- LLStrider<LLVector3> &normals,
- LLStrider<LLColor4U> &colors,
- LLStrider<LLVector2> &texcoords0,
- LLStrider<LLVector2> &texcoords1,
- LLStrider<U32> &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<LLVector3> &vertices, LLStrider<LLVector3> &normals,
- LLStrider<LLVector2> &tex_coords, LLStrider<U32> &indicesp)
+U16 LLFace::getGeometry(LLStrider<LLVector3> &vertices, LLStrider<LLVector3> &normals,
+ LLStrider<LLVector2> &tex_coords, LLStrider<U16> &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<LLVector3> &vertices, LLStrider<LLVector3> &no
mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
}
- else
- {
- mGeomIndex = -1;
- }
return mGeomIndex;
}
-S32 LLFace::getGeometryColors(LLStrider<LLVector3> &vertices, LLStrider<LLVector3> &normals,
- LLStrider<LLVector2> &tex_coords, LLStrider<LLColor4U> &colors,
- LLStrider<U32> &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<LLVector3>& vertices,
- LLStrider<LLVector3>& normals,
- LLStrider<LLVector2>& tex_coords,
- LLStrider<LLVector2>& tex_coords2,
- LLStrider<LLColor4U>& colors,
- LLStrider<U32>& 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<LLVector3> old_verts;
- LLStrider<LLVector2> old_texcoords;
- LLStrider<LLVector2> old_texcoords2;
- LLStrider<LLVector3> old_normals;
- LLStrider<LLColor4U> 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<LLVector3> old_verts,vertices;
+ LLStrider<LLVector2> old_texcoords,tex_coords;
+ LLStrider<LLVector2> old_texcoords2,tex_coords2;
+ LLStrider<LLVector3> old_normals,normals;
+ LLStrider<LLColor4U> old_colors,colors;
+ LLStrider<U16> 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<LLColor4U> 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<LLColor4U> 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<LLVector3> &vertices)
-{
- if (!mGeomCount)
- {
- return -1;
- }
-
- if (mGeomIndex >= 0) // flexible objects may not have geometry
- {
- mVertexBuffer->getVertexStrider(vertices, mGeomIndex);
-
- }
- return mGeomIndex;
-}
-
S32 LLFace::getColors(LLStrider<LLColor4U> &colors)
{
if (!mGeomCount)
@@ -1526,15 +1325,15 @@ S32 LLFace::getColors(LLStrider<LLColor4U> &colors)
return -1;
}
- llassert(mGeomIndex >= 0);
+ // llassert(mGeomIndex >= 0);
mVertexBuffer->getColorStrider(colors, mGeomIndex);
return mGeomIndex;
}
-S32 LLFace::getIndices(LLStrider<U32> &indicesp)
+S32 LLFace::getIndices(LLStrider<U16> &indicesp)
{
mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
- llassert(mGeomIndex >= 0 && indicesp[0] != indicesp[1]);
+ llassert(indicesp[0] != indicesp[1]);
return mIndicesIndex;
}
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 2a732ee51d..6142ba6672 100644
--- a/indra/newview/llface.h
+++ b/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<LLVector3>& vertices,
- LLStrider<LLVector3>& normals,
- LLStrider<LLVector2>& texcoords,
- LLStrider<LLVector2>& texcoords2,
- LLStrider<LLColor4U>& colors,
- LLStrider<U32>& 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<LLVector3> &vertices,
LLStrider<LLVector3> &normals,
- LLStrider<LLVector3> &binormals,
LLStrider<LLVector2> &texCoords,
LLStrider<F32> &vertex_weights,
LLStrider<LLVector4> &clothing_weights);
- // For terrain
- S32 getGeometryTerrain(LLStrider<LLVector3> &vertices,
- LLStrider<LLVector3> &normals,
- LLStrider<LLColor4U> &colors,
- LLStrider<LLVector2> &texCoords0,
- LLStrider<LLVector2> &texCoords1,
- LLStrider<U32> &indices);
-
// For volumes, etc.
- S32 getGeometry(LLStrider<LLVector3> &vertices,
+ U16 getGeometry(LLStrider<LLVector3> &vertices,
LLStrider<LLVector3> &normals,
LLStrider<LLVector2> &texCoords,
- LLStrider<U32> &indices);
+ LLStrider<U16> &indices);
- S32 getGeometryColors(LLStrider<LLVector3> &vertices,
- LLStrider<LLVector3> &normals,
- LLStrider<LLVector2> &texCoords,
- LLStrider<LLColor4U> &colors,
- LLStrider<U32> &indices);
-
- S32 getVertices(LLStrider<LLVector3> &vertices);
S32 getColors(LLStrider<LLColor4U> &colors);
- S32 getIndices(LLStrider<U32> &indices);
+ S32 getIndices(LLStrider<U16> &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<LLVertexBuffer> mVertexBuffer;
LLPointer<LLVertexBuffer> 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<LLViewerImage> 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/indra/newview/llface.inl b/indra/newview/llface.inl
index 71f0638d45..aa94493196 100644
--- a/indra/newview/llface.inl
+++ b/indra/newview/llface.inl
@@ -69,87 +69,6 @@ inline LLViewerObject* LLFace::getViewerObject() const
return mVObjp;
}
-
-
-inline S32 LLFace::getVertices(LLStrider<LLVector3> &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<LLVector3> &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<LLVector3> &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<LLColor4U> &colors)
{
if (!mGeomCount)
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 7c1ec514e5..e29d8fb40d 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/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_SIMULATE_PARTICLES, " Particle Sim", &LLColor4::blue4, 0 },
{ LLFastTimer::FTM_OBJECTLIST_UPDATE, " Object Update", &LLColor4::purple1, 0 },
{ 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, 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_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,16 @@ 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},
-
+
{ LLFastTimer::FTM_TEMP1, " Temp1", &LLColor4::red1, 0 },
{ LLFastTimer::FTM_TEMP2, " Temp2", &LLColor4::magenta1, 0 },
{ LLFastTimer::FTM_TEMP3, " Temp3", &LLColor4::red2, 0 },
@@ -211,6 +214,7 @@ LLFastTimerView::LLFastTimerView(const std::string& name, const LLRect& rect)
mMaxCountTotal = 0;
mDisplayCenter = 1;
mDisplayCalls = 0;
+ mDisplayHz = 0;
mScrollIndex = 0;
mHoverIndex = -1;
mHoverBarIndex = -1;
@@ -322,9 +326,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)
{
@@ -756,7 +768,7 @@ 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;
@@ -921,7 +933,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);
@@ -948,6 +960,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;
@@ -955,7 +969,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;
@@ -966,7 +980,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)
@@ -974,12 +988,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();
}
}
@@ -994,10 +1008,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;
@@ -1010,30 +1025,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);
}
}
@@ -1046,7 +1069,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/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h
index 7e461ec778..d47cc003ac 100644
--- a/indra/newview/llfasttimerview.h
+++ b/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/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index d957a3783a..561d96d281 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -34,6 +34,8 @@
#include "llviewerprecompiledheaders.h"
+#include <boost/regex.hpp>
+
#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 <list> 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<char>("\t\n"));
+ boost_tokenizer::iterator token_iter = tokens.begin();
+
+ // 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 == NULL || expr == NULL || cls == NULL)
+ 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,128 @@ 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::applyRecommendedSettings()
+{
+ // 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;
-void LLFeatureManager::initCPUFeatureMasks()
+ setGraphicsLevel(level, false);
+ gSavedSettings.setU32("RenderQualityPerformance", level);
+ gSavedSettings.setBOOL("RenderCustomSettings", FALSE);
+
+}
+
+void LLFeatureManager::applyFeatures(bool skipFeatures)
{
- if (gSysMemory.getPhysicalMemoryClamped() <= 256*1024*1024)
- {
- maskFeatures("RAM256MB");
- }
-
-#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)
+ // 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 +554,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 +593,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 +604,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/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index 21d1ee0f91..26d491b96f 100644
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -38,11 +38,20 @@
#include "llskipmap.h"
#include <map>
+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 +59,38 @@ public:
BOOL mValid;
LLString mName;
BOOL mAvailable;
- S32 mRecommendedLevel;
+ F32 mRecommendedLevel;
};
class LLFeatureList
{
public:
+ typedef std::map<LLString, LLFeatureInfo> 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<LLString, LLFeatureInfo> feature_map_t;
feature_map_t mFeatures;
};
@@ -83,14 +98,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 +121,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<LLString, LLFeatureList *> mMaskList;
+ std::set<LLString> 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/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 757cbccb59..f69f66bce2 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/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<<mRenderRes;
- path->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/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h
index fe20235feb..d4b79fb536 100644
--- a/indra/newview/llflexibleobject.h
+++ b/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/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index 2eddb45f23..d966f0d3c8 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/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"
@@ -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();
@@ -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;
}
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index 094cbb6c33..f1bba7d9c5 100644
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -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/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 137b35c3ee..19793550cc 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/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,37 +545,37 @@ 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(getDragHandle()))
@@ -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;
@@ -1162,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/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h
index abfe4c1679..a0f378053b 100644
--- a/indra/newview/llfloatercolorpicker.h
+++ b/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/indra/newview/llfloaterdaycycle.cpp b/indra/newview/llfloaterdaycycle.cpp
new file mode 100644
index 0000000000..67694f49c2
--- /dev/null
+++ b/indra/newview/llfloaterdaycycle.cpp
@@ -0,0 +1,612 @@
+/**
+ * @file llfloaterdaycycle.cpp
+ * @brief LLFloaterDayCycle class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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<LLString, LLWLSkyKey> 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<std::string, LLWLParamSet>::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<std::string, LLVector4> & 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<F32, std::string>::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<LLString, LLWLSkyKey>::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<LLString, LLWLSkyKey>(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<LLString, LLWLSkyKey>::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<LLString, LLWLSkyKey>::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/indra/newview/llfloaterdaycycle.h b/indra/newview/llfloaterdaycycle.h
new file mode 100644
index 0000000000..91a649b97c
--- /dev/null
+++ b/indra/newview/llfloaterdaycycle.h
@@ -0,0 +1,146 @@
+/**
+ * @file llfloaterdaycycle.h
+ * @brief LLFloaterDayCycle class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <vector>
+#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<LLString, LLWLSkyKey> sSliderToKey;
+
+ static const F32 sHoursPerDay;
+};
+
+
+#endif
diff --git a/indra/newview/llfloaterenvsettings.cpp b/indra/newview/llfloaterenvsettings.cpp
new file mode 100644
index 0000000000..197e2ba15e
--- /dev/null
+++ b/indra/newview/llfloaterenvsettings.cpp
@@ -0,0 +1,384 @@
+/**
+ * @file llfloaterenvsettings.cpp
+ * @brief LLFloaterEnvSettings class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <sstream>
+
+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<LLFloaterEnvSettings*>(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<LLColorSwatchCtrl>("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<WaterExpFloatControl *>(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<LLColorSwatchCtrl*>(ctrl);
+ WaterColorControl * colorControl = static_cast<WaterColorControl *>(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/indra/newview/llfloaterenvsettings.h b/indra/newview/llfloaterenvsettings.h
new file mode 100644
index 0000000000..2ac555083e
--- /dev/null
+++ b/indra/newview/llfloaterenvsettings.h
@@ -0,0 +1,106 @@
+/**
+ * @file llfloaterskysettings.h
+ * @brief LLFloaterEnvSettings class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp
new file mode 100644
index 0000000000..00dcf67453
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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/indra/newview/llfloaterhardwaresettings.h b/indra/newview/llfloaterhardwaresettings.h
new file mode 100644
index 0000000000..0f5f2fee05
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 53779b6970..eb5ee352b9 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/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/indra/newview/llfloaterpostprocess.cpp b/indra/newview/llfloaterpostprocess.cpp
new file mode 100644
index 0000000000..33704fc720
--- /dev/null
+++ b/indra/newview/llfloaterpostprocess.cpp
@@ -0,0 +1,273 @@
+/**
+ * @file llfloaterpostprocess.cpp
+ * @brief LLFloaterPostProcess class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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<LLCheckBoxCtrl*>(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<LLSliderCtrl*>(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<LLSliderCtrl*>(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<LLSliderCtrl*>(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<LLSliderCtrl*>(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<LLSliderCtrl*>(ctrl);
+ gPostProcess->tweaks[floatVariableName][3] = sldrCtrl->getValue();
+}
+
+void LLFloaterPostProcess::onLoadEffect(void* userData)
+{
+ LLComboBox* comboBox = static_cast<LLComboBox*>(userData);
+
+ LLSD::String effectName(comboBox->getSelectedValue().asString());
+
+ gPostProcess->setSelectedEffect(effectName);
+
+ sPostProcess->syncMenu();
+}
+
+void LLFloaterPostProcess::onSaveEffect(void* userData)
+{
+ LLLineEditor* editBox = static_cast<LLLineEditor*>(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<LLComboBox*>(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<LLLineEditor*>(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/indra/newview/llfloaterpostprocess.h b/indra/newview/llfloaterpostprocess.h
new file mode 100644
index 0000000000..8b590f8b8e
--- /dev/null
+++ b/indra/newview/llfloaterpostprocess.h
@@ -0,0 +1,90 @@
+/**
+ * @file llfloaterpostprocess.h
+ * @brief LLFloaterPostProcess class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index cac2d0a0b6..584d7479e4 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/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
@@ -133,7 +134,6 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainer* tab_container, LLButton * def
mInputPanel(NULL),
mNetworkPanel(NULL),
mDisplayPanel(NULL),
- mDisplayPanel2(NULL),
mAudioPanel(NULL),
mMsgPanel(NULL),
mLCDPanel(NULL)
@@ -158,14 +158,6 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainer* tab_container, LLButton * def
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);
@@ -225,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;
@@ -269,12 +252,14 @@ void LLPreferenceCore::apply()
mInputPanel->apply();
mNetworkPanel->apply();
mDisplayPanel->apply();
- mDisplayPanel2->apply();
- mDisplayPanel3->apply();
mPrefsChat->apply();
mPrefsVoice->apply();
mPrefsIM->apply();
mMsgPanel->apply();
+
+ // hardware menu apply
+ LLFloaterHardwareSettings::instance()->apply();
+
mWebPanel->apply();
#if LL_WINDOWS && LL_LCD_COMPILE
// only add this option if we actually have a logitech keyboard / speaker set
@@ -293,13 +278,15 @@ void LLPreferenceCore::cancel()
mInputPanel->cancel();
mNetworkPanel->cancel();
mDisplayPanel->cancel();
- mDisplayPanel2->cancel();
- mDisplayPanel3->cancel();
mAudioPanel->cancel();
mPrefsChat->cancel();
mPrefsVoice->cancel();
mPrefsIM->cancel();
mMsgPanel->cancel();
+
+ // cancel hardware menu
+ LLFloaterHardwareSettings::instance()->cancel();
+
mWebPanel->cancel();
#if LL_WINDOWS && LL_LCD_COMPILE
// only add this option if we actually have a logitech keyboard / speaker set
@@ -328,6 +315,12 @@ void LLPreferenceCore::setPersonalInfo(
mPrefsIM->setPersonalInfo(visibility, im_via_email, email);
}
+void LLPreferenceCore::refreshEnabledGraphics()
+{
+ LLFloaterHardwareSettings::instance()->refreshEnabledState();
+ mDisplayPanel->refreshEnabledState();
+}
+
//////////////////////////////////////////////
// LLFloaterPreference
@@ -521,3 +514,8 @@ void LLFloaterPreference::updateUserInfo(
visibility, im_via_email, email);
}
}
+
+void LLFloaterPreference::refreshEnabledGraphics()
+{
+ sInstance->mPreferenceCore->refreshEnabledGraphics();
+}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 7396467d8c..52592c0bad 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/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;
@@ -76,6 +74,9 @@ public:
const char* email);
static void onTabChanged(void* user_data, bool from_click);
+
+ // refresh all the graphics preferences menus
+ void refreshEnabledGraphics();
private:
LLTabContainer *mTabContainer;
@@ -83,8 +84,6 @@ private:
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/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 4a3b2192c0..375523cc39 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/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"
@@ -1436,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)
@@ -2010,6 +2024,9 @@ BOOL LLPanelEstateInfo::postBuild()
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");
@@ -2069,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();
}
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index cdda7e532c..6ef276a739 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -257,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);
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 63d7d7b958..7dc404cab1 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -861,7 +861,7 @@ void LLFloaterReporter::takeScreenshot()
const S32 IMAGE_HEIGHT = 768;
LLPointer<LLImageRaw> 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;
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index d2f3bc7cf5..d9694a7b3f 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/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<LLImageRaw> mRawImage;
LLPointer<LLImageRaw> mRawImageEncoded;
@@ -161,6 +166,7 @@ protected:
public:
static std::set<LLSnapshotLivePreview*> sList;
+ BOOL mKeepAspectRatio ;
};
std::set<LLSnapshotLivePreview*> 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];
@@ -223,7 +244,7 @@ F32 LLSnapshotLivePreview::getImageAspect()
F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]);
F32 window_aspect_ratio = ((F32)getRect().getWidth()) / ((F32)getRect().getHeight());
- if (gSavedSettings.getBOOL("KeepAspectForSnapshot"))
+ if (!mKeepAspectRatio)//gSavedSettings.getBOOL("KeepAspectForSnapshot"))
{
return image_aspect_ratio;
}
@@ -267,7 +288,7 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot)
F32 image_aspect_ratio = ((F32)mWidth[mCurImageIndex]) / ((F32)mHeight[mCurImageIndex]);
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)
{
@@ -320,9 +341,8 @@ void LLSnapshotLivePreview::draw()
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,25 +350,25 @@ 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);
+ gGL.color4f(1.f, 1.f, 1.f, mFlashAlpha);
gl_rect_2d(getRect());
if (mNeedsFlash)
{
@@ -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
@@ -472,21 +490,21 @@ void LLSnapshotLivePreview::draw()
LLRect& rect = mImageRect[old_image_index];
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();
}
@@ -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,6 +759,7 @@ 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);
@@ -743,12 +767,14 @@ public:
static void updateLayout(LLFloaterSnapshot* floater);
static LLHandle<LLView> 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<LLAnimPauseRequest> mAvatarPauseHandles;
@@ -759,6 +785,8 @@ public:
// static
LLHandle<LLView> LLFloaterSnapshot::Impl::sPreviewHandle;
+//static
+BOOL LLFloaterSnapshot::Impl::sAspectRatioCheckOff = FALSE ;
// static
LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater)
{
@@ -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->getRect().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->getRect().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;
@@ -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");
@@ -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);
@@ -1354,7 +1692,7 @@ 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
@@ -1382,7 +1720,7 @@ 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
@@ -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((getRect().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/indra/newview/llfloaterwater.cpp b/indra/newview/llfloaterwater.cpp
new file mode 100644
index 0000000000..0b02ea2623
--- /dev/null
+++ b/indra/newview/llfloaterwater.cpp
@@ -0,0 +1,735 @@
+/**
+ * @file llfloaterwater.cpp
+ * @brief LLFloaterWater class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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<std::string> 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<std::string, LLWaterParamSet>::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<char>(":"));
+ 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, &param_mgr->mFogColor);
+
+ //
+ childSetCommitCallback("WaterGlow", onColorControlAMoved, &param_mgr->mFogColor);
+
+ // fog density
+ childSetCommitCallback("WaterFogDensity", onExpFloatControlMoved, &param_mgr->mFogDensity);
+ childSetCommitCallback("WaterUnderWaterFogMod", onFloatControlMoved, &param_mgr->mUnderWaterFogMod);
+
+ // blue density
+ childSetCommitCallback("WaterNormalScaleX", onVector3ControlXMoved, &param_mgr->mNormalScale);
+ childSetCommitCallback("WaterNormalScaleY", onVector3ControlYMoved, &param_mgr->mNormalScale);
+ childSetCommitCallback("WaterNormalScaleZ", onVector3ControlZMoved, &param_mgr->mNormalScale);
+
+ // fresnel
+ childSetCommitCallback("WaterFresnelScale", onFloatControlMoved, &param_mgr->mFresnelScale);
+ childSetCommitCallback("WaterFresnelOffset", onFloatControlMoved, &param_mgr->mFresnelOffset);
+
+ // scale above/below
+ childSetCommitCallback("WaterScaleAbove", onFloatControlMoved, &param_mgr->mScaleAbove);
+ childSetCommitCallback("WaterScaleBelow", onFloatControlMoved, &param_mgr->mScaleBelow);
+
+ // blur mult
+ childSetCommitCallback("WaterBlurMult", onFloatControlMoved, &param_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, &param_mgr->mWave1Dir);
+ childSetCommitCallback("WaterWave1DirY", onVector2ControlYMoved, &param_mgr->mWave1Dir);
+ childSetCommitCallback("WaterWave2DirX", onVector2ControlXMoved, &param_mgr->mWave2Dir);
+ childSetCommitCallback("WaterWave2DirY", onVector2ControlYMoved, &param_mgr->mWave2Dir);
+
+ comboBox->setCommitCallback(onChangePresetName);
+
+ LLTextureCtrl* textCtrl = getChild<LLTextureCtrl>("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<std::string, LLWaterParamSet>::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<LLColorSwatchCtrl>("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<LLTextureCtrl>("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<LLSliderCtrl*>(ctrl);
+ WaterVector3Control * vectorControl = static_cast<WaterVector3Control *>(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<LLSliderCtrl*>(ctrl);
+ WaterVector3Control * vectorControl = static_cast<WaterVector3Control *>(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<LLSliderCtrl*>(ctrl);
+ WaterVector3Control * vectorControl = static_cast<WaterVector3Control *>(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<LLSliderCtrl*>(ctrl);
+ WaterVector2Control * vectorControl = static_cast<WaterVector2Control *>(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<LLSliderCtrl*>(ctrl);
+ WaterVector2Control * vectorControl = static_cast<WaterVector2Control *>(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<LLSliderCtrl*>(ctrl);
+ WaterColorControl * colorControl = static_cast<WaterColorControl *>(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<LLSliderCtrl*>(ctrl);
+ WaterColorControl * colorControl = static_cast<WaterColorControl *>(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<LLSliderCtrl*>(ctrl);
+ WaterColorControl * colorControl = static_cast<WaterColorControl *>(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<LLSliderCtrl*>(ctrl);
+ WaterColorControl * colorControl = static_cast<WaterColorControl *>(userData);
+
+ colorControl->mA = sldrCtrl->getValueF32();
+
+ colorControl->update(LLWaterParamManager::instance()->mCurParams);
+
+ LLWaterParamManager::instance()->propagateParameters();
+}
+
+
+void LLFloaterWater::onColorControlIMoved(LLUICtrl* ctrl, void* userData)
+{
+ LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
+ WaterColorControl * colorControl = static_cast<WaterColorControl *>(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<LLSliderCtrl*>(ctrl);
+ WaterExpFloatControl * expFloatControl = static_cast<WaterExpFloatControl *>(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<LLSliderCtrl*>(ctrl);
+ WaterFloatControl * floatControl = static_cast<WaterFloatControl *>(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<LLColorSwatchCtrl*>(ctrl);
+ WaterColorControl * colorControl = static_cast<WaterColorControl *>(userData);
+ *colorControl = swatch->get();
+
+ colorControl->update(LLWaterParamManager::instance()->mCurParams);
+ LLWaterParamManager::instance()->propagateParameters();
+}
+
+void LLFloaterWater::onBoolToggle(LLUICtrl* ctrl, void* userData)
+{
+ LLCheckBoxCtrl* cbCtrl = static_cast<LLCheckBoxCtrl*>(ctrl);
+
+ bool value = cbCtrl->get();
+ (*(static_cast<BOOL *>(userData))) = value;
+}
+
+void LLFloaterWater::onNormalMapPicked(LLUICtrl* ctrl, void* userData)
+{
+ LLTextureCtrl* textCtrl = static_cast<LLTextureCtrl*>(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<std::string>::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<std::string>::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<LLComboBox*>(ctrl);
+
+ if(combo_box->getSimple() == "")
+ {
+ return;
+ }
+
+ LLWaterParamManager::instance()->loadPreset(
+ combo_box->getSelectedValue().asString());
+ sWaterMenu->syncMenu();
+}
+
diff --git a/indra/newview/llfloaterwater.h b/indra/newview/llfloaterwater.h
new file mode 100644
index 0000000000..311ef9a75e
--- /dev/null
+++ b/indra/newview/llfloaterwater.h
@@ -0,0 +1,133 @@
+/**
+ * @file llfloaterwindlight.h
+ * @brief LLFloaterWater class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <vector>
+#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<std::string> sDefaultPresets;
+};
+
+
+#endif
diff --git a/indra/newview/llfloaterwindlight.cpp b/indra/newview/llfloaterwindlight.cpp
new file mode 100644
index 0000000000..2627ea3705
--- /dev/null
+++ b/indra/newview/llfloaterwindlight.cpp
@@ -0,0 +1,998 @@
+/**
+ * @file llfloaterwindlight.cpp
+ * @brief LLFloaterWindLight class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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<std::string> 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<std::string, LLWLParamSet>::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<char>(":"));
+ 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, &param_mgr->mBlueHorizon);
+ childSetCommitCallback("WLBlueHorizonG", onColorControlGMoved, &param_mgr->mBlueHorizon);
+ childSetCommitCallback("WLBlueHorizonB", onColorControlBMoved, &param_mgr->mBlueHorizon);
+ childSetCommitCallback("WLBlueHorizonI", onColorControlIMoved, &param_mgr->mBlueHorizon);
+
+ // haze density, horizon, mult, and altitude
+ childSetCommitCallback("WLHazeDensity", onColorControlRMoved, &param_mgr->mHazeDensity);
+ childSetCommitCallback("WLHazeHorizon", onColorControlRMoved, &param_mgr->mHazeHorizon);
+ childSetCommitCallback("WLDensityMult", onFloatControlMoved, &param_mgr->mDensityMult);
+ childSetCommitCallback("WLMaxAltitude", onFloatControlMoved, &param_mgr->mMaxAlt);
+
+ // blue density
+ childSetCommitCallback("WLBlueDensityR", onColorControlRMoved, &param_mgr->mBlueDensity);
+ childSetCommitCallback("WLBlueDensityG", onColorControlGMoved, &param_mgr->mBlueDensity);
+ childSetCommitCallback("WLBlueDensityB", onColorControlBMoved, &param_mgr->mBlueDensity);
+ childSetCommitCallback("WLBlueDensityI", onColorControlIMoved, &param_mgr->mBlueDensity);
+
+ // Lighting
+
+ // sunlight
+ childSetCommitCallback("WLSunlightR", onColorControlRMoved, &param_mgr->mSunlight);
+ childSetCommitCallback("WLSunlightG", onColorControlGMoved, &param_mgr->mSunlight);
+ childSetCommitCallback("WLSunlightB", onColorControlBMoved, &param_mgr->mSunlight);
+ childSetCommitCallback("WLSunlightI", onColorControlIMoved, &param_mgr->mSunlight);
+
+ // glow
+ childSetCommitCallback("WLGlowR", onGlowRMoved, &param_mgr->mGlow);
+ childSetCommitCallback("WLGlowB", onGlowBMoved, &param_mgr->mGlow);
+
+ // ambient
+ childSetCommitCallback("WLAmbientR", onColorControlRMoved, &param_mgr->mAmbient);
+ childSetCommitCallback("WLAmbientG", onColorControlGMoved, &param_mgr->mAmbient);
+ childSetCommitCallback("WLAmbientB", onColorControlBMoved, &param_mgr->mAmbient);
+ childSetCommitCallback("WLAmbientI", onColorControlIMoved, &param_mgr->mAmbient);
+
+ // time of day
+ childSetCommitCallback("WLSunAngle", onSunMoved, &param_mgr->mLightnorm);
+ childSetCommitCallback("WLEastAngle", onSunMoved, &param_mgr->mLightnorm);
+
+ // Clouds
+
+ // Cloud Color
+ childSetCommitCallback("WLCloudColorR", onColorControlRMoved, &param_mgr->mCloudColor);
+ childSetCommitCallback("WLCloudColorG", onColorControlGMoved, &param_mgr->mCloudColor);
+ childSetCommitCallback("WLCloudColorB", onColorControlBMoved, &param_mgr->mCloudColor);
+ childSetCommitCallback("WLCloudColorI", onColorControlIMoved, &param_mgr->mCloudColor);
+
+ // Cloud
+ childSetCommitCallback("WLCloudX", onColorControlRMoved, &param_mgr->mCloudMain);
+ childSetCommitCallback("WLCloudY", onColorControlGMoved, &param_mgr->mCloudMain);
+ childSetCommitCallback("WLCloudDensity", onColorControlBMoved, &param_mgr->mCloudMain);
+
+ // Cloud Detail
+ childSetCommitCallback("WLCloudDetailX", onColorControlRMoved, &param_mgr->mCloudDetail);
+ childSetCommitCallback("WLCloudDetailY", onColorControlGMoved, &param_mgr->mCloudDetail);
+ childSetCommitCallback("WLCloudDetailDensity", onColorControlBMoved, &param_mgr->mCloudDetail);
+
+ // Cloud extras
+ childSetCommitCallback("WLCloudCoverage", onFloatControlMoved, &param_mgr->mCloudCoverage);
+ childSetCommitCallback("WLCloudScale", onFloatControlMoved, &param_mgr->mCloudScale);
+ childSetCommitCallback("WLCloudLockX", onCloudScrollXToggled, NULL);
+ childSetCommitCallback("WLCloudLockY", onCloudScrollYToggled, NULL);
+ childSetCommitCallback("WLCloudScrollX", onCloudScrollXMoved, NULL);
+ childSetCommitCallback("WLCloudScrollY", onCloudScrollYMoved, NULL);
+ childSetCommitCallback("WLDistanceMult", onFloatControlMoved, &param_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, &param_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<std::string, LLWLParamSet>::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<std::string, LLVector4> & 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<LLSliderCtrl*>(ctrl);
+ WLColorControl * colorControl = static_cast<WLColorControl *>(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<LLSliderCtrl*>(ctrl);
+ WLColorControl * colorControl = static_cast<WLColorControl *>(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<LLSliderCtrl*>(ctrl);
+ WLColorControl * colorControl = static_cast<WLColorControl *>(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<LLSliderCtrl*>(ctrl);
+ WLColorControl * colorControl = static_cast<WLColorControl *>(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<LLSliderCtrl*>(ctrl);
+ WLColorControl * colorControl = static_cast<WLColorControl *>(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<LLSliderCtrl*>(ctrl);
+ WLColorControl * colorControl = static_cast<WLColorControl *>(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<LLSliderCtrl*>(ctrl);
+ WLFloatControl * floatControl = static_cast<WLFloatControl *>(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<LLCheckBoxCtrl*>(ctrl);
+
+ bool value = cbCtrl->get();
+ (*(static_cast<BOOL *>(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<WLColorControl *>(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<LLSliderCtrl*>(ctrl);
+ F32 * tweak = static_cast<F32 *>(userData);
+
+ (*tweak) = sldrCtrl->getValueF32();
+ LLWLParamManager::instance()->propagateParameters();
+}
+
+void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl, void* userData)
+{
+ deactivateAnimator();
+
+ LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(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<std::string>::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<std::string>::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<LLComboBox*>(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<LLSliderCtrl*>(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<LLSliderCtrl*>(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<LLCheckBoxCtrl*>(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<LLCheckBoxCtrl*>(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/indra/newview/llfloaterwindlight.h b/indra/newview/llfloaterwindlight.h
new file mode 100644
index 0000000000..9bb7f1371c
--- /dev/null
+++ b/indra/newview/llfloaterwindlight.h
@@ -0,0 +1,142 @@
+/**
+ * @file llfloaterwindlight.h
+ * @brief LLFloaterWindLight class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <vector>
+#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<std::string> sDefaultPresets;
+};
+
+
+#endif
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index a710d1688d..9ec7676195 100644
--- a/indra/newview/llfolderview.cpp
+++ b/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"
@@ -809,7 +810,6 @@ void LLFolderViewItem::draw()
}
if(/*mControlLabel[0] != '\0' && */possibly_has_children)
{
- LLGLSTexture gls_texture;
if (mArrowImage)
{
gl_draw_scaled_rotated_image(mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD,
@@ -962,7 +962,7 @@ void LLFolderViewItem::draw()
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)getRect().getHeight() - sFont->getLineHeight() - (F32)TEXT_PAD;
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index a291f1da49..6459cd5033 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/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<LLDrawable*> 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();
}
@@ -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();
+ }
}
@@ -858,7 +863,7 @@ void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLV
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/indra/newview/llhudeffectbeam.cpp b/indra/newview/llhudeffectbeam.cpp
index 22aa7bebd2..236fdaf70f 100644
--- a/indra/newview/llhudeffectbeam.cpp
+++ b/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/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index 16c77149d5..920a1caaf3 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/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/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index fbb5ba5d62..2679ed5fbb 100644
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/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/indra/newview/llhudeffecttrail.cpp b/indra/newview/llhudeffecttrail.cpp
index 248ee8136e..da734d6104 100644
--- a/indra/newview/llhudeffecttrail.cpp
+++ b/indra/newview/llhudeffecttrail.cpp
@@ -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/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp
index 229228f4da..1260a268e3 100644
--- a/indra/newview/llhudicon.cpp
+++ b/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/indra/newview/llhudmanager.cpp b/indra/newview/llhudmanager.cpp
index c08e9552fc..30a09a96d3 100644
--- a/indra/newview/llhudmanager.cpp
+++ b/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/indra/newview/llhudmanager.h b/indra/newview/llhudmanager.h
index 2f8c1a1ec7..934bcf44a1 100644
--- a/indra/newview/llhudmanager.h
+++ b/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/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp
index 6271f0f377..d6bafa9b58 100644
--- a/indra/newview/llhudobject.cpp
+++ b/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/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp
index df1fdf175f..bdbc849dc2 100644
--- a/indra/newview/llhudrender.cpp
+++ b/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/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 1d68441231..0468ae5a1a 100644
--- a/indra/newview/llhudtext.cpp
+++ b/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/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp
index 9e0fa26f25..0027036b36 100644
--- a/indra/newview/lljoystickbutton.cpp
+++ b/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"
@@ -652,23 +653,23 @@ void LLJoystickCameraRotate::drawRotatedImage( const LLImageGL* image, S32 rotat
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();
}
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 44b919aa61..9b6ef2d079 100644
--- a/indra/newview/llmanip.cpp
+++ b/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/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index 2e4f66c929..fb85c81d01 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/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/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index a67e3fcce6..457682a154 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/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 );
}
}
@@ -600,47 +600,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 +763,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 +1536,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 +1587,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 +1636,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 +1660,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 +1693,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/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 2f5f154b77..3182f14951 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -38,6 +38,7 @@
#include "llmaniptranslate.h"
#include "llgl.h"
+#include "llglimmediate.h"
#include "llagent.h"
#include "llbbox.h"
@@ -140,7 +141,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);
@@ -1057,7 +1057,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 +1071,7 @@ void LLManipTranslate::render()
renderTranslationHandles();
renderSnapGuides();
}
- glPopMatrix();
+ gGL.popMatrix();
renderText();
}
@@ -1257,31 +1257,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 +1314,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 +1444,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 +1497,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 +1524,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 +1568,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 +1585,7 @@ void LLManipTranslate::renderSnapGuides()
default:
break;
}
+ gGL.flush();
}
}
}
@@ -1592,32 +1598,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 +1639,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 +1654,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 +1683,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 +1706,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 +1720,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 +1728,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 +1843,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 +1897,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 +1911,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 +1966,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 +2021,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 +2045,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 +2154,7 @@ void LLManipTranslate::renderTranslationHandles()
}
}
}
- glPopMatrix();
+ gGL.popMatrix();
}
@@ -2150,11 +2163,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 +2188,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 +2229,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/indra/newview/llmemoryview.cpp b/indra/newview/llmemoryview.cpp
index 616fabebf7..d554c272ee 100644
--- a/indra/newview/llmemoryview.cpp
+++ b/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 },
@@ -194,7 +194,6 @@ void LLMemoryView::draw()
// Labels
{
- LLGLSTexture gls_texture;
y = ytop;
S32 peak = 0;
for (S32 i=0; i<MTV_DISPLAY_NUM; i++)
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 257e87171a..0a078e1058 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -39,6 +39,7 @@
#include "linked_lists.h"
#include "llmath.h" // clampf()
#include "llfocusmgr.h"
+#include "llglimmediate.h"
#include "llagent.h"
#include "llcallingcard.h"
@@ -117,9 +118,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 );
@@ -256,7 +259,7 @@ void LLNetMap::draw()
glMatrixMode(GL_MODELVIEW);
// Draw background rectangle
- glColor4fv( mBackgroundColor.mV );
+ gGL.color4fv( mBackgroundColor.mV );
gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0);
}
@@ -264,9 +267,9 @@ void LLNetMap::draw()
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 +299,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 +331,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 +381,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 +489,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();
}
}
diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp
index 53066aa52d..cda921ab8f 100644
--- a/indra/newview/lloverlaybar.cpp
+++ b/indra/newview/lloverlaybar.cpp
@@ -37,6 +37,7 @@
#include "lloverlaybar.h"
#include "audioengine.h"
+#include "llglimmediate.h"
#include "llagent.h"
#include "llbutton.h"
#include "llchatbar.h"
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 24b055b0a6..b87d18a545 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -80,6 +80,9 @@ BOOL LLPanelFace::postBuild()
LLTextBox* mLabelColorTransp;
LLSpinCtrl* mCtrlColorTransp; // transparency = 1 - alpha
+ LLTextBox* mLabelGlow;
+ LLSpinCtrl* mCtrlGlow;
+
setMouseOpaque(FALSE);
mTextureCtrl = getChild<LLTextureCtrl>("texture control");
if(mTextureCtrl)
@@ -156,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);
@@ -254,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) {}
@@ -363,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();
@@ -578,10 +600,28 @@ void LLPanelFace::getState()
childSetEnabled("ColorTrans",editable);
}
+ {
+ F32 glow = 0.f;
+ struct f8 : public LLSelectedTEGetFunctor<F32>
+ {
+ 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<F32>
+ struct f9 : public LLSelectedTEGetFunctor<F32>
{
F32 get(LLViewerObject* object, S32 face)
{
@@ -606,7 +646,7 @@ void LLPanelFace::getState()
{
F32 bumpf = 0.f;
- struct f9 : public LLSelectedTEGetFunctor<F32>
+ struct f10 : public LLSelectedTEGetFunctor<F32>
{
F32 get(LLViewerObject* object, S32 face)
{
@@ -631,7 +671,7 @@ void LLPanelFace::getState()
{
F32 genf = 0.f;
- struct f10 : public LLSelectedTEGetFunctor<F32>
+ struct f11 : public LLSelectedTEGetFunctor<F32>
{
F32 get(LLViewerObject* object, S32 face)
{
@@ -669,7 +709,7 @@ void LLPanelFace::getState()
{
F32 fullbrightf = 0.f;
- struct f11 : public LLSelectedTEGetFunctor<F32>
+ struct f12 : public LLSelectedTEGetFunctor<F32>
{
F32 get(LLViewerObject* object, S32 face)
{
@@ -691,7 +731,7 @@ void LLPanelFace::getState()
// Repeats per meter
{
F32 repeats = 1.f;
- struct f12 : public LLSelectedTEGetFunctor<F32>
+ struct f13 : public LLSelectedTEGetFunctor<F32>
{
F32 get(LLViewerObject* object, S32 face)
{
@@ -761,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)
@@ -819,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;
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index d680129989..ddef5a1b5f 100644
--- a/indra/newview/llpanelface.h
+++ b/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/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index c6aae2dd88..b19d3723a7 100644
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -311,7 +311,6 @@ void LLPanelGroupLandMoney::impl::setYourContributionTextField(int contrib)
if ( mYourContributionEditorp )
{
mYourContributionEditorp->setText(buffer);
- mYourContributionEditorp->draw();
}
}
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index f717088de6..2ebbc07500 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -913,12 +913,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;
}
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 83a2a5e0bd..a9198cd6b4 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -232,6 +232,10 @@ 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 = getChild<LLColorSwatchCtrl>("colorswatch");
if(LightColorSwatch)
@@ -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);
diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp
index ba96ba088b..105103d10b 100644
--- a/indra/newview/llpreviewanim.cpp
+++ b/indra/newview/llpreviewanim.cpp
@@ -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/indra/newview/llpreviewanim.h b/indra/newview/llpreviewanim.h
index 37cbd49725..28b09a49dd 100644
--- a/indra/newview/llpreviewanim.h
+++ b/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/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 20737eb7f1..e1a9636fd0 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -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,
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index 9e437df2d1..101f7ace5d 100644
--- a/indra/newview/llprogressview.cpp
+++ b/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"
@@ -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
@@ -195,7 +196,7 @@ void LLProgressView::draw()
else
{
LLGLSNoTexture gls_no_texture;
- glColor4f(0.f, 0.f, 0.f, 1.f);
+ gGL.color4f(0.f, 0.f, 0.f, 1.f);
gl_rect_2d(getRect());
}
glPopMatrix();
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index ffc53f0dd5..d2e3dc1ed9 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -39,6 +39,7 @@
#include "lldbstrings.h"
#include "lleconomy.h"
#include "llgl.h"
+#include "llglimmediate.h"
#include "llpermissions.h"
#include "llpermissionsflags.h"
#include "llptrskiplist.h"
@@ -1730,6 +1731,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 );
+}
//-----------------------------------------------------------------------------
@@ -1752,6 +1784,26 @@ LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object)
//-----------------------------------------------------------------------------
+// selectionGetGlow()
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectionGetGlow(F32 *glow)
+{
+ BOOL identical;
+ F32 lglow = 0.f;
+ struct f1 : public LLSelectedTEGetFunctor<F32>
+ {
+ 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)
@@ -5161,7 +5213,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();
@@ -5172,7 +5225,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++)
@@ -5181,18 +5234,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++)
@@ -5208,15 +5262,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);
@@ -5225,24 +5279,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();
}
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 32c7f7617e..68c1d4d9f8 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -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/indra/newview/llsky.cpp b/indra/newview/llsky.cpp
index ee3890e50a..1ba4adf4d2 100644
--- a/indra/newview/llsky.cpp
+++ b/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<LLVOWLSky*>(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/indra/newview/llsky.h b/indra/newview/llsky.h
index 690b54a59e..e9e9999ff9 100644
--- a/indra/newview/llsky.h
+++ b/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<LLVOSky> mVOSkyp; // Pointer to the LLVOSky object (only one, ever!)
- LLPointer<LLVOStars> mVOStarsp; // Pointer to the LLVOStars object (only one, ever!)
LLPointer<LLVOGround> mVOGroundp;
+ LLPointer<LLVOWLSky> mVOWLSkyp;
+
LLVector3 mSunTargDir;
// Legacy stuff
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index abb8d973aa..84e14ef341 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/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<LLDrawable>
+{
+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<LLDrawable>* 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<LLDrawInfo*>& draw_vec = i->second;
- for (std::vector<LLDrawInfo*>::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,14 +1248,95 @@ BOOL LLSpatialGroup::rebound()
return TRUE;
}
+void LLSpatialGroup::checkOcclusion()
+{
+ 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);
+ }
+
+ 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);
+ }
+ }
+}
+
+void LLSpatialGroup::doOcclusion(LLCamera* camera)
+{
+ if (mSpatialPartition->mOcclusionEnabled && LLPipeline::sUseOcclusion > 1)
+ {
+ 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, BOOL is_volatile, U32 buffer_usage)
+LLSpatialPartition::LLSpatialPartition(U32 data_mask, U32 buffer_usage)
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
+ mOcclusionEnabled = TRUE;
mDrawableType = 0;
- mPartitionType = LLPipeline::PARTITION_NONE;
- mVolatile = is_volatile;
+ mPartitionType = LLViewerRegion::PARTITION_NONE;
mLODSeed = 0;
mLODPeriod = 1;
mVertexDataMask = data_mask;
@@ -1096,10 +1345,13 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL is_volatile, U32 buff
mSlopRatio = 0.25f;
mRenderByGroup = TRUE;
mImageEnabled = FALSE;
+ mInfiniteFarClip = FALSE;
+
+ LLGLNamePool::registerPool(&sQueryPool);
- mOctree = new LLSpatialGroup::OctreeNode(LLVector3d(0,0,0),
+ mOctree = new LLSpatialGroup::OctreeRoot(LLVector3d(0,0,0),
LLVector3d(1,1,1),
- new LLSpatialGroup::OctreeRoot(), NULL);
+ NULL);
new LLSpatialGroup(mOctree, this);
}
@@ -1108,11 +1360,6 @@ LLSpatialPartition::~LLSpatialPartition()
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
- for (U32 i = 0; i < mOcclusionQueries.size(); i++)
- {
- glDeleteQueriesARB(1, (GLuint*)(&(mOcclusionQueries[i])));
- }
-
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<LLDrawable*>* 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<LLDrawable*>* 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<LLDrawable>
{
public:
- virtual void visit(const LLOctreeState<LLDrawable>* state)
+ virtual void visit(const LLOctreeNode<LLDrawable>* 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<LLDrawable *>* 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<LLDrawable *>* 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<LLSpatialGroup*>* mQueue;
- LLQueueNonCulled(std::queue<LLSpatialGroup*> *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,23 +1846,34 @@ 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<LLSpatialGroup> group = mImageQueue.front();
mImageQueue.pop();
-
- group->clearState(LLSpatialGroup::IN_IMAGE_QUEUE);
-
+
if (group->isDead())
{
continue;
}
+ if (group->isState(LLSpatialGroup::GEOM_DIRTY))
+ { //put it back
+ mImageQueue.push(group);
+ continue;
+ }
+
+ group->clearState(LLSpatialGroup::IN_IMAGE_QUEUE);
if (LLPipeline::sDynamicReflections)
{
process_count--;
LLVector3 origin = group->mBounds[0];
-
+ /*LLVector3 at = camera->getOrigin()-origin;
+ at.normVec();
+ origin += at* (at * group->mBounds[1]);*/
+
LLCamera cube_cam;
cube_cam.setOrigin(origin);
cube_cam.setFar(64.f);
@@ -1716,15 +1886,8 @@ void LLSpatialPartition::processImagery(LLCamera* camera)
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);
+ gPipeline.generateReflectionMap(gPipeline.mCubeBuffer, cube_cam);
+ gPipeline.blurReflectionMap(gPipeline.mCubeBuffer, cube_map);
group->mReflectionMap = cube_map;
group->setState(LLSpatialGroup::GEOM_DIRTY);
}
@@ -1733,601 +1896,75 @@ void LLSpatialPartition::processImagery(LLCamera* camera)
}
}
-void validate_occlusion_list(std::vector<LLPointer<LLSpatialGroup> >& occluded_list)
+void pushVerts(LLDrawInfo* params, U32 mask)
{
-#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
+ LLRenderPass::applyModelMatrix(*params);
+ params->mVertexBuffer->setBuffer(mask);
+ U16* indicesp = (U16*) params->mVertexBuffer->getIndicesPointer();
+ glDrawRangeElements(params->mParticle ? GL_POINTS : GL_TRIANGLES, params->mStart, params->mEnd, params->mCount,
+ GL_UNSIGNED_SHORT, indicesp+params->mOffset);
}
-void LLSpatialPartition::processOcclusion(LLCamera* camera)
+void pushVerts(LLSpatialGroup* group, U32 mask)
{
- 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<LLSpatialGroup> 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);
- }
+ LLDrawInfo* params = NULL;
- //remove non-occluded groups from occluded list
- for (U32 i = 0; i < mOccludedList.size(); )
+ for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
{
- 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
+ for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
{
- i++;
+ params = *j;
+ pushVerts(params, mask);
}
}
-
- validate_occlusion_list(mOccludedList);
-
- //pump some non-culled items onto the occlusion list
- //count = MAX_PULLED;
- while (!mQueryQueue.empty())
- {
- LLPointer<LLSpatialGroup> 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
+void pushVerts(LLFace* face, U32 mask)
{
-public:
- LLOcclusionIndexBuffer(U32 size)
- : LLVertexBuffer(0, GL_STREAM_DRAW_ARB)
- {
- allocateBuffer(0, size, TRUE);
-
- LLStrider<U32> 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;
- }
-};
+ LLVertexBuffer* buffer = face->mVertexBuffer;
-class LLOcclusionVertexBuffer : public LLVertexBuffer
-{
-public:
- LLOcclusionVertexBuffer(S32 usage)
- : LLVertexBuffer(MAP_VERTEX, usage)
+ if (buffer)
{
- 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<LLVector3> 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
+ 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();
- *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
- }
+ glDrawRangeElements(GL_TRIANGLES, start, end, count, GL_UNSIGNED_SHORT, indicesp + offset);
}
-/* 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)
+void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
{
- 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)
+ if (buffer)
{
- return;
+ buffer->setBuffer(mask);
+ U16* indicesp = (U16*) buffer->getIndicesPointer();
+ glDrawRangeElements(GL_TRIANGLES, 0, buffer->getRequestedVerts(), buffer->getRequestedIndices(),
+ GL_UNSIGNED_SHORT, indicesp);
}
-
- //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
+void pushBufferVerts(LLSpatialGroup* group, U32 mask)
{
-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)
+ if (!group->mDrawMap.empty())
{
- 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
- }
- return FALSE;
- }
+ LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin());
+ LLRenderPass::applyModelMatrix(*params);
+
+ pushBufferVerts(group->mVertexBuffer, mask);
- virtual void visit(const LLSpatialGroup::OctreeState* branch)
- {
- for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
+ for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
{
- LLDrawable* drawable = *i;
- if (!skip(drawable, mLights))
+ for (LLSpatialGroup::buffer_list_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
{
- 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);
- }
- }
+ pushBufferVerts(*j, mask);
}
}
}
-
- 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);
-
- return results.size();
-}
-
-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);
-}
-
-S32 LLSpatialPartition::getLights(const LLVector3& pos, F32 rad, LLDrawable::drawable_set_t &results)
-{
- return getDrawables(pos, rad, results, TRUE);
-}
-
-void pushVerts(LLDrawInfo* params, U32 mask)
-{
- params->mVertexBuffer->setBuffer(mask);
- U32* indicesp = (U32*) params->mVertexBuffer->getIndicesPointer();
- glDrawRangeElements(params->mParticle ? GL_POINTS : GL_TRIANGLES, params->mStart, params->mEnd, params->mCount,
- GL_UNSIGNED_INT, indicesp+params->mOffset);
-}
-
-void pushVerts(LLSpatialGroup* group, U32 mask)
-{
- LLDrawInfo* params = NULL;
-
- for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
- {
- for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
- {
- params = *j;
- pushVerts(params, mask);
- }
- }
}
void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
@@ -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);
+ gGL.blendFunc(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]);
-
- if (group->mOctreeNode->hasLeafState())
- {
- glColor4f(1,1,1,1);
- }
- else
+ if (group->mBuilt <= 0.f)
{
- 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<LLDrawable>
{
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/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 53764930f8..7e1175a000 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -40,14 +40,18 @@
#include "llvertexbuffer.h"
#include "llgltypes.h"
#include "llcubemap.h"
+#include "lldrawpool.h"
#include <queue>
-#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<LLViewerImage> mTexture;
LLPointer<LLCubeMap> 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<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
{
// sort by pointer, sort NULL down to the end
@@ -93,6 +100,17 @@ public:
}
};
+ struct CompareTexturePtrMatrix
+ {
+ bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& 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<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
@@ -108,23 +126,24 @@ class LLSpatialGroup : public LLOctreeListener<LLDrawable>
{
friend class LLSpatialPartition;
public:
+ static U32 sNodeCount;
typedef std::vector<LLPointer<LLSpatialGroup> > sg_vector_t;
typedef std::set<LLPointer<LLSpatialGroup> > sg_set_t;
typedef std::vector<LLPointer<LLSpatialBridge> > bridge_list_t;
typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t;
typedef std::map<U32, drawmap_elem_t > draw_map_t;
- typedef std::map<LLPointer<LLViewerImage>, LLPointer<LLVertexBuffer> > buffer_map_t;
+ typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t;
+ typedef std::map<LLPointer<LLViewerImage>, buffer_list_t> buffer_map_t;
typedef LLOctreeListener<LLDrawable> BaseType;
typedef LLOctreeListener<LLDrawable> OctreeListener;
typedef LLTreeNode<LLDrawable> TreeNode;
typedef LLOctreeNode<LLDrawable> OctreeNode;
typedef LLOctreeRoot<LLDrawable> OctreeRoot;
- typedef LLOctreeState<LLDrawable> OctreeState;
typedef LLOctreeTraveler<LLDrawable> OctreeTraveler;
- typedef LLOctreeState<LLDrawable>::element_iter element_iter;
- typedef LLOctreeState<LLDrawable>::element_list element_list;
+ typedef LLOctreeNode<LLDrawable>::element_iter element_iter;
+ typedef LLOctreeNode<LLDrawable>::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<LLVertexBuffer> mVertexBuffer;
- LLPointer<LLVertexBuffer> mOcclusionVerts;
+ F32* mOcclusionVerts;
+ GLuint mOcclusionQuery;
LLPointer<LLCubeMap> 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<LLDrawable *>* 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<LLPointer<LLSpatialGroup> > spatial_group_set_t;
spatial_group_set_t mSpatialGroups;
- //things that might be occluded
typedef std::queue<LLPointer<LLSpatialGroup> > 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<LLGLuint> 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<LLVertexBuffer> mOcclusionIndices;
-
- //things that are occluded
- std::vector<LLPointer<LLSpatialGroup> > mOccludedList;
};
// class for creating bridges between spatial partitions
@@ -370,7 +369,6 @@ public:
virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* 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<LLSpatialGroup*> sg_list_t;
+ typedef std::vector<LLDrawable*> drawable_list_t;
+ typedef std::vector<LLSpatialBridge*> bridge_list_t;
+ typedef std::vector<LLDrawInfo*> 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/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp
index 827493d1b5..92fcbb6e6c 100644
--- a/indra/newview/llsprite.cpp
+++ b/indra/newview/llsprite.cpp
@@ -199,8 +199,8 @@ void LLSprite::updateFace(LLFace &face)
LLStrider<LLVector3> verticesp;
LLStrider<LLVector3> normalsp;
LLStrider<LLVector2> tex_coordsp;
- LLStrider<U32> indicesp;
- S32 index_offset;
+ LLStrider<U16> 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/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 455fcc7bc0..461730b947 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -170,6 +170,9 @@
#include "llnamelistctrl.h"
#include "llnamebox.h"
#include "llnameeditor.h"
+#include "llpostprocess.h"
+#include "llwlparammanager.h"
+#include "llwaterparammanager.h"
#if LL_WINDOWS
#include "llwindebug.h"
@@ -1540,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();
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index e9aa9b0232..dc1102eba7 100644
--- a/indra/newview/llsurface.cpp
+++ b/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/indra/newview/llsurface.h b/indra/newview/llsurface.h
index 8fecd2d97e..c806d804f1 100644
--- a/indra/newview/llsurface.h
+++ b/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/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index 58f6778646..502ff07b3c 100644
--- a/indra/newview/llsurfacepatch.cpp
+++ b/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/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 5330e8dfac..78cb53c2a5 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/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/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 7368ac9fdb..4f8e562baf 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -34,6 +34,7 @@
#include "lltexturectrl.h"
+#include "llglimmediate.h"
#include "llagent.h"
#include "llviewerimagelist.h"
#include "llcheckboxctrl.h"
@@ -483,38 +484,38 @@ 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();
}
}
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 031492e0e9..b5d4818fba 100644
--- a/indra/newview/lltextureview.cpp
+++ b/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"
@@ -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);
}
}
@@ -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(),
diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp
index 189996e871..5a637a6346 100644
--- a/indra/newview/lltoolbrush.cpp
+++ b/indra/newview/lltoolbrush.cpp
@@ -35,6 +35,7 @@
#include "lltoolselectland.h"
#include "llgl.h"
+#include "llglimmediate.h"
#include "message.h"
@@ -476,29 +477,25 @@ 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();
}
diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp
index ebe22fc43c..ffa921125a 100644
--- a/indra/newview/lltoolgun.cpp
+++ b/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/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index 3a56a9fd63..e32f9bfcc1 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -33,6 +33,7 @@
// File includes
#include "lltoolmorph.h"
+#include "llglimmediate.h"
// Library includes
#include "audioengine.h"
@@ -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/indra/newview/lltoolselectrect.cpp b/indra/newview/lltoolselectrect.cpp
index dd1a01f8dd..3b68751740 100644
--- a/indra/newview/lltoolselectrect.cpp
+++ b/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/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index 594ecb5591..cc45b121ae 100644
--- a/indra/newview/lltracker.cpp
+++ b/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/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index b71d9d954b..3e8ceaba1b 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/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 &center,
// 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 &center,
// 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/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index 5a655cba1a..c4a0f7ea53 100644
--- a/indra/newview/llviewercamera.h
+++ b/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/indra/newview/llviewercontrol.h b/indra/newview/llviewercontrol.h
index 8a3191d3bb..c2a9dc9096 100644
--- a/indra/newview/llviewercontrol.h
+++ b/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/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 60184312a7..cf5d7b406e 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/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<LLImageGL> 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/indra/newview/llviewerdisplay.h b/indra/newview/llviewerdisplay.h
index 2bf784c575..2190021fe4 100644
--- a/indra/newview/llviewerdisplay.h
+++ b/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/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp
index 093aca66f3..365bfa7010 100644
--- a/indra/newview/llviewerjoint.cpp
+++ b/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, " <BONE ID=\"%d\" NAME=\"%s\" NUMCHILDS=\"%d\">\n", mJointNum + 1, mName.c_str(), num_children);
- apr_file_printf(fp, " <TRANSLATION>%.6f %.6f %.6f</TRANSLATION>\n", bone_pos.mV[VX], bone_pos.mV[VY], bone_pos.mV[VZ]);
- apr_file_printf(fp, " <ROTATION>%.6f %.6f %.6f %.6f</ROTATION>\n", bone_rot.mQ[VX], bone_rot.mQ[VY], bone_rot.mQ[VZ], bone_rot.mQ[VW]);
- apr_file_printf(fp, " <LOCALTRANSLATION>%.6f %.6f %.6f</LOCALTRANSLATION>\n", rootSkinOffset.mV[VX], rootSkinOffset.mV[VY], rootSkinOffset.mV[VZ]);
- apr_file_printf(fp, " <LOCALROTATION>0 0 0 1</LOCALROTATION>\n");
- apr_file_printf(fp, " <PARENTID>%d</PARENTID>\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, " <CHILDID>%d</CHILDID>\n", joint->mJointNum + 1);
- }
- }
- apr_file_printf(fp, " </BONE>\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/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h
index e432258f88..5aa49aee7e 100644
--- a/indra/newview/llviewerjoint.h
+++ b/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/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index 18c99f7453..8b653b6430 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/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
@@ -211,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)
{
@@ -251,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/indra/newview/llviewerjointattachment.h b/indra/newview/llviewerjointattachment.h
index a834e68986..aa41252ab9 100644
--- a/indra/newview/llviewerjointattachment.h
+++ b/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/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index dfd9ec1d12..2677b33af8 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/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<LLVector3> verticesp;
LLStrider<LLVector3> normalsp;
- LLStrider<LLVector3> binormalsp;
LLStrider<LLVector2> tex_coordsp;
LLStrider<F32> vertex_weightsp;
LLStrider<LLVector4> clothing_weightsp;
- LLStrider<U32> indicesp;
+ LLStrider<U16> 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<SUBMESH NUMVERTICES=\"%d\" NUMFACES=\"%d\" MATERIAL=\"%d\" NUMLODSTEPS=\"0\" NUMSPRINGS=\"0\" NUMTEXCOORDS=\"1\">\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, " <VERTEX ID=\"%d\" NUMINFLUENCES=\"%d\">\n", i, num_bound_joints);
- apr_file_printf(fp, " <POS>%.4f %.4f %.4f</POS>\n", coord.mV[VX], coord.mV[VY], coord.mV[VZ]);
- apr_file_printf(fp, " <NORM>%.6f %.6f %.6f</NORM>\n", mesh_normals[i].mV[VX], mesh_normals[i].mV[VY], mesh_normals[i].mV[VZ]);
- apr_file_printf(fp, " <TEXCOORD>%.6f %.6f</TEXCOORD>\n", mesh_uvs[i].mV[VX], 1.f - mesh_uvs[i].mV[VY]);
- if (num_bound_joints >= 1)
- {
- apr_file_printf(fp, " <INFLUENCE ID=\"%d\">%.2f</INFLUENCE>\n", joint_a + 1, 1.f - fmod(mesh_weights[i], 1.f));
- }
- if (num_bound_joints == 2)
- {
- apr_file_printf(fp, " <INFLUENCE ID=\"%d\">%.2f</INFLUENCE>\n", joint_b + 1, fmod(mesh_weights[i], 1.f));
- }
- apr_file_printf(fp, " </VERTEX>\n");
- }
-
- LLPolyFace* mesh_faces = mMesh->getFaces();
- for (S32 i = 0; i < mMesh->getNumFaces(); i++)
- {
- apr_file_printf(fp, " <FACE VERTEXID=\"%d %d %d\" />\n", mesh_faces[i][0], mesh_faces[i][1], mesh_faces[i][2]);
- }
-
- apr_file_printf(fp, " </SUBMESH>\n");
-}
-
// End
diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h
index 8a3cc1ae28..8e1ee514ff 100644
--- a/indra/newview/llviewerjointmesh.h
+++ b/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/indra/newview/llviewerjointmesh_sse.cpp b/indra/newview/llviewerjointmesh_sse.cpp
index 7a0d4756ca..d3083fc1c7 100644
--- a/indra/newview/llviewerjointmesh_sse.cpp
+++ b/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/indra/newview/llviewerjointmesh_sse2.cpp b/indra/newview/llviewerjointmesh_sse2.cpp
index 129f06c40a..8e890637c1 100644
--- a/indra/newview/llviewerjointmesh_sse2.cpp
+++ b/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/indra/newview/llviewerjointmesh_vec.cpp b/indra/newview/llviewerjointmesh_vec.cpp
index c7be7ce092..ad0e15a42a 100644
--- a/indra/newview/llviewerjointmesh_vec.cpp
+++ b/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/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index fc9b765525..546c52a070 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/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"
@@ -113,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"
@@ -193,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"
@@ -1112,12 +1120,14 @@ void init_client_menu(LLMenuGL* menu)
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,
@@ -1186,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();
}
@@ -1329,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));
@@ -1344,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));
@@ -1380,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 );
@@ -1403,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);
@@ -5203,40 +5219,6 @@ void handle_force_unlock(void*)
gSelectMgr->getSelection()->applyToObjects(&func);
}
-class LLWorldForceSun : public view_listener_t
-{
- bool handleEvent(LLPointer<LLEvent> 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();
@@ -7225,6 +7207,33 @@ class LLViewCheckHighlightTransparent : public view_listener_t
}
};
+class LLViewBeaconWidth : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> 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<LLEvent> event, const LLSD& userdata)
@@ -7531,6 +7540,125 @@ class LLToolsSelectTool : public view_listener_t
}
};
+/// WINDLIGHT callbacks
+class LLWorldEnvSettings : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> 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<LLEvent> 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<LLEvent> event, const LLSD& userdata)
+ {
+ LLFloaterPostProcess::show();
+ return true;
+ }
+};
+
+/// Day Cycle callbacks
+class LLWorldDayCycle : public view_listener_t
+{
+ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+ {
+ LLFloaterDayCycle::show();
+ return true;
+ }
+};
+
+
+
static void addMenu(view_listener_t *menu, const char *name)
{
sMenus.push_back(menu);
@@ -7575,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");
@@ -7610,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/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 291e3da13d..8a7f7e047f 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/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<LLEvent> 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/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index cf71694e13..8aa2b8224a 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/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"
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 3a0daba8aa..602b60bc9d 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/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.
@@ -3063,6 +3063,11 @@ const LLVector3 &LLViewerObject::getPositionRegion() const
LLViewerObject *parent = (LLViewerObject *)getParent();
mPositionRegion = parent->getPositionRegion() + (getPosition() * parent->getRotation());
}
+ else
+ {
+ mPositionRegion = getPosition();
+ }
+
return mPositionRegion;
}
@@ -3088,18 +3093,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 +3764,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 +4179,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 +4837,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/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 42124610eb..c11c3c891e 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -194,7 +194,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);
@@ -248,11 +247,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
@@ -295,6 +294,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;
@@ -323,6 +323,7 @@ public:
// Create if necessary
LLAudioSource *getAudioSource(const LLUUID& owner_id);
+ bool isAudioSource() {return mAudioSourcep != NULL;}
U8 getMediaType() const;
void setMediaType(U8 media_type);
@@ -452,6 +453,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);
@@ -478,13 +481,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;
@@ -601,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
@@ -669,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<LLVector3>& verticesp,
LLStrider<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
- LLStrider<U32>& indicesp) = 0;
+ LLStrider<U16>& indicesp) = 0;
F32 mDepth;
};
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 012bdb0843..8d1867cc31 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/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<LLDrawable*> 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);
+ }
}
}
@@ -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/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index f73a094197..95c65d15ce 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -104,7 +104,6 @@ public:
void renderObjectBeacons();
void resetObjectBeacons();
- void relightAllObjects();
void dirtyAllObjectInventory();
void updateActive(LLViewerObject *objectp);
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index d9ab2bcd8a..3dc14caa2d 100644
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/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/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index acae8d333f..93e3ad2919 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/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<LLViewerPartSource> sourcep, LLViewerImage *imagep, LLVPCallback cb)
{
LLMemType mt(LLMemType::MTYPE_PARTICLES);
@@ -114,6 +95,7 @@ void LLViewerPart::init(LLPointer<LLViewerPartSource> 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 &center_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<LLViewerPart>::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<LLViewerPart>::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<LLViewerPartSource> sourcep)
{
@@ -696,6 +725,7 @@ void LLViewerPartSim::addPartSource(LLPointer<LLViewerPartSource> sourcep)
llwarns << "Null part source!" << llendl;
return;
}
+ sourcep->setStart() ;
mViewerPartSources.push_back(sourcep);
}
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index c915468c3b..51b8e5a42a 100644
--- a/indra/newview/llviewerpartsim.h
+++ b/indra/newview/llviewerpartsim.h
@@ -61,13 +61,12 @@ protected:
public:
LLViewerPart();
- LLViewerPart &operator=(const LLViewerPart &part);
void init(LLPointer<LLViewerPartSource> 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<LLViewerPartSource> mPartSourcep; // Particle source used for this object
@@ -97,7 +96,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 +116,7 @@ public:
BOOL mUniformParticles;
U32 mID;
-protected:
- void removePart(const S32 part_num);
+ F32 mSkippedTime;
protected:
LLVector3 mCenterAgent;
@@ -131,7 +129,6 @@ protected:
class LLViewerPartSim
{
-
public:
LLViewerPartSim();
virtual ~LLViewerPartSim();
@@ -148,7 +145,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 +182,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/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index a69fc51fe0..d81b688abf 100644
--- a/indra/newview/llviewerpartsource.cpp
+++ b/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/indra/newview/llviewerpartsource.h b/indra/newview/llviewerpartsource.h
index 3e3e63c2fb..7a49a919bc 100644
--- a/indra/newview/llviewerpartsource.h
+++ b/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/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 9f343abdae..3f0f5bee98 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/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
@@ -105,6 +106,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 +140,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 +191,8 @@ LLViewerRegion::~LLViewerRegion()
LLHTTPSender::clearSender(mHost);
saveCache();
+
+ std::for_each(mObjectPartition.begin(), mObjectPartition.end(), DeletePointer());
}
@@ -381,12 +398,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 +974,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 +983,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;
@@ -1431,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/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index e42c0015df..3d5334cd18 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -64,10 +64,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 +101,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 +263,7 @@ public:
// used by LCD to get details for debug screen
U32 getNetDetailsForLCD();
+ LLSpatialPartition* getSpatialPartition(U32 type);
public:
struct CompareDistance
{
@@ -270,6 +289,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
@@ -348,6 +369,10 @@ protected:
CapabilityMap mCapabilities;
LLEventPoll* mEventPoll;
+
+private:
+ //spatial partitions for objects in this region
+ std::vector<LLSpatialPartition*> mObjectPartition;
};
inline BOOL LLViewerRegion::getAllowDamage() const
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index ec4f66d681..93919fba05 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/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/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 9e8a7c2a9b..2ab11bf507 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/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
@@ -183,6 +183,7 @@
#include "llappviewer.h"
#include "llurlsimstring.h"
#include "llviewerdisplay.h"
+#include "llspatialpartition.h"
#if LL_WINDOWS
#include "llwindebug.h"
@@ -192,11 +193,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;
@@ -531,13 +534,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))
{
@@ -1509,63 +1567,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);
@@ -1609,11 +1643,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 };
@@ -1624,10 +1654,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);
@@ -1636,8 +1670,6 @@ void LLViewerWindow::initGLDefaults()
gBox.prerender();
gSphere.prerender();
gCylinder.prerender();
-
- LLVOAvatar::initVertexPrograms();
}
void LLViewerWindow::initBase()
@@ -2157,6 +2189,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)
gViewerStats->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width);
gViewerStats->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height);
+ gResizeScreenTexture = TRUE;
}
}
@@ -2222,11 +2255,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
@@ -2268,7 +2310,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);
@@ -2293,11 +2335,6 @@ void LLViewerWindow::draw()
}
}
- {
- LLGLSTexture gls_texture;
- drawDebugText();
- }
-
if (gToolMgr)
{
// Draw tool specific overlay on world
@@ -2358,7 +2395,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),
@@ -2369,8 +2405,7 @@ void LLViewerWindow::draw()
LLUI::sGLScaleFactor = old_scale_factor;
}
- glPopMatrix();
-
+ gGL.popMatrix();
#if LL_DEBUG
LLView::sIsDrawing = FALSE;
@@ -3201,11 +3236,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)
@@ -3368,6 +3404,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]);
@@ -3408,6 +3448,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();
@@ -3421,13 +3463,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.
@@ -4285,7 +4332,7 @@ BOOL LLViewerWindow::saveSnapshot( const LLString& filepath, S32 image_width, S3
llinfos << "Saving snapshot to: " << filepath << llendl;
LLPointer<LLImageRaw> 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)
{
@@ -4318,10 +4365,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))
@@ -4330,7 +4377,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);
@@ -4342,7 +4391,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)
{
@@ -4354,20 +4402,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_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);
+ //}
+ }
+
+ 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)
{
- snapshot_width = llround((F32)snapshot_height * image_aspect_ratio);
+ 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);
- 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);
+ 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)
@@ -4378,12 +4487,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());
@@ -4414,9 +4517,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) -
@@ -4475,6 +4579,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))
{
@@ -4492,14 +4604,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);
@@ -4547,7 +4665,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 );
}
@@ -4630,12 +4748,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()
@@ -4764,7 +4886,10 @@ void LLViewerWindow::stopGL(BOOL save_state)
LLDynamicTexture::destroyGL();
stop_glerror();
- gPipeline.destroyGL();
+ if (gPipeline.isInit())
+ {
+ gPipeline.destroyGL();
+ }
gCone.cleanupGL();
gBox.cleanupGL();
@@ -4799,6 +4924,8 @@ void LLViewerWindow::restoreGL(const LLString& progress_message)
LLDynamicTexture::restoreGL();
LLVOAvatar::restoreGL();
+ gResizeScreenTexture = TRUE;
+
if (gFloaterCustomize && gFloaterCustomize->getVisible())
{
LLVisualParamHint::requestHintUpdates();
@@ -4893,11 +5020,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;
@@ -4924,6 +5060,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())
{
@@ -5067,6 +5205,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;
@@ -5075,7 +5215,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)),
@@ -5089,7 +5229,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),
@@ -5100,7 +5240,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/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 1053234e8f..f040ca62d3 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -61,6 +61,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 +221,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/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 90e61426e9..99cf3a8046 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/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;
@@ -1271,16 +1281,6 @@ void LLVOAvatar::dumpBakedStatus()
}
//static
-void LLVOAvatar::cleanupVertexPrograms()
-{
-}
-
-//static
-void LLVOAvatar::initVertexPrograms()
-{
-}
-
-//static
void LLVOAvatar::restoreGL()
{
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
@@ -1301,7 +1301,19 @@ void LLVOAvatar::restoreGL()
void LLVOAvatar::destroyGL()
{
deleteCachedImages();
- cleanupVertexPrograms();
+
+ resetImpostors();
+}
+
+//static
+void LLVOAvatar::resetImpostors()
+{
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ LLVOAvatar* avatar = (LLVOAvatar*) *iter;
+ avatar->mImpostor.release();
+ }
}
// static
@@ -1454,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());
+ }
+ }
- newMin.setVec((center-size)-animation_buffer);
- newMax.setVec(center+size+animation_buffer);
- mDrawable->setPositionGroup((newMin + newMax) * 0.5f);
+ //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]);
+ }
+ }
+ }
+ }
+
+ //pad bounding box
+ newMin -= buffer;
+ newMax += buffer;
}
@@ -2080,6 +2181,7 @@ void LLVOAvatar::updateMeshData()
{
if (mDrawable.notNull())
{
+ stop_glerror();
LLFace* facep = mDrawable->getFace(0);
U32 num_vertices = 0;
@@ -2102,6 +2204,7 @@ void LLVOAvatar::updateMeshData()
facep->mVertexBuffer = new LLVertexBufferAvatar();
facep->mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE);
+
facep->setGeomIndex(0);
facep->setIndicesIndex(0);
@@ -2120,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);
}
}
@@ -2286,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)
{
@@ -2346,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)
{
@@ -2446,7 +2550,10 @@ 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 (attachment_map_t::iterator iter = mAttachmentPoints.begin();
@@ -2456,8 +2563,9 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
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())
{
@@ -2470,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())
@@ -2613,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
@@ -2996,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)
{
@@ -3045,7 +3203,7 @@ void LLVOAvatar::updateCharacter(LLAgent &agent)
{
gAgent.setPositionAgent(getPositionAgent());
}
- return;
+ return FALSE;
}
@@ -3053,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
@@ -3336,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
//-------------------------------------------------------------------------
@@ -3494,6 +3663,11 @@ void LLVOAvatar::updateCharacter(LLAgent &agent)
{
setDebugText(mDebugText);
}
+
+ //mesh vertices need to be reskinned
+ mNeedsSkin = TRUE;
+
+ return TRUE;
}
//-----------------------------------------------------------------------------
@@ -3524,7 +3698,7 @@ void LLVOAvatar::updateHeadOffset()
//------------------------------------------------------------------------
// updateVisibility()
//------------------------------------------------------------------------
-void LLVOAvatar::updateVisibility(BOOL force_invisible)
+void LLVOAvatar::updateVisibility()
{
BOOL visible = FALSE;
@@ -3536,7 +3710,7 @@ void LLVOAvatar::updateVisibility(BOOL force_invisible)
{
visible = FALSE;
}
- else if (!force_invisible)
+ else
{
// calculate avatar distance wrt head
mDrawable->updateDistance(*gCamera);
@@ -3659,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<LLCharacter*>::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()
@@ -3733,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");
@@ -3777,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
@@ -3823,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;
@@ -3881,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;
@@ -3935,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();
@@ -3949,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()
//-----------------------------------------------------------------------------
@@ -3965,7 +4152,6 @@ void LLVOAvatar::renderCollisionVolumes()
//------------------------------------------------------------------------
void LLVOAvatar::updateTextures(LLAgent &agent)
{
-// LLFastTimer ftm(LLFastTimer::FTM_TEMP5);
BOOL render_avatar = TRUE;
if (mIsDummy || gNoRender)
@@ -5423,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
@@ -5567,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);
@@ -5583,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())
{
@@ -5771,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)
@@ -5829,20 +6008,15 @@ BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object)
//-----------------------------------------------------------------------------
void LLVOAvatar::lazyAttach()
{
- for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end(); )
+ for (U32 i = 0; i < mPendingAttachment.size(); i++)
{
- attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getAttachmentDirty())
+ if (mPendingAttachment[i]->mDrawable)
{
- attachment->lazyAttach();
- if (mIsSelf)
- {
- updateAttachmentVisibility(gAgent.getCameraMode());
- }
+ attachObject(mPendingAttachment[i]);
}
}
+
+ mPendingAttachment.clear();
}
void LLVOAvatar::resetHUDAttachments()
@@ -9159,253 +9333,6 @@ 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, "<SKELETON VERSION=\"1000\" NUMBONES=\"%d\">\n", sSkeletonInfo->getNumBones() - sSkeletonInfo->getNumCollisionVolumes());
- mRoot.writeCAL3D(fp);
- apr_file_printf(fp, "</SKELETON>\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, "<MESH VERSION=\"1000\" NUMSUBMESH=\"%d\">\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, "</MESH>\n");
- apr_file_close(fp);
-
- // write out material files
- LLPointer<LLImageTGA> 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<LLImageRaw> 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<LLImageRaw> 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<LLUUID, LLMaterialExportInfo*>::iterator material_it_t;
- std::multimap<LLUUID, LLMaterialExportInfo*> material_map;
-
- S32 num_attachment_objects = 0;
- 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();
- 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, "<MESH VERSION=\"1000\" NUMSUBMESH=\"%d\">\n", num_attachment_objects);
-
- S32 material_index = 6;
- S32 texture_index = 6;
- 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();
- 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, "</MESH>\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, "<HEADER MAGIC=\"XRF\" VERSION=\"900\" />\n<MATERIAL NUMMAPS=\"1\">\n");
- apr_file_printf(fp, " <AMBIENT>%d %d %d %d</AMBIENT>\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]);
- apr_file_printf(fp, " <DIFFUSE>%d %d %d %d</DIFFUSE>\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]);
- apr_file_printf(fp, " <SPECULAR>0 0 0 0</SPECULAR>\n");
- apr_file_printf(fp, " <SHININESS>1.0</SHININESS>\n");
- apr_file_printf(fp, " <MAP>%s_material_tex_%d.tga</MAP>\n", file_base.c_str(), i);
- apr_file_printf(fp, "</MATERIAL>\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, "<HEADER MAGIC=\"XRF\" VERSION=\"900\" />\n<MATERIAL NUMMAPS=\"1\">\n");
- apr_file_printf(fp, " <AMBIENT>%d %d %d %d</AMBIENT>\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]);
- apr_file_printf(fp, " <DIFFUSE>%d %d %d %d</DIFFUSE>\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]);
- apr_file_printf(fp, " <SPECULAR>0 0 0 0</SPECULAR>\n");
- apr_file_printf(fp, " <SHININESS>1.0</SHININESS>\n");
- apr_file_printf(fp, " <MAP>%s_material_tex_%d.tga</MAP>\n", file_base.c_str(), export_info->mTextureIndex);
- apr_file_printf(fp, "</MATERIAL>\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()
{
@@ -9523,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<LLCharacter*>::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/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 6f262a730a..491d991369 100644
--- a/indra/newview/llvoavatar.h
+++ b/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;
@@ -848,14 +870,13 @@ public:
typedef std::map<S32, LLViewerJointAttachment*> attachment_map_t;
attachment_map_t mAttachmentPoints;
+ std::vector<LLPointer<LLViewerObject> > 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;
@@ -930,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/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp
index 7a2ba609e8..2e0da4727c 100644
--- a/indra/newview/llvoclouds.cpp
+++ b/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<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
- LLStrider<U32>& indicesp)
+ LLStrider<U16>& 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/indra/newview/llvoclouds.h b/indra/newview/llvoclouds.h
index 500d9426ae..af5bbf0e8f 100644
--- a/indra/newview/llvoclouds.h
+++ b/indra/newview/llvoclouds.h
@@ -59,10 +59,9 @@ public:
LLStrider<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
- LLStrider<U32>& indicesp);
+ LLStrider<U16>& 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/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 84fdbfff0b..833fe4b464 100644
--- a/indra/newview/llvograss.cpp
+++ b/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<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
- LLStrider<U32>& indicesp)
+ LLStrider<U16>& 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/indra/newview/llvograss.h b/indra/newview/llvograss.h
index f7ce9a4233..a1dab634be 100644
--- a/indra/newview/llvograss.h
+++ b/indra/newview/llvograss.h
@@ -68,7 +68,7 @@ public:
LLStrider<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
- LLStrider<U32>& indicesp);
+ LLStrider<U16>& indicesp);
void updateFaceSize(S32 idx) { }
/*virtual*/ void updateTextures(LLAgent &agent);
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index 8f6bc4a090..fd4956113d 100644
--- a/indra/newview/llvoground.cpp
+++ b/indra/newview/llvoground.cpp
@@ -93,7 +93,7 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
LLStrider<LLVector3> verticesp;
LLStrider<LLVector3> normalsp;
LLStrider<LLVector2> texCoordsp;
- LLStrider<U32> indicesp;
+ LLStrider<U16> 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/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index 96026c58ba..8d813f47aa 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/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] )
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 56643e321f..14e503d2d1 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/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<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
- LLStrider<U32>& indicesp)
+ LLStrider<U16>& 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<U32> indicesp;
+ LLStrider<U16> indicesp;
LLStrider<LLVector3> verticesp;
LLStrider<LLVector3> normalsp;
LLStrider<LLVector2> 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/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index 90c8ac4018..d8e1da7e5a 100644
--- a/indra/newview/llvopartgroup.h
+++ b/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<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
- LLStrider<U32>& indicesp);
+ LLStrider<U16>& 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/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index b8d994d095..ba06083fd3 100644
--- a/indra/newview/llvosky.cpp
+++ b/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; i<FACE_COUNT; i++)
{
@@ -529,9 +358,8 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
mCameraPosAgent = gAgent.getCameraPositionAgent();
mAtmHeight = ATM_HEIGHT;
mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS);
- updateHaze();
- mSunDefaultPosition = gSavedSettings.getVector3("SkySunDefaultPosition");
+ mSunDefaultPosition = LLVector3(LLWLParamManager::instance()->mCurParams.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<LLPointer<LLImageRaw> > 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<LLPointer<LLImageRaw> > 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<LLImageRaw> 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<LLPointer<LLImageRaw> > 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<LLPointer<LLImageRaw> > 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<LLVector3> 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<LLVector3> verticesp;
LLStrider<LLVector3> normalsp;
LLStrider<LLVector2> texCoordsp;
- LLStrider<U32> indicesp;
- S32 index_offset;
+ LLStrider<U16> 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<LLVector3> verticesp;
LLStrider<LLVector3> normalsp;
LLStrider<LLVector2> texCoordsp;
- LLStrider<U32> indicesp;
+ LLStrider<U16> 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<LLVector3> verticesp;
LLStrider<LLVector3> normalsp;
LLStrider<LLVector2> texCoordsp;
- LLStrider<U32> indicesp;
+ LLStrider<U16> 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<LLVector3> verticesp;
LLStrider<LLVector3> normalsp;
LLStrider<LLVector2> texCoordsp;
- LLStrider<U32> indicesp;
+ LLStrider<U16> 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/indra/newview/llvosky.h b/indra/newview/llvosky.h
index f3bceb0653..260aeeada7 100644
--- a/indra/newview/llvosky.h
+++ b/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<LLImageGL> mImageGL[2];
LLPointer<LLImageRaw> 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<LLImageGL> mScatterMap;
- LLPointer<LLImageRaw> 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/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index 05b374e607..d2fe5d31e6 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/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<LLVector3> &verticesp,
LLStrider<LLColor4U> &colorsp,
LLStrider<LLVector2> &texCoords0p,
LLStrider<LLVector2> &texCoords1p,
- LLStrider<U32> &indicesp)
+ LLStrider<U16> &indicesp)
{
LLFace* facep = mDrawable->getFace(0);
@@ -319,7 +322,7 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,
LLStrider<LLColor4U> &colorsp,
LLStrider<LLVector2> &texCoords0p,
LLStrider<LLVector2> &texCoords1p,
- LLStrider<U32> &indicesp,
+ LLStrider<U16> &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<LLColor4U> &colorsp,
LLStrider<LLVector2> &texCoords0p,
LLStrider<LLVector2> &texCoords1p,
- LLStrider<U32> &indicesp,
+ LLStrider<U16> &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<LLColor4U> &colorsp,
LLStrider<LLVector2> &texCoords0p,
LLStrider<LLVector2> &texCoords1p,
- LLStrider<U32> &indicesp,
+ LLStrider<U16> &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<LLVector2> texcoords2;
LLStrider<LLVector2> texcoords;
LLStrider<LLColor4U> colors;
- LLStrider<U32> indices;
+ LLStrider<U16> 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/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h
index ad2331ffed..ede01eb1a9 100644
--- a/indra/newview/llvosurfacepatch.h
+++ b/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<LLColor4U> &colorsp,
LLStrider<LLVector2> &texCoords0p,
LLStrider<LLVector2> &texCoords1p,
- LLStrider<U32> &indicesp);
+ LLStrider<U16> &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<LLColor4U> &colorsp,
LLStrider<LLVector2> &texCoords0p,
LLStrider<LLVector2> &texCoords1p,
- LLStrider<U32> &indicesp,
+ LLStrider<U16> &indicesp,
U32 &index_offset);
void updateNorthGeometry(LLFace *facep,
LLStrider<LLVector3> &verticesp,
@@ -121,7 +121,7 @@ protected:
LLStrider<LLColor4U> &colorsp,
LLStrider<LLVector2> &texCoords0p,
LLStrider<LLVector2> &texCoords1p,
- LLStrider<U32> &indicesp,
+ LLStrider<U16> &indicesp,
U32 &index_offset);
void updateEastGeometry(LLFace *facep,
LLStrider<LLVector3> &verticesp,
@@ -129,7 +129,7 @@ protected:
LLStrider<LLColor4U> &colorsp,
LLStrider<LLVector2> &texCoords0p,
LLStrider<LLVector2> &texCoords1p,
- LLStrider<U32> &indicesp,
+ LLStrider<U16> &indicesp,
U32 &index_offset);
};
diff --git a/indra/newview/llvotextbubble.cpp b/indra/newview/llvotextbubble.cpp
index cd3e4d16ce..4ecf180777 100644
--- a/indra/newview/llvotextbubble.cpp
+++ b/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<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
- LLStrider<U32>& indicesp)
+ LLStrider<U16>& 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/indra/newview/llvotextbubble.h b/indra/newview/llvotextbubble.h
index 35d4f97651..790e7208bc 100644
--- a/indra/newview/llvotextbubble.h
+++ b/indra/newview/llvotextbubble.h
@@ -54,7 +54,7 @@ public:
LLStrider<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
- LLStrider<U32>& indicesp);
+ LLStrider<U16>& indicesp);
virtual U32 getPartitionType() const;
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index b7c762a7c1..2f81ae84ba 100644
--- a/indra/newview/llvotree.cpp
+++ b/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<LLVector3> vertices;
LLStrider<LLVector3> normals;
LLStrider<LLVector2> tex_coords;
- LLStrider<U32> indicesp;
+ LLStrider<U16> 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/indra/newview/llvotree.h b/indra/newview/llvotree.h
index 90570f3b2e..dee282c752 100644
--- a/indra/newview/llvotree.h
+++ b/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/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 70037d3c20..5521b7f5f7 100644
--- a/indra/newview/llvovolume.cpp
+++ b/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;
@@ -742,9 +760,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 +780,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 +888,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 +939,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 +969,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 +977,14 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
return res;
}
+void LLVOVolume::preRebuild()
+{
+ if (mVolumeImpl != NULL)
+ {
+ mVolumeImpl->preRebuild();
+ }
+}
+
void LLVOVolume::updateRelativeXform()
{
if (mVolumeImpl)
@@ -1012,8 +1048,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 +1081,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 +1104,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
if (mVolumeChanged || mFaceMappingChanged )
{
compiled = TRUE;
- mInited = TRUE;
if (mVolumeChanged)
{
@@ -1248,6 +1288,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 +1365,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 +1521,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 +1535,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 +1644,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 +1710,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<LLUUID, LLMaterialExportInfo*>& 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<LLUUID, LLMaterialExportInfo*>::iterator material_it_t;
- std::pair<material_it_t, material_it_t> 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<LLUUID, LLMaterialExportInfo*>(tep->getID(), material_info));
- }
-
- apr_file_printf(fp, "\t<SUBMESH NUMVERTICES=\"%d\" NUMFACES=\"%d\" MATERIAL=\"%d\" NUMLODSTEPS=\"0\" NUMSPRINGS=\"0\" NUMTEXCOORDS=\"1\">\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, " <VERTEX ID=\"%d\" NUMINFLUENCES=\"1\">\n", vert_num++);
- apr_file_printf(fp, " <POS>%.4f %.4f %.4f</POS>\n", vert_pos.mV[VX], vert_pos.mV[VY], vert_pos.mV[VZ]);
- apr_file_printf(fp, " <NORM>%.6f %.6f %.6f</NORM>\n", vert_norm.mV[VX], vert_norm.mV[VY], vert_norm.mV[VZ]);
- apr_file_printf(fp, " <TEXCOORD>%.6f %.6f</TEXCOORD>\n", vert_tc.mV[VX], 1.f - vert_tc.mV[VY]);
- apr_file_printf(fp, " <INFLUENCE ID=\"%d\">1.0</INFLUENCE>\n", joint_num + 1);
- apr_file_printf(fp, " </VERTEX>\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, " <FACE VERTEXID=\"%d %d %d\" />\n", index_a, index_b, index_c);
- }
-
- apr_file_printf(fp, " </SUBMESH>\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 +1743,7 @@ void LLVOVolume::setSelected(BOOL sel)
LLViewerObject::setSelected(sel);
if (mDrawable.notNull())
{
- mDrawable->movePartition();
+ markForUpdate(TRUE);
}
}
@@ -1929,7 +1764,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 +1791,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 +1893,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 +1905,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 +1917,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 +1943,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);
+ tex_mat = facep->mTextureMatrix;
+ }
+
+ const LLMatrix4* model_mat = NULL;
+
+ LLDrawable* drawable = facep->getDrawable();
+ if (drawable->isActive())
+ {
+ model_mat = &(drawable->getRenderMatrix());
+ }
+ else
+ {
+ 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<LLDrawInfo> 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 +1998,13 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
U32 count = facep->getIndicesCount();
LLPointer<LLDrawInfo> 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 +2016,11 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
+ if (LLPipeline::sSkipUpdate)
+ {
+ return;
+ }
+
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -2182,6 +2031,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 +2094,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 +2116,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 +2135,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 +2180,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 +2228,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<LLVector3> vertices;
- LLStrider<LLVector3> normals;
- LLStrider<LLVector2> texcoords2;
- LLStrider<LLVector2> texcoords;
- LLStrider<LLColor4U> colors;
- LLStrider<U32> 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<LLFace*>::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<LLFace*>::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 +2292,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 +2318,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 +2337,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 +2433,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<LLFace*>::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 +2466,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 +2500,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 +2557,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/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 60700e6563..5f98dd6b9c 100644
--- a/indra/newview/llvovolume.h
+++ b/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<LLUUID, LLMaterialExportInfo*>& 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/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index 33095d1b8c..901dc6de21 100644
--- a/indra/newview/llvowater.cpp
+++ b/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<LLVector3> verticesp, normalsp;
LLStrider<LLVector2> texCoordsp;
- LLStrider<U32> indicesp;
- S32 index_offset;
+ LLStrider<U16> 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/indra/newview/llvowater.h b/indra/newview/llvowater.h
index 12b5ac07fe..346fa5bb46 100644
--- a/indra/newview/llvowater.h
+++ b/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/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
new file mode 100644
index 0000000000..ca9f328e48
--- /dev/null
+++ b/indra/newview/llvowlsky.cpp
@@ -0,0 +1,821 @@
+/**
+ * @file llvowlsky.cpp
+ * @brief LLVOWLSky class implementation
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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<LLDrawPoolWLSky *>(
+ 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<LLVector3> vin, vout;
+ LLStrider<U16> 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<LLVector3> vert;
+
+ LLStrider<LLVector3> vin;
+ LLStrider<U16> 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<LLVector3> 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<LLVector3> vertices;
+ LLStrider<LLVector2> texCoords;
+ LLStrider<U16> 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<LLVertexBuffer> 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<LLVertexBuffer> 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<LLVector3> v;
+ temp2->getVertexStrider(v);
+ LLStrider<U16> 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<LLVertexBuffer> >::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<LLVector3>::iterator v_p = mStarVertices.begin();
+ std::vector<LLColor4>::iterator v_c = mStarColors.begin();
+ std::vector<F32>::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<LLVector3> & vertices,
+ LLStrider<LLVector2> & texCoords,
+ LLStrider<U16> & 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<LLVector3> & vertices,
+ LLStrider<LLVector2> & texCoords,
+ LLStrider<U16> & 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<LLColor4>::iterator v_c = mStarColors.begin();
+ std::vector<F32>::iterator v_i = mStarIntensities.begin();
+ std::vector<LLVector3>::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<LLVector3> verticesp;
+ LLStrider<LLColor4U> colorsp;
+ LLStrider<U16> 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/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h
new file mode 100644
index 0000000000..dcb4b851a2
--- /dev/null
+++ b/indra/newview/llvowlsky.h
@@ -0,0 +1,110 @@
+/**
+ * @file llvowlsky.h
+ * @brief LLVOWLSky class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewergpl$
+ *
+ * Copyright (c) 2007-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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<LLVector3> & vertices,
+ LLStrider<LLVector2> & texCoords,
+ LLStrider<U16> & 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<LLVector3> & vertices,
+ LLStrider<LLVector2> & texCoords,
+ LLStrider<U16> & indices);
+
+ // helper function for updating the stars colors.
+ void updateStarColors();
+
+ // helper function for updating the stars geometry.
+ BOOL updateStarGeometry(LLDrawable *drawable);
+
+private:
+ LLPointer<LLVertexBuffer> mFanVerts;
+ std::vector< LLPointer<LLVertexBuffer> > mStripsVerts;
+ LLPointer<LLVertexBuffer> mStarsVerts;
+
+ std::vector<LLVector3> mStarVertices; // Star verticies
+ std::vector<LLColor4> mStarColors; // Star colors
+ std::vector<F32> mStarIntensities; // Star intensities
+};
+
+#endif // LL_VOWLSKY_H
diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
new file mode 100644
index 0000000000..d81cbf832f
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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<LLSDParser> 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<LLSDParser> parser = new LLSDXMLParser();
+
+ parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED);
+
+ std::map<std::string, LLWaterParamSet>::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<LLSDFormatter> 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<std::string, LLWaterParamSet>::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<std::string, LLWaterParamSet>::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<std::string, LLWaterParamSet>::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<std::string, LLWaterParamSet>::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/indra/newview/llwaterparammanager.h b/indra/newview/llwaterparammanager.h
new file mode 100644
index 0000000000..6892bb1924
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <vector>
+#include <map>
+#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<std::string, LLWaterParamSet> 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/indra/newview/llwaterparamset.cpp b/indra/newview/llwaterparamset.cpp
new file mode 100644
index 0000000000..78baae8db6
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <llgl.h>
+
+#include <sstream>
+
+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/indra/newview/llwaterparamset.h b/indra/newview/llwaterparamset.h
new file mode 100644
index 0000000000..f853140733
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <string>
+#include <map>
+
+#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/indra/newview/llwlanimator.cpp b/indra/newview/llwlanimator.cpp
new file mode 100644
index 0000000000..1b158d0685
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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<F32, std::string>& curTrack,
+ F32 dayRate, F64 dayTime, bool run)
+{
+ mTimeTrack = curTrack;
+ mDayRate = dayRate;
+ setDayTime(dayTime);
+
+ mIsRunning = run;
+}
diff --git a/indra/newview/llwlanimator.h b/indra/newview/llwlanimator.h
new file mode 100644
index 0000000000..5f20df3bae
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <string>
+#include <map>
+
+class LLWLAnimator {
+public:
+ F64 mStartTime;
+ F32 mDayRate;
+ F64 mDayTime;
+
+ // track to play
+ std::map<F32, std::string> mTimeTrack;
+ std::map<F32, std::string>::iterator mFirstIt, mSecondIt;
+
+ // params to use
+ //std::map<std::string, LLWLParamSet> 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<F32, std::string>& track,
+ F32 dayRate, F64 dayTime = 0, bool run = true);
+
+};
+
+#endif // LL_WL_ANIMATOR_H
diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp
new file mode 100644
index 0000000000..b8b2a85ee4
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <map>
+
+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<LLSDParser> 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<F32, std::string>::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<LLSDFormatter> 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<F32, std::string>(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<F32, std::string>::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<F32, std::string>::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<F32, std::string>::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<F32, std::string>::iterator mIt = mTimeMap.find(time);
+ if(mIt != mTimeMap.end())
+ {
+ name = mTimeMap[time];
+ return true;
+ }
+
+ // return error if not found
+ return false;
+}
diff --git a/indra/newview/llwldaycycle.h b/indra/newview/llwldaycycle.h
new file mode 100644
index 0000000000..b554c915fc
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <vector>
+#include <map>
+#include <string>
+#include "llwlparamset.h"
+#include "llwlanimator.h"
+
+class LLWLDayCycle
+{
+public:
+
+ // lists what param sets are used when during the day
+ std::map<F32, std::string> 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/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
new file mode 100644
index 0000000000..b1c1f5e2d0
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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<LLSDParser> 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<LLSDParser> 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<std::string, LLWLParamSet>::iterator mIt = mParamList.begin();
+ mIt != mParamList.end();
+ ++mIt)
+ {
+ paramsData[mIt->first] = mIt->second.getAll();
+ }
+
+ std::ofstream presetsXML(pathName.c_str());
+
+ LLPointer<LLSDFormatter> 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<LLSDParser> parser = new LLSDXMLParser();
+
+ parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED);
+
+ std::map<std::string, LLWLParamSet>::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<LLSDFormatter> 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<std::string, LLWLParamSet>::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<std::string, LLWLParamSet>::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<std::string, LLWLParamSet>::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<std::string, LLWLParamSet>::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/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h
new file mode 100644
index 0000000000..a78d92bf8b
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <vector>
+#include <map>
+#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<std::string, LLWLParamSet> 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/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp
new file mode 100644
index 0000000000..6e1a3972ea
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <llgl.h>
+
+#include <sstream>
+
+LLWLParamSet::LLWLParamSet(void) :
+ mName("Unnamed Preset"),
+ mCloudScrollXOffset(0.f), mCloudScrollYOffset(0.f)
+{
+/* REMOVE or init the LLSD
+ const std::map<std::string, LLVector4>::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<std::string, LLVector4>::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/indra/newview/llwlparamset.h b/indra/newview/llwlparamset.h
new file mode 100644
index 0000000000..1f72fffdfc
--- /dev/null
+++ b/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-2007, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 <string>
+#include <map>
+
+#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/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index ead4654c7f..6551361739 100644
--- a/indra/newview/llworld.cpp
+++ b/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(), &region_x, &region_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(), &region_x, &region_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(), &region_x, &region_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/indra/newview/llworld.h b/indra/newview/llworld.h
index e634459acd..a3cf874cfa 100644
--- a/indra/newview/llworld.h
+++ b/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/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 1abc1b165c..6bbe5307b0 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -39,6 +39,7 @@
#include "llmath.h" // clampf()
#include "llregionhandle.h"
#include "lleventflags.h"
+#include "llglimmediate.h"
#include "llagent.h"
#include "llcallingcard.h"
@@ -210,9 +211,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 );
@@ -338,16 +341,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 +415,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 +573,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 +628,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 +645,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 +707,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)
@@ -996,23 +1006,23 @@ void LLWorldMapView::drawFrustum()
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();
}
@@ -1210,15 +1220,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 +1396,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();
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 8c5ad393ab..4f533e1189 100644
--- a/indra/newview/pipeline.cpp
+++ b/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])
{
- glDeleteFramebuffersEXT(2, mFramebuffer);
- mFramebuffer[0] = mFramebuffer[1] = 0;
+ glDeleteTextures(3, mBlurCubeTexture);
+ mBlurCubeTexture[0] = mBlurCubeTexture[1] = mBlurCubeTexture[2] = 0;
}
+
+ mWaterRef.release();
+ mWaterDis.release();
+ mScreen.release();
+
+ for (U32 i = 0; i < 3; i++)
+ {
+ 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<LLViewerImage*>& textures) : mTextures(textures) { }
- virtual void visit(const LLOctreeState<LLDrawable>* state)
+ virtual void visit(const LLOctreeNode<LLDrawable>* 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<LLViewerImage*>& 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<LLViewerImage*>& 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;
@@ -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<LLDrawable> 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;
- processOcclusion(camera);
+ if (to_texture)
+ {
+ mScreen.bindTarget();
+ }
+
+ glPushMatrix();
+ gGLLastMatrix = NULL;
+ glLoadMatrixd(gGLLastModelView);
- for (U32 i = 0; i < mObjectPartition.size(); i++)
- {
- if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType))
+ 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);
+
+ 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
{
- mObjectPartition[i]->cull(camera);
+ camera.disableUserClipPlane();
+ }
+
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ {
+ 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,25 +2558,36 @@ 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<LLViewerObject*>& objects)
{
+ assertInitialized();
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
+ gPipeline.resetDrawOrders();
+
+ for (std::set<LLViewerObject*>::iterator iter = objects.begin(); iter != objects.end(); ++iter)
+ {
+ stateSort((*iter)->mDrawable, *gCamera);
+ }
+
LLMemType mt(LLMemType::MTYPE_PIPELINE);
LLVertexBuffer::startRender();
@@ -2319,7 +2615,10 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& 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<LLViewerObject*>& objects)
}
#endif
}
- }
+ }
- LLGLEnable tex(GL_TEXTURE_2D);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
LLGLEnable alpha_test(GL_ALPHA_TEST);
if (gPickTransparent)
@@ -2387,11 +2685,16 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& 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);
for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
iter != avatarp->mAttachmentPoints.end(); )
@@ -2436,15 +2739,27 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& 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 &center, 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);
- }
}
+
+ 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]);
+ U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
- 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);
-
-
- 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,774 @@ 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);
- glBegin(GL_TRIANGLE_STRIP);
- glColor4f(1,1,1,1);
- glTexCoord2f(tc1.mV[0], tc1.mV[1]);
- glVertex2f(-1,-1);
+ gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }*/
+ gGL.stop();
+
+ {
+ LLVertexBuffer::unbind();
+
+ 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]
+ };
- glTexCoord2f(tc1.mV[0], tc2.mV[1]);
- glVertex2f(-1,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);
+
+ 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<<LLPipeline::RENDER_TYPE_WATER) |
+ (1<<LLPipeline::RENDER_TYPE_GROUND) |
+ (1<<LLPipeline::RENDER_TYPE_SKY) |
+ (1<<LLPipeline::RENDER_TYPE_CLOUDS) |
+ (1<<LLPipeline::RENDER_TYPE_WL_SKY));
+
+ if (gSavedSettings.getBOOL("RenderWaterReflections"))
+ { //mask out selected geometry based on reflection detail
+
+ S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
+ if (detail < 3)
+ {
+ mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_PARTICLES);
+ if (detail < 2)
+ {
+ mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_AVATAR);
+ if (detail < 1)
+ {
+ mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_VOLUME);
+ }
+ }
+ }
+
+ LLSpatialPartition::sFreezeState = TRUE;
+ LLPipeline::sSkipUpdate = TRUE;
+ LLGLUserClipPlane clip_plane(plane, mat, projection);
+ static LLCullResult result;
+ updateCull(camera, result, 1);
+ stateSort(camera, result);
+ renderGeom(camera);
+ LLSpatialPartition::sFreezeState = FALSE;
+ LLPipeline::sSkipUpdate = FALSE;
+ }
+ }
+ glCullFace(GL_BACK);
+ glPopMatrix();
+ mWaterRef.flush();
+
+ glh_set_current_modelview(current);
+ }
+
+ //render distortion map
+ static BOOL last_update = TRUE;
+ if (last_update)
+ {
+ camera.setFar(camera_in.getFar());
+ mRenderTypeMask = type_mask & (~(1<<LLPipeline::RENDER_TYPE_WATER) |
+ (1<<LLPipeline::RENDER_TYPE_GROUND));
+ stop_glerror();
+
+ LLPipeline::sUnderWaterRender = gCamera->cameraUnderWater() ? FALSE : TRUE;
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_GROUND) |
+ (1<<LLPipeline::RENDER_TYPE_SKY) |
+ (1<<LLPipeline::RENDER_TYPE_CLOUDS) |
+ (1<<LLPipeline::RENDER_TYPE_WL_SKY));
+ }
+ LLViewerCamera::updateFrustumPlanes(camera);
+
+ LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
+ LLColor4& col = LLDrawPoolWater::sWaterFogColor;
+ glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
+ glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
+ mWaterDis.bindTarget();
+ mWaterDis.getViewport(gGLViewport);
+ mWaterDis.clear();
+ glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
+
+ if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate)
+ {
+ //clip out geometry on the same side of water as the camera
+ mat = glh_get_current_modelview();
+ LLGLUserClipPlane clip_plane(LLPlane(-pnorm, -(pd+pad)), mat, projection);
+ static LLCullResult result;
+ updateCull(camera, result, water_clip);
+ stateSort(camera, result);
+ renderGeom(camera);
+ }
+
+ LLPipeline::sUnderWaterRender = FALSE;
+ mWaterDis.flush();
+ }
+ last_update = LLDrawPoolWater::sNeedsReflectionUpdate;
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ LLPipeline::sReflectionRender = FALSE;
+
+ if (!LLRenderTarget::sUseFBO)
+ {
+ glClear(GL_DEPTH_BUFFER_BIT);
+ }
+ glClearColor(0.f, 0.f, 0.f, 0.f);
+
+ gViewerWindow->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;
+}
+
+S32 LLPipeline::getVisibleCount() const
+{
+ return sCull->getVisibleListSize();
+}
+
+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<<LLPipeline::RENDER_TYPE_VOLUME) |
+ (1<<LLPipeline::RENDER_TYPE_AVATAR) |
+ (1<<LLPipeline::RENDER_TYPE_BUMP) |
+ (1<<LLPipeline::RENDER_TYPE_GRASS) |
+ (1<<LLPipeline::RENDER_TYPE_SIMPLE) |
+ (1<<LLPipeline::RENDER_TYPE_ALPHA) |
+ (1<<LLPipeline::RENDER_TYPE_INVISIBLE);
+
+ mask = mask & gPipeline.getRenderTypeMask();
+ U32 saved_mask = gPipeline.mRenderTypeMask;
+ gPipeline.mRenderTypeMask = mask;
+
+ S32 occlusion = sUseOcclusion;
+ sUseOcclusion = 0;
+ sReflectionRender = TRUE;
+ sImpostorRender = TRUE;
+
+ markVisible(avatar->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/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 8b64b63016..32f5a7487b 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -32,6 +32,7 @@
#ifndef LL_PIPELINE_H
#define LL_PIPELINE_H
+#include "llerror.h"
#include "lldarrayptr.h"
#include "lldqueueptr.h"
#include "llstat.h"
@@ -43,9 +44,10 @@
#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 +56,8 @@ class LLDisplayPrimitive;
class LLTextureEntry;
class LLRenderFunc;
class LLCubeMap;
+class LLCullResult;
+class LLVOAvatar;
typedef enum e_avatar_skinning_method
{
@@ -65,6 +69,11 @@ BOOL compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max); // Shouldn
bool LLRayAABB(const LLVector3 &center, 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 +84,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 +123,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 +152,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 +162,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<LLViewerObject*>& objects);
void renderFaceForUVSelect(LLFace* facep);
@@ -172,29 +193,34 @@ 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 getVisibleCount() const;
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<<type))) ? TRUE : FALSE; }
BOOL hasRenderDebugFeatureMask(const U32 mask) const { return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; }
- BOOL hasRenderFeatureMask(const U32 mask) const { return (mRenderFeatureMask & mask) ? TRUE : FALSE; }
BOOL hasRenderDebugMask(const U32 mask) const { return (mRenderDebugMask & mask) ? TRUE : FALSE; }
void setRenderTypeMask(const U32 mask) { mRenderTypeMask = mask; }
U32 getRenderTypeMask() const { return mRenderTypeMask; }
@@ -240,13 +266,12 @@ public:
static BOOL getProcessBeacons(void* data);
private:
- void initShaders(BOOL force);
void unloadShaders();
- BOOL loadShaders();
- void saveVertexShaderLevel(S32 type, S32 level, S32 max);
void addToQuickLookup( LLDrawPool* new_poolp );
void removeFromQuickLookup( LLDrawPool* poolp );
BOOL updateDrawableGeom(LLDrawable* drawable, BOOL priority);
+ void assertInitializedDoError();
+ bool assertInitialized() { const bool is_init = isInit(); if (!is_init) assertInitializedDoError(); return is_init; };
public:
enum {GPU_CLASS_MAX = 3 };
@@ -255,17 +280,18 @@ public:
{
// Following are pool types (some are also object types)
RENDER_TYPE_SKY = LLDrawPool::POOL_SKY,
- RENDER_TYPE_STARS = LLDrawPool::POOL_STARS,
+ RENDER_TYPE_WL_SKY = LLDrawPool::POOL_WL_SKY,
RENDER_TYPE_GROUND = LLDrawPool::POOL_GROUND,
RENDER_TYPE_TERRAIN = LLDrawPool::POOL_TERRAIN,
RENDER_TYPE_SIMPLE = LLDrawPool::POOL_SIMPLE,
RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP,
RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR,
RENDER_TYPE_TREE = LLDrawPool::POOL_TREE,
+ RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE,
RENDER_TYPE_WATER = LLDrawPool::POOL_WATER,
RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA,
RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW,
-
+
// Following are object types (only used in drawable mRenderType)
RENDER_TYPE_HUD = LLDrawPool::NUM_POOL_TYPES,
RENDER_TYPE_VOLUME,
@@ -288,58 +314,30 @@ public:
RENDER_DEBUG_FEATURE_FOOT_SHADOWS = 0x0100,
};
- enum LLRenderFeatureMask
- {
- RENDER_FEATURE_LOCAL_LIGHTING = 0x02,
- RENDER_FEATURE_OBJECT_BUMP = 0x04,
- RENDER_FEATURE_AVATAR_BUMP = 0x08,
-// RENDER_FEATURE_SHADOWS = 0x10,
- RENDER_FEATURE_RIPPLE_WATER = 0X20
- };
-
enum LLRenderDebugMask
{
- RENDER_DEBUG_LIGHT_TRACE = 0x00001,
- RENDER_DEBUG_COMPOSITION = 0x00020,
- RENDER_DEBUG_VERIFY = 0x00080,
- RENDER_DEBUG_SHADOW_MAP = 0x00100,
- RENDER_DEBUG_BBOXES = 0x00200,
- RENDER_DEBUG_OCTREE = 0x00400,
- RENDER_DEBUG_PICKING = 0x00800,
- RENDER_DEBUG_OCCLUSION = 0x01000,
- RENDER_DEBUG_POINTS = 0x02000,
- RENDER_DEBUG_TEXTURE_PRIORITY = 0x04000,
- RENDER_DEBUG_TEXTURE_AREA = 0x08000,
- RENDER_DEBUG_FACE_AREA = 0x10000,
- RENDER_DEBUG_PARTICLES = 0x20000,
- RENDER_DEBUG_GLOW = 0x40000,
- RENDER_DEBUG_TEXTURE_ANIM = 0x80000,
+ RENDER_DEBUG_COMPOSITION = 0x000020,
+ RENDER_DEBUG_VERIFY = 0x000080,
+ RENDER_DEBUG_BBOXES = 0x000200,
+ RENDER_DEBUG_OCTREE = 0x000400,
+ RENDER_DEBUG_PICKING = 0x000800,
+ RENDER_DEBUG_OCCLUSION = 0x001000,
+ RENDER_DEBUG_POINTS = 0x002000,
+ RENDER_DEBUG_TEXTURE_PRIORITY = 0x004000,
+ RENDER_DEBUG_TEXTURE_AREA = 0x008000,
+ RENDER_DEBUG_FACE_AREA = 0x010000,
+ RENDER_DEBUG_PARTICLES = 0x020000,
+ RENDER_DEBUG_GLOW = 0x040000,
+ RENDER_DEBUG_TEXTURE_ANIM = 0x080000,
+ RENDER_DEBUG_LIGHTS = 0x100000,
+ RENDER_DEBUG_BATCH_SIZE = 0x200000,
};
LLPointer<LLViewerImage> 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<LLSpatialPartition*> mObjectPartition;
public:
LLSpatialPartition* getSpatialPartition(LLViewerObject* vobj);
- LLSpatialPartition* getSpatialPartition(U32 index);
void updateCamera(BOOL reset = FALSE);
@@ -347,7 +345,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 +364,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<LLCubeMap> mCubeBuffer;
+ //cube map anti-aliasing buffers
+ GLuint mBlurCubeBuffer[3];
+ GLuint mBlurCubeTexture[3];
+
//frambuffer object for rendering dynamic cube maps
GLuint mCubeFrameBuffer;
@@ -388,22 +416,12 @@ public:
LLColor4 mSunDiffuse;
LLVector3 mSunDir;
- LLSpatialGroup::sg_vector_t mActiveGroups;
- LLSpatialGroup::drawmap_elem_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES];
- std::vector<LLSpatialGroup* > mAlphaGroups;
- std::vector<LLSpatialGroup* > 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 +430,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 +472,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 +511,15 @@ protected:
std::map<uintptr_t, LLDrawPool*> mTerrainPools;
std::map<uintptr_t, LLDrawPool*> 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 +534,7 @@ protected:
U32 mLightMask;
U32 mLightMovingMask;
S32 mLightingDetail;
- F32 mSunShadowFactor;
-
+
static BOOL sRenderPhysicalBeacons;
static BOOL sRenderScriptedTouchBeacons;
static BOOL sRenderScriptedBeacons;
@@ -536,5 +550,6 @@ void render_bbox(const LLVector3 &min, const LLVector3 &max);
extern LLPipeline gPipeline;
extern BOOL gRenderForSelect;
+extern const LLMatrix4* gGLLastMatrix;
#endif
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index a84942d747..94688dd8bc 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -56,6 +56,8 @@ class ViewerManifest(LLManifest):
# include the entire shaders directory recursively
self.path("shaders")
+ # ... and the entire windlight directory
+ self.path("windlight")
self.end_prefix("app_settings")
if self.prefix(src="character"):